1. Circuit language – quantities and conventions

In circuit analysis, we first set the language of description: which quantities we use, how their signs are defined, and how we annotate them on a schematic. The key point is that current directions and voltage polarities are often chosen by convention (as reference directions) — and the sign of the result tells you whether reality matches your choice.

1.1 Current

Electric current \(i(t)\) is the time rate of flow of charge:

\[ i(t) = \frac{d q(t)}{dt}. \]

Unit: ampere \([A] = [C/s]\). You will also often use the integral form:

\[ q(t) = q(t_0) + \int_{t_0}^{t} i(\tau)\, d\tau. \]

Convention note: on schematics, current direction is usually indicated according to the motion of positive charge (conventional current), even though in metals the mobile carriers are electrons.

1.2 Voltage

Voltage \(v_{ab}(t)\) between nodes \(a\) and \(b\) is a potential difference:

\[ v_{ab}(t) = \varphi_a(t) - \varphi_b(t), \]

equivalently, it is the energy change per unit charge when moving from \(b\) to \(a\):

\[ v_{ab}(t) = \frac{d w_{b\to a}(t)}{d q}. \]

Unit: volt \([V] = [J/C]\).

1.3 Reference directions

For any circuit element you choose:

  • a reference current direction \(i\) (an arrow on the branch),
  • a reference voltage polarity \(v\) (the \(+\) and \(-\) marks on the terminals).

These are reference directions. If you compute, for example, \(i<0\), it means the actual current flows opposite to the arrow you assumed. Similarly, \(v<0\) means the actual polarity is opposite to the one you assigned.

1.4 Power

The instantaneous power associated with an element is:

\[ p(t) = v(t)\, i(t). \]

Unit: watt \([W] = [J/s]\). Power integrates to energy:

\[ w(t) = w(t_0) + \int_{t_0}^{t} p(\tau)\, d\tau. \]

1.5 Resistor – Ohm’s law

For an ideal resistor:

\[ v(t) = R\, i(t), \]

where \(R\) is resistance in ohms \([\Omega]\). Power in a resistor:

\[ p(t) = v i = R i^2 = \frac{v^2}{R}. \]

1.6 Passive sign convention

In practice we most often use the passive sign convention:

  • the \(+\) terminal of \(v\) is the terminal where the reference current \(i\) enters the element.

Then the formula \(p = v i\) has a clean interpretation:

  • \(p>0\) — the element absorbs power (e.g., a resistor dissipates heat),
  • \(p<0\) — the element delivers power to the rest of the circuit (e.g., a source in a given operating mode).

1.7 Example: schematic annotations

Below is a minimal example of our standard: drawing schematics in Python with schemdraw, including a reference current direction and a voltage label on an element.

Show the code
import schemdraw
import schemdraw.elements as elm

with schemdraw.Drawing() as d:
    d += elm.Line().right().label('$i$', loc='top')
    R1 = elm.Resistor().right()
    R1.label('$R$', loc='bottom')
    R1.label(['+', '$v$', '−'], loc='top')
    d += R1

Interpretation: $i$ defines the reference current direction, and the + v − marks define the reference voltage polarity across the resistor terminals (consistent with the passive sign convention).

1.8 Skills after this section

After this section you can:

  • define and convert \(i\), \(v\), \(p\), and \(w\) together with their units,
  • use reference directions (the sign of a result encodes the actual direction/polarity),
  • write Ohm’s law and resistor power in multiple equivalent forms,
  • apply the passive sign convention and interpret the sign of power,
  • read and describe schematic annotations (current, voltage, element labels).

2. Simplification strategies

In many problems the first step is to reduce a part of the circuit to an equivalent element (most often an equivalent resistance). This works when you only care about the behavior “seen at the terminals” (a two-node/two-terminal port), and the internal structure is no longer needed for the remaining analysis.

2.1 Series connections

Elements are in series if the same current flows through them (there is no branching node between them). For resistors:

\[ R_\text{eq} = R_1 + R_2 + \cdots + R_n. \]

Properties (for ideal resistors):

  • current: \(i\) is the same through every series element,
  • voltages: they add: \(v = v_1 + v_2 + \cdots\),
  • voltage divider (two resistors): \(v_1 = v\,\frac{R_1}{R_1+R_2}\).

2.2 Parallel connections

Elements are in parallel if both terminals are connected to the same two nodes — then they have the same voltage across them. For resistors:

\[ \frac{1}{R_\text{eq}} = \frac{1}{R_1} + \frac{1}{R_2} + \cdots + \frac{1}{R_n}. \]

Properties:

  • voltage: \(v\) is the same across every branch,
  • currents: they add: \(i = i_1 + i_2 + \cdots\),
  • two resistors: \(R_\text{eq} = \frac{R_1R_2}{R_1+R_2}\),
  • it is often convenient to use conductances: \(G=1/R\), so \(G_\text{eq} = \sum_k G_k\).

2.3 Mixed networks

For mixed networks, a reliable approach is “from the inside out”:

  1. Identify obvious series and parallel groups.
  2. Reduce them to equivalent elements.
  3. Repeat until you obtain a single element (or a simple circuit where Kirchhoff’s laws are easy to apply).

Practical tips:

  • “Series” and “parallel” are properties of node connectivity, not of how the drawing looks.
  • If there is a node between two elements with an extra branch attached, those two elements are not in series.
  • If two elements do not share exactly the same two terminal nodes, they are not in parallel.

2.4 When reduction is not possible

Reduction to a single \(R_\text{eq}\) via simple series/parallel steps fails, for example, when:

  • the circuit contains a bridge (e.g. a Wheatstone bridge), where no element is purely series or parallel,
  • there are dependent sources or nonlinear elements and you need a port relation beyond a “constant resistance,”
  • you care about more than the two-terminal behavior (e.g. multiple node voltages/currents at once).

In such cases you switch to general methods: Kirchhoff’s laws (KCL/KVL), nodal analysis, mesh analysis, and sometimes Thévenin/Norton equivalents (port reduction, but not via simple series/parallel steps).

3. Kirchhoff’s laws – a general method

When a circuit cannot be reduced by series/parallel steps (or when you need multiple node voltages/currents), you can always fall back on Kirchhoff’s laws. They translate a circuit diagram into a system of algebraic (or differential) equations.

Before writing equations, choose:

  • a reference direction for each branch current,
  • a reference polarity for each element voltage (often using the passive sign convention).

The final numerical sign of the solution tells you whether the true direction/polarity matches your choice.

3.1 Kirchhoff’s Current Law (KCL)

KCL: at any node, the algebraic sum of currents is zero:

\[ \sum_{k} i_k(t) = 0. \]

Interpretation: total current entering a node equals total current leaving the node.

Practical form (choose a sign convention):

  • take currents leaving the node as positive and entering as negative (or vice versa),
  • write one KCL equation per node (usually for all but one reference/ground node).

KCL is the foundation of nodal analysis: unknowns are node voltages, and branch currents are expressed via element laws (e.g. Ohm’s law) in terms of node voltages.

3.2 Kirchhoff’s Voltage Law (KVL)

KVL: around any closed loop, the algebraic sum of voltage rises/drops is zero:

\[ \sum_{k} v_k(t) = 0. \]

How to apply it:

  1. Pick a loop direction (clockwise/counterclockwise).
  2. Traverse the loop and add each element voltage with a sign consistent with your traversal and the element’s marked polarity.

KVL is the basis of mesh analysis (mainly for planar circuits): unknowns are loop/mesh currents, and element voltages are written in terms of those currents.

3.3 Why this always works

At the level of lumped-element circuit theory, Kirchhoff’s laws come from two fundamental conservation principles:

  • KCL expresses conservation of charge: charge cannot accumulate indefinitely at an ideal node, so currents must balance.
  • KVL expresses energy consistency: in quasi-static lumped circuits the electric field is effectively conservative along the wires, so the net potential change around a closed path is zero.

Important caveat: KVL must be used with care when there is significant time-varying magnetic flux linking a loop (Faraday’s law). In standard circuit problems (wires small compared to wavelength, localized elements, negligible radiation), the lumped approximation holds and KCL/KVL provide a reliable general method.

5. A first complete example

In this section we solve a small circuit from start to finish, using a consistent set of reference currents and voltage polarities (passive sign convention).

5.1 Schematic analysis

Consider a source \(V_s\) feeding a series resistor \(R_1\) and a node that splits into two resistors \(R_2\) and \(R_3\) to ground:

Show the code
import schemdraw
import schemdraw.elements as elm

with schemdraw.Drawing() as d:
    Vs = elm.SourceV().up()
    Vs.label(['+', '$V_s$', '−'], loc='left')
    d += Vs

    d += elm.Line().right().label('$i_1$', loc='top')
    R1 = elm.Resistor().right()
    R1.label('$R_1$', loc='bottom')
    R1.label(['+', '$v_1$', '−'], loc='top')
    d += R1

    d.push()  # Branch 1: R2
    d += elm.Line().down().label('$i_2$', loc='right')
    R2 = elm.Resistor().down()
    R2.label('$R_2$', loc='left')
    R2.label(['+', '$v_2$', '−'], loc='right')
    d += R2
    d += elm.Ground()
    d.pop()

    d += elm.Line().right()  # Branch 2: R3 (shift right for readability)
    d += elm.Line().down().label('$i_3$', loc='right')
    R3 = elm.Resistor().down()
    R3.label('$R_3$', loc='left')
    R3.label(['+', '$v_3$', '−'], loc='right')
    d += R3
    d += elm.Ground()

There is one essential top node (the split node). The bottom node is the reference (ground).

5.2 Choosing currents

We choose branch currents:

  • \(i_1\) through \(R_1\) from left to right (toward the split node),
  • \(i_2\) through \(R_2\) downward to ground,
  • \(i_3\) through \(R_3\) downward to ground.

Voltage polarities across each resistor are marked so that the \(+\) terminal is where the chosen current enters (passive sign convention).

5.3 Applying KCL

Apply KCL at the split node:

\[ i_1 - i_2 - i_3 = 0. \]

5.4 Applying KVL

Write KVL around two loops (take the loop direction consistent with the schematic):

Loop through \(V_s\), \(R_1\), \(R_2\):

\[ V_s - v_1 - v_2 = 0. \]

Loop through \(V_s\), \(R_1\), \(R_3\):

\[ V_s - v_1 - v_3 = 0. \]

5.5 Element substitutions

For ideal resistors (with the chosen polarity/current directions):

\[ v_1 = R_1 i_1,\qquad v_2 = R_2 i_2,\qquad v_3 = R_3 i_3. \]

Substitute into the loop equations:

\[ V_s - R_1 i_1 - R_2 i_2 = 0,\qquad V_s - R_1 i_1 - R_3 i_3 = 0. \]

5.6 Final system of equations

Collecting KCL + KVL gives a linear system in the unknown currents \((i_1,i_2,i_3)\):

\[ \begin{bmatrix} 1 & -1 & -1 \\ R_1 & R_2 & 0 \\ R_1 & 0 & R_3 \end{bmatrix} \begin{bmatrix} i_1 \\ i_2 \\ i_3 \end{bmatrix} = \begin{bmatrix} 0 \\ V_s \\ V_s \end{bmatrix}. \]

As a quick check, the equivalent resistance seen by the source is \(R_\text{eq} = R_1 + (R_2 \parallel R_3)\), so \(i_1 = \dfrac{V_s}{R_\text{eq}}\) and the node voltage is \(v_\text{node} = V_s - R_1 i_1\) (then \(i_2=v_\text{node}/R_2\), \(i_3=v_\text{node}/R_3\)).

6. Picking up speed – more configurations

The goal now is to get fluent at turning a schematic into equations. Below are a few common patterns; in each, choose mesh currents (clockwise by convention) and keep voltage polarities consistent with your chosen current directions.

6.1 Two meshes (decoupled)

Two independent loops lead to two independent KVL equations (no coupling terms).

Show the code
import schemdraw
import schemdraw.elements as elm

with schemdraw.Drawing() as d:
    # Left loop
    Vs1 = elm.SourceV().up()
    Vs1.label(['+', '$V_{s1}$', '−'], loc='left')
    d += Vs1
    R1 = elm.Resistor().right().label('$R_1$', loc='bottom')
    R1.label(['+', '$v_1$', '−'], loc='top')
    d += R1
    R2 = elm.Resistor().down().label('$R_2$', loc='right')
    R2.label(['+', '$v_2$', '−'], loc='left')
    d += R2
    d += elm.Line().left().length(2)
    d += elm.LoopArrow(direction='cw', width=1.2, height=1.2).at((1, 1)).label('$I_1$')

    # Right loop (shifted)
    d.move(dx=3.5, dy=0)
    Vs2 = elm.SourceV().up()
    Vs2.label(['+', '$V_{s2}$', '−'], loc='left')
    d += Vs2
    R3 = elm.Resistor().right().label('$R_3$', loc='bottom')
    R3.label(['+', '$v_3$', '−'], loc='top')
    d += R3
    R4 = elm.Resistor().down().label('$R_4$', loc='right')
    R4.label(['+', '$v_4$', '−'], loc='left')
    d += R4
    d += elm.Line().left().length(2)
    d += elm.LoopArrow(direction='cw', width=1.2, height=1.2).at((4.5, 1)).label('$I_2$')

Mesh equations:

\[ V_{s1} - R_1 I_1 - R_2 I_1 = 0,\qquad V_{s2} - R_3 I_2 - R_4 I_2 = 0. \]

6.2 Three meshes (ladder-type planar circuit)

When meshes share resistors, the equations couple via current differences (e.g. \(R(I_1-I_2)\)).

Show the code
import schemdraw
import schemdraw.elements as elm

with schemdraw.Drawing() as d:
    # Outer frame
    Vs = elm.SourceV().up()
    Vs.label(['+', '$V_s$', '−'], loc='left')
    d += Vs

    R1 = elm.Resistor().right().label('$R_1$', loc='bottom')
    R1.label(['+', '$v_1$', '−'], loc='top')
    d += R1
    node_A = d.here

    R3 = elm.Resistor().right().label('$R_3$', loc='bottom')
    R3.label(['+', '$v_3$', '−'], loc='top')
    d += R3
    node_B = d.here

    R5 = elm.Resistor().right().label('$R_5$', loc='bottom')
    R5.label(['+', '$v_5$', '−'], loc='top')
    d += R5

    R6 = elm.Resistor().down().length(2).label('$R_6$', loc='right')
    R6.label(['+', '$v_6$', '−'], loc='left')
    d += R6

    d += elm.Line().left().length(6)

    # Internal branches (shared resistors)
    d.push()
    d.here = node_A
    R2 = elm.Resistor().down().length(2).label('$R_2$', loc='left')
    R2.label(['+', '$v_2$', '−'], loc='right')
    d += R2
    d.pop()

    d.push()
    d.here = node_B
    R4 = elm.Resistor().down().length(2).label('$R_4$', loc='left')
    R4.label(['+', '$v_4$', '−'], loc='right')
    d += R4
    d.pop()

    # Mesh current arrows
    d += elm.LoopArrow(direction='cw', width=1.6, height=1.2).at((1, 1)).label('$I_1$')
    d += elm.LoopArrow(direction='cw', width=1.6, height=1.2).at((3, 1)).label('$I_2$')
    d += elm.LoopArrow(direction='cw', width=1.6, height=1.2).at((5, 1)).label('$I_3$')

One possible mesh-equation set (clockwise mesh currents):

\[ \begin{aligned} &V_s - R_1 I_1 - R_2 (I_1 - I_2) = 0,\\ &-R_3 I_2 - R_2 (I_2 - I_1) - R_4 (I_2 - I_3) = 0,\\ &-R_5 I_3 - R_4 (I_3 - I_2) - R_6 I_3 = 0. \end{aligned} \]

6.3 A shared element (signs matter)

If a resistor \(R_s\) lies on a branch shared by two meshes, the voltage drop contribution in each KVL equation is written using the difference of mesh currents.

Show the code
import schemdraw
import schemdraw.elements as elm

with schemdraw.Drawing() as d:
    # Left boundary source
    Vs = elm.SourceV().up()
    Vs.label(['+', '$V_s$', '−'], loc='left')
    d += Vs

    # Top resistors
    d += elm.Resistor().right().label('$R_1$', loc='bottom').label(['+', '$v_1$', '−'], loc='top')
    top_mid = d.here
    d += elm.Resistor().right().label('$R_3$', loc='bottom').label(['+', '$v_3$', '−'], loc='top')

    # Right boundary resistor
    d += elm.Resistor().down().length(2).label('$R_4$', loc='right').label(['+', '$v_4$', '−'], loc='left')
    d += elm.Line().left().length(4)

    # Shared middle resistor (between the two meshes)
    d.push()
    d.here = top_mid
    Rs = elm.Resistor().down().length(2)
    Rs.label('$R_s$', loc='left')
    Rs.label(['+', '$v_s$', '−'], loc='right')
    d += Rs
    d.pop()

    # Mesh current arrows
    d += elm.LoopArrow(direction='cw', width=1.6, height=1.2).at((1, 1)).label('$I_1$')
    d += elm.LoopArrow(direction='cw', width=1.6, height=1.2).at((3, 1)).label('$I_2$')

With clockwise mesh currents, the shared-branch current is \(I_1-I_2\) (one mesh goes down the shared branch, the other goes up). Therefore:

  • in mesh 1: the shared-resistor drop is \(R_s (I_1 - I_2)\),
  • in mesh 2: the shared-resistor drop is \(R_s (I_2 - I_1)\).

This “same element, opposite sign” pattern is the most common place where sign mistakes happen.

6.4 Multiple sources (including a supermesh case)

When a current source lies on a branch shared by two meshes, you typically form a supermesh: write KVL around the outer perimeter (skipping the current-source branch) and add a constraint equation for the current source.

Show the code
import schemdraw
import schemdraw.elements as elm

with schemdraw.Drawing() as d:
    # Outer frame
    Vs = elm.SourceV().up()
    Vs.label(['+', '$V_s$', '−'], loc='left')
    d += Vs

    d += elm.Resistor().right().label('$R_1$', loc='bottom').label(['+', '$v_1$', '−'], loc='top')
    top_mid = d.here
    d += elm.Resistor().right().label('$R_3$', loc='bottom').label(['+', '$v_3$', '−'], loc='top')
    d += elm.Resistor().down().length(2).label('$R_4$', loc='right').label(['+', '$v_4$', '−'], loc='left')
    d += elm.Line().left().length(4)

    # Shared branch is a current source (downward)
    d.push()
    d.here = top_mid
    Is = elm.SourceI().down().length(2)
    Is.label('$I_s$', loc='right')
    d += Is
    d.pop()

    # Mesh current arrows
    d += elm.LoopArrow(direction='cw', width=1.6, height=1.2).at((1, 1)).label('$I_1$')
    d += elm.LoopArrow(direction='cw', width=1.6, height=1.2).at((3, 1)).label('$I_2$')

With clockwise mesh currents, the current in the shared branch (downward) is \(I_1 - I_2\), so the current source imposes the constraint:

\[ I_1 - I_2 = I_s. \]

Write one KVL equation for the supermesh (the outer loop that goes around both meshes, avoiding the current source branch). For example:

\[ V_s - R_1 I_1 - R_3 I_2 - R_4 I_2 = 0, \]

together with \(I_1 - I_2 = I_s\) gives a complete solvable system for \((I_1,I_2)\).

7. Common mistakes

Most errors in circuit equation setups are not “hard math” issues—they come from inconsistent reference directions, missing constraints, or sign slips. This section highlights the typical failure modes and how to catch them quickly.

7.1 Signs

The most common sign mistakes are:

  • mixing “voltage rise” and “voltage drop” conventions within one KVL equation,
  • forgetting that reversing a reference direction flips the sign of the associated variable,
  • labeling a voltage \(v\) as if it were a point quantity (it is always a difference between two terminals).

Checklist for KVL signs

  1. Mark a \(+/-\) polarity for every element voltage you use.
  2. Pick a loop direction and stick to it.
  3. As you traverse an element: going from \(+\) to \(-\) contributes \(-v\); going from \(-\) to \(+\) contributes \(+v\).
Show the code
import schemdraw
import schemdraw.elements as elm

with schemdraw.Drawing() as d:
    # A single loop to illustrate sign bookkeeping
    Vs = elm.SourceV().up()
    Vs.label(['+', '$V_s$', '−'], loc='left')
    d += Vs

    R = elm.Resistor().right()
    R.label('$R$', loc='bottom')
    R.label(['+', '$v_R$', '−'], loc='top')
    d += R

    d += elm.Line().down().length(2)
    d += elm.Line().left().length(2)
    d += elm.Line().up().length(2)

    d += elm.LoopArrow(direction='cw', width=1.4, height=1.1).at((1, 1)).label('$I$')

For the clockwise traversal shown above, one consistent KVL statement is:

\[ V_s - v_R = 0,\qquad v_R = RI. \]

If you flip the resistor polarity, the equation becomes \(V_s + v_R = 0\) (and then \(v_R=RI\) would no longer match the marked polarity).

7.2 Contradictory orientations

It is perfectly fine to choose “wrong” current directions—your solution will simply return a negative value. What is not fine is choosing orientations that contradict your own definitions.

Typical contradictions:

  • choosing a current arrow one way but writing \(v=Ri\) with the polarity corresponding to the opposite direction,
  • using passive sign convention in some elements and the opposite convention in others without noticing,
  • reusing the same symbol (e.g. \(v\)) for different terminal pairs.
Show the code
import schemdraw
import schemdraw.elements as elm

with schemdraw.Drawing() as d:
    d += elm.Line().right().label('$i$', loc='top')
    R = elm.Resistor().right()
    R.label('$R$', loc='bottom')
    R.label(['+', '$v$', '−'], loc='top')
    d += R

In this schematic, the passive sign convention means \(v = Ri\) with \(+\) on the left. If you later write \(v = -Ri\), that is a different definition of \(v\) (or a sign mistake).

7.3 Missing equations

A solvable setup requires as many independent equations as unknowns (after accounting for known sources/constraints).

Common ways to end up short:

  • writing KCL for too few nodes (or forgetting the reference node choice),
  • writing KVL for loops that are not independent,
  • using mesh currents with a current source and forgetting to add the constraint (supermesh case),
  • introducing extra unknowns (e.g. both branch currents and mesh currents) without adding conversion relations.

Quick self-checks:

  • Count unknowns vs. independent equations.
  • In purely resistive circuits, the final system should be linear in the unknowns.
  • If you use a supermesh, you should have: one KVL for the supermesh + one current-source constraint.

7.4 One element belonging to multiple meshes

When a component sits on a branch shared by two meshes, the branch current is the difference of mesh currents, so the element voltage depends on that difference. The sign is opposite in the two mesh KVL equations.

Show the code
import schemdraw
import schemdraw.elements as elm

with schemdraw.Drawing() as d:
    # Two meshes sharing a vertical resistor
    d += elm.SourceV().up().label(['+', '$V_s$', '−'], loc='left')
    d += elm.Resistor().right().label('$R_1$', loc='bottom').label(['+', '$v_1$', '−'], loc='top')
    shared_top = d.here
    d += elm.Resistor().right().label('$R_3$', loc='bottom').label(['+', '$v_3$', '−'], loc='top')
    d += elm.Resistor().down().length(2).label('$R_4$', loc='right').label(['+', '$v_4$', '−'], loc='left')
    d += elm.Line().left().length(4)

    d.push()
    d.here = shared_top
    Rs = elm.Resistor().down().length(2)
    Rs.label('$R_s$', loc='left')
    Rs.label(['+', '$v_s$', '−'], loc='right')
    d += Rs
    d.pop()

    d += elm.LoopArrow(direction='cw', width=1.6, height=1.2).at((1, 1)).label('$I_1$')
    d += elm.LoopArrow(direction='cw', width=1.6, height=1.2).at((3, 1)).label('$I_2$')

If both meshes are clockwise, the shared-resistor current is \((I_1 - I_2)\) (downward for mesh 1, upward for mesh 2). Therefore:

\[ v_s = R_s (I_1 - I_2), \]

and in the second mesh equation it appears with the opposite sign via \((I_2-I_1)\).

8. Capacitor – a dynamic element

Resistors relate voltage and current algebraically (\(v = Ri\)). A capacitor introduces dynamics: its current depends on how fast the voltage changes in time. This is where circuit equations become differential equations.

8.1 A new current–voltage relation

For an ideal capacitor \(C\) (capacitance in farads, \([F] = [C/V]\)), the defining relation is:

\[ i_C(t) = C\,\frac{d v_C(t)}{dt}. \]

Equivalently, the voltage is the time integral of current:

\[ v_C(t) = v_C(t_0) + \frac{1}{C}\int_{t_0}^{t} i_C(\tau)\, d\tau. \]

Interpretation and key consequence:

  • the capacitor voltage cannot change instantaneously unless the current becomes infinite,
  • therefore, \(v_C(t)\) is continuous in time in ideal circuit models.

Passive sign convention still applies: if the reference current \(i_C\) enters the \(+\) terminal of \(v_C\), then the equation above is used as written.

Show the code
import schemdraw
import schemdraw.elements as elm

with schemdraw.Drawing() as d:
    d += elm.Line().right().label('$i_C$', loc='top')
    C1 = elm.Capacitor().right()
    C1.label('$C$', loc='bottom')
    C1.label(['+', '$v_C$', '−'], loc='top')
    d += C1

8.2 What changes in the procedure

The high-level workflow (pick unknowns → write KCL/KVL → substitute element laws) stays the same, but two practical things change immediately:

  1. You get differential equations.
    After substituting \(i_C = C\,dv_C/dt\), KCL/KVL produce ODEs (and sometimes DAEs if you mix variables).

  2. Initial conditions matter.
    To obtain a unique time-domain solution you typically need \(v_C(t_0)\) (and for inductors, \(i_L(t_0)\)). These values come from the problem statement or from continuity at switching instants.

  3. Choose state variables wisely.
    A common choice is capacitor voltages and inductor currents. This often leads to a minimal-order system.

  4. Work in the Laplace domain (optional).
    In many linear problems, applying the Laplace transform turns derivatives into algebraic factors (\(s\)), making analysis similar to resistive circuits—at the cost of tracking initial conditions properly.

8.3 What stays the same

Even with capacitors (and other dynamic elements), the fundamentals are unchanged:

  • KCL and KVL still apply under the lumped-element/quasi-static assumptions.
  • Reference directions are still conventions. Negative solutions still mean “opposite of what you assumed.”
  • Power and passive sign convention still work: instantaneous power is \(p(t)=v(t)i(t)\).
  • Equivalent-circuit thinking remains useful: you can still form Thévenin/Norton equivalents “seen by the capacitor” to simplify the differential equation.

9. An RC example – building the model

We now build a complete time-domain model for the simplest dynamic circuit: a resistor feeding a capacitor.

9.1 Choosing variables

A natural choice of variables is:

  • the state variable: capacitor voltage \(v_C(t)\),
  • the branch current: \(i(t)\) (the same through \(R\) and \(C\) in series).

We treat the source voltage as a known input \(v_s(t)\) (it can be a step, sinusoid, or any given waveform).

Show the code
import schemdraw
import schemdraw.elements as elm

with schemdraw.Drawing() as d:
    Vs = elm.SourceV().up()
    Vs.label(['+', '$v_s(t)$', '−'], loc='left')
    d += Vs

    d += elm.Line().right().label('$i(t)$', loc='top')
    R1 = elm.Resistor().right()
    R1.label('$R$', loc='bottom')
    R1.label(['+', '$v_R$', '−'], loc='top')
    d += R1

    d += elm.Line().right()
    C1 = elm.Capacitor().down().length(2)
    C1.label('$C$', loc='right')
    C1.label(['+', '$v_C(t)$', '−'], loc='left')
    d += C1
    d += elm.Ground()

9.2 Kirchhoff

There is one loop. Apply KVL (taking the marked polarities):

\[ v_s(t) - v_R(t) - v_C(t) = 0. \]

Now substitute the element laws:

\[ v_R(t) = R\,i(t),\qquad i(t) = C\,\frac{d v_C(t)}{dt}. \]

9.3 The resulting differential equation

Combining the above gives a first-order linear ODE for the capacitor voltage:

\[ RC\,\frac{d v_C(t)}{dt} + v_C(t) = v_s(t). \]

To obtain a unique solution, you also need an initial condition such as \(v_C(t_0)\) (set by the circuit history and the continuity of capacitor voltage).