Objetivos de aprendizaje
Plantear el análisis de mallas como un sistema lineal y escribir la matriz por inspección.
Resolver un mismo circuito por mallas y por nodos y comprobar que los resultados son coherentes.
Contar las ecuaciones de cada método antes de resolver y decidir cuál conviene.
Analizar un puente de Wheatstone con un sensor resistivo por los dos métodos.
Teoría: Volumen I, capítulo 5 (métodos de mallas y de nodos) y capítulo 6 (Miguel-Medina, 2026). Tiempo: ~2 h
import sys
if "google.colab" in sys.modules:
%pip install -q git+https://github.com/telmomm/math-tools-biomedical-electronicsimport matplotlib.pyplot as plt
import numpy as np
import schemdraw
import schemdraw.elements as elm
import sympy as sp
from circuitmath.plotting import use_style
use_style()Idea clave¶
El método de mallas es el reflejo del método de nodos. Las incógnitas son las corrientes de malla, una por cada «ventana» del circuito, y la ley que se aplica es la de Kirchhoff de tensiones (KVL). El resultado vuelve a ser un sistema lineal:
Si todas las corrientes de malla se toman en el mismo sentido (horario), la matriz también se escribe por inspección:
es la suma de las resistencias de la malla ;
es la resistencia que comparten las mallas y , con signo negativo;
es la suma de las fuentes de tensión de la malla , positivas si empujan la corriente en el sentido de .
Los dos métodos resuelven el mismo circuito, pero no siempre con el mismo número de ecuaciones. Saber contarlas antes de empezar ahorra trabajo.
El circuito¶
Una escalera de tres mallas alimentada por una fuente de tensión. Las tres corrientes de malla giran en sentido horario.
with schemdraw.Drawing() as d:
d.config(unit=2.5, fontsize=12)
fuente = elm.SourceV().up().label("$V_s$")
r1 = elm.Resistor().right().label("$R_1$")
elm.Dot().label("a", loc="top")
r2 = elm.Resistor().down().label("$R_2$", loc="bottom")
base1 = elm.Line().left().tox(fuente.start)
r3 = elm.Resistor().right().at(r1.end).label("$R_3$")
elm.Dot().label("b", loc="top")
r4 = elm.Resistor().down().label("$R_4$", loc="bottom")
base2 = elm.Line().left().tox(r2.end)
r5 = elm.Resistor().right().at(r3.end).label("$R_5$")
elm.Dot().label("c", loc="top")
r6 = elm.Resistor().down().label("$R_6$", loc="bottom")
base3 = elm.Line().left().tox(r4.end)
elm.Ground().at(fuente.start)
elm.LoopCurrent([r1, r2, base1, fuente], pad=0.6).label("$i_1$")
elm.LoopCurrent([r3, r4, base2, r2], pad=0.6).label("$i_2$")
elm.LoopCurrent([r5, r6, base3, r4], pad=0.6).label("$i_3$")# Valores de los componentes <- cámbialos cuando quieras experimentar
R = {"R1": 1e3, "R2": 2.2e3, "R3": 1e3, "R4": 4.7e3, "R5": 1e3, "R6": 3.3e3} # ohmios
V_FUENTE = 10.0 # voltios1. Predice¶
La escalera tiene tres mallas. ¿Cuántas tensiones de nodo desconocidas tiene? (El nodo superior de la fuente no cuenta: su tensión es .)
En la matriz habrá un cero. ¿En qué posición y por qué?
Más abajo aparece un puente de Wheatstone alimentado por una fuente de tensión. Cuando lo veas, y antes de ejecutar su código, decide qué método necesita menos ecuaciones.
Tu predicción:
2. Ejecuta y explora¶
2.1 Las ecuaciones de malla, escritas tal cual¶
Recorremos cada malla en sentido horario y sumamos las caídas de tensión en las resistencias. Por una resistencia compartida, como , circula la diferencia de las dos corrientes de malla.
i1, i2, i3 = sp.symbols("i1 i2 i3")
R1, R2, R3, R4, R5, R6, Vs = sp.symbols("R1 R2 R3 R4 R5 R6 V_s")
malla1 = sp.Eq(R1 * i1 + R2 * (i1 - i2), Vs)
malla2 = sp.Eq(R2 * (i2 - i1) + R3 * i2 + R4 * (i2 - i3), 0)
malla3 = sp.Eq(R4 * (i3 - i2) + R5 * i3 + R6 * i3, 0)
R_sim, v_sim = sp.linear_eq_to_matrix([malla1, malla2, malla3], [i1, i2, i3])
R_simCompara la matriz con la regla de inspección: en la diagonal, la suma de las resistencias de cada malla; fuera de ella, la resistencia compartida con signo negativo. Tiene la misma forma que la matriz del cuaderno B1, con resistencias donde antes había conductancias.
2.2 Solución por mallas¶
def matriz_R(R1, R2, R3, R4, R5, R6):
"""Matriz de resistencias de malla de la escalera, escrita por inspección."""
return np.array(
[
[R1 + R2, -R2, 0],
[-R2, R2 + R3 + R4, -R4],
[0, -R4, R4 + R5 + R6],
]
)
R_mallas = matriz_R(**R)
v_mallas = np.array([V_FUENTE, 0, 0])
i_mallas = np.linalg.solve(R_mallas, v_mallas)
print("Corrientes de malla (mA):", np.round(i_mallas * 1e3, 4))Corrientes de malla (mA): [4.3268 1.748 0.9128]
2.3 El mismo circuito por nodos¶
Para aplicar lo aprendido en B1 hace falta que las fuentes sean de corriente. La fuente en serie con equivale (Norton) a una fuente de corriente que inyecta en el nodo a, con entre a y la referencia.
def matriz_G(R1, R2, R3, R4, R5, R6):
"""Matriz de conductancias de la escalera (nodos a, b y c)."""
G1, G2, G3, G4, G5, G6 = 1 / R1, 1 / R2, 1 / R3, 1 / R4, 1 / R5, 1 / R6
return np.array(
[
[G1 + G2 + G3, -G3, 0],
[-G3, G3 + G4 + G5, -G5],
[0, -G5, G5 + G6],
]
)
G_nodos = matriz_G(**R)
i_nodos = np.array([V_FUENTE / R["R1"], 0, 0])
v_nodos = np.linalg.solve(G_nodos, i_nodos)
print("Tensiones de nodo (V):", np.round(v_nodos, 4))Tensiones de nodo (V): [5.6732 3.9252 3.0124]
2.4 ¿Dicen lo mismo?¶
Los dos métodos dan incógnitas distintas (corrientes uno, tensiones el otro), así que no se pueden comparar directamente. Pero de las corrientes de malla se deducen las tensiones de nodo con la ley de Ohm: por circula , por circula y por circula .
v_desde_mallas = np.array(
[
R["R2"] * (i_mallas[0] - i_mallas[1]),
R["R4"] * (i_mallas[1] - i_mallas[2]),
R["R6"] * i_mallas[2],
]
)
print("Tensiones a partir de las mallas (V):", np.round(v_desde_mallas, 4))
print("Tensiones por nodos (V): ", np.round(v_nodos, 4))
print("¿Coinciden?", np.allclose(v_desde_mallas, v_nodos))Tensiones a partir de las mallas (V): [5.6732 3.9252 3.0124]
Tensiones por nodos (V): [5.6732 3.9252 3.0124]
¿Coinciden? True
2.5 Contar antes de resolver¶
En la escalera los dos métodos necesitan tres ecuaciones. No siempre hay empate. Para un circuito con elementos y nodos (contando la referencia):
el método de nodos necesita ecuaciones, menos una por cada fuente de tensión que fija directamente la tensión de un nodo;
el método de mallas necesita ecuaciones, menos una por cada fuente de corriente que fija directamente una corriente de malla.
La función siguiente hace la cuenta para cuatro circuitos.
def cuenta_ecuaciones(elementos, nodos, fuentes_tension=0, fuentes_corriente=0):
"""Número de ecuaciones del método de nodos y del método de mallas."""
por_nodos = nodos - 1 - fuentes_tension
por_mallas = elementos - nodos + 1 - fuentes_corriente
return por_nodos, por_mallas
circuitos = {
"Escalera de este cuaderno": dict(elementos=7, nodos=5, fuentes_tension=1),
"Puente de Wheatstone con detector": dict(elementos=6, nodos=4, fuentes_tension=1),
"Cinco ramas (fuente + R) en paralelo": dict(elementos=10, nodos=7, fuentes_tension=5),
"Un solo lazo: fuente y cuatro R en serie": dict(elementos=5, nodos=5, fuentes_tension=1),
}
print(f"{'Circuito':<42}{'Nodos':>7}{'Mallas':>8}")
for nombre, datos in circuitos.items():
por_nodos, por_mallas = cuenta_ecuaciones(**datos)
print(f"{nombre:<42}{por_nodos:>7}{por_mallas:>8}")Circuito Nodos Mallas
Escalera de este cuaderno 3 3
Puente de Wheatstone con detector 2 3
Cinco ramas (fuente + R) en paralelo 1 4
Un solo lazo: fuente y cuatro R en serie 3 1
Ningún método gana siempre. Muchas ramas en paralelo entre dos nodos favorecen al método de nodos (una sola ecuación: es el teorema de Millman del capítulo 5); muchos elementos en serie en pocos lazos favorecen al de mallas.
Hay además una diferencia de fondo. Las «ventanas» de un circuito solo están bien definidas si se puede dibujar en un plano sin que se crucen los cables; los nodos existen siempre. Por eso los simuladores no usan mallas, sino una variante del método de nodos que construirás en el cuaderno B3.
2.6 Hilo biomédico: un puente de Wheatstone con sensor¶
Muchos sensores biomédicos son resistencias que cambian con la magnitud que se mide: galgas extensométricas en transductores de presión arterial, termistores en sondas de temperatura. El cambio es pequeño (del orden del 1 %), y el puente de Wheatstone es el circuito clásico para convertirlo en una tensión.
En el puente de la figura, es el sensor y su variación relativa. La salida es la tensión entre los puntos a y b, que se mide con un instrumento de resistencia de entrada .
with schemdraw.Drawing() as d:
d.config(unit=2.2, fontsize=12)
fuente = elm.SourceV().up().length(4.4).label("$V_s$")
arriba1 = elm.Line().right().length(3.2)
r1 = elm.Resistor().down().label("$R_1$", loc="top")
elm.Dot().label("a", loc="left")
r2 = elm.Resistor().down().label("$R_2$", loc="top")
abajo1 = elm.Line().left().tox(fuente.start)
arriba2 = elm.Line().right().at(arriba1.end).length(3.2)
r3 = elm.Resistor().down().label("$R_3$", loc="bottom")
elm.Dot().label("b", loc="right")
r4 = elm.Resistor().down().label("$R_4 = R_0(1+x)$", loc="bottom")
abajo2 = elm.Line().left().tox(r2.end)
rd = elm.Resistor().at(r1.end).to(r3.end).label("$R_d$")
elm.Ground().at(fuente.start)
elm.LoopCurrent([arriba1, r1, abajo1, fuente], pad=0.7).label("$i_1$")
elm.LoopCurrent([arriba2, r3, rd, r1], pad=0.5).label("$i_2$")
elm.LoopCurrent([rd, r4, abajo2, r2], pad=0.5).label("$i_3$")Por mallas hay tres incógnitas. Con las corrientes de la figura:
Por nodos solo hay dos, y , porque la fuente fija la tensión del nodo superior. Los términos con pasan al segundo miembro:
Comprueba la primera fila de cada matriz sobre la figura antes de seguir.
R0 = 1e3 # ohmios, resistencia nominal de las cuatro ramas
RD = 10e3 # ohmios, resistencia de entrada del instrumento
V_PUENTE = 5.0 # voltios
def puente_por_mallas(x, Rd=RD):
"""Tensión de salida v_b - v_a del puente, por el método de mallas."""
R1, R2, R3, R4 = R0, R0, R0, R0 * (1 + x)
matriz = np.array(
[
[R1 + R2, -R1, -R2],
[-R1, R1 + R3 + Rd, -Rd],
[-R2, -Rd, R2 + R4 + Rd],
]
)
i = np.linalg.solve(matriz, [V_PUENTE, 0, 0])
return Rd * (i[1] - i[2]) # por Rd circula i2 - i3 de b hacia a
def puente_por_nodos(x, Rd=RD):
"""Tensión de salida v_b - v_a del puente, por el método de nodos."""
G1, G2, G3, G4, Gd = 1 / R0, 1 / R0, 1 / R0, 1 / (R0 * (1 + x)), 1 / Rd
matriz = np.array(
[
[G1 + G2 + Gd, -Gd],
[-Gd, G3 + G4 + Gd],
]
)
va, vb = np.linalg.solve(matriz, [G1 * V_PUENTE, G3 * V_PUENTE])
return vb - va
x = 0.01 # el sensor aumenta un 1 %
print(f"Salida por mallas: {puente_por_mallas(x) * 1e3:.4f} mV")
print(f"Salida por nodos: {puente_por_nodos(x) * 1e3:.4f} mV")
print("¿Salida nula con el puente equilibrado (x = 0)?", np.isclose(puente_por_nodos(0), 0))Salida por mallas: 11.3045 mV
Salida por nodos: 11.3045 mV
¿Salida nula con el puente equilibrado (x = 0)? True
Los dos métodos coinciden, y con el puente equilibrado la salida es nula. Para ver cómo responde el puente al sensor, barremos entre el −20 % y el +20 % y comparamos con la aproximación habitual para variaciones pequeñas y sin carga, .
variaciones = np.linspace(-0.2, 0.2, 81)
salida_cargada = np.array([puente_por_nodos(x) for x in variaciones])
salida_sin_carga = np.array([puente_por_nodos(x, Rd=1e12) for x in variaciones])
aproximacion = V_PUENTE * variaciones / 4
fig, ax = plt.subplots()
ax.plot(variaciones * 100, aproximacion * 1e3, "k--", linewidth=1, label="$V_s\\,x/4$")
ax.plot(variaciones * 100, salida_sin_carga * 1e3, label="Sin carga ($R_d \\to \\infty$)")
ax.plot(variaciones * 100, salida_cargada * 1e3, label=f"$R_d$ = {RD / 1e3:.0f} kΩ")
ax.set(
xlabel="Variación del sensor, $x$ (%)",
ylabel="Salida $v_b - v_a$ (mV)",
title="Respuesta del puente de Wheatstone",
)
ax.legend()
plt.show()
3. Explica¶
Los elementos de fuera de la diagonal de son negativos. ¿De dónde sale ese signo? ¿Qué cambiaría en la matriz si se tomara en sentido antihorario?
En la escalera, ; en el puente, ningún elemento de la matriz de mallas es cero. ¿Qué diferencia entre los dos circuitos lo explica?
En el puente, la fuente de tensión ahorra una ecuación al método de nodos pero ninguna al de mallas. ¿Por qué? ¿Qué pasaría si el puente se alimentara con una fuente de corriente?
En la última figura, la curva sin carga se separa de la recta cuando es grande. ¿Hacia qué lado y por qué? ¿Importa esa no linealidad para un sensor que varía un 1 %?
La resistencia del instrumento reduce la salida en una proporción casi constante. Estima esa proporción con el equivalente Thévenin del puente visto desde a y b y compárala con la figura.
4. Ejercicios¶
Básico. En la escalera, añade una segunda fuente de tensión de 5 V en serie con , con el terminal positivo hacia el nodo c. ¿Qué cambia en y qué en ? Resuelve por mallas y comprueba el resultado por nodos.
Aplicación. Escribe una función
escalera(N, R_serie, R_paralelo)que construya la matriz de mallas de una escalera de secciones iguales (pista:np.diagcon el argumentok). Resuelve el caso con una fuente de 10 V y representa las corrientes de malla. ¿Cómo decaen a lo largo de la escalera?Reto biomédico. Los transductores de presión arterial no usan un solo elemento sensible, sino un puente completo: las cuatro ramas son galgas, dos que aumentan ( y , con ) y dos que disminuyen ( y , con ).
Modifica
puente_por_nodospara que acepte la variación de cada rama y compara la salida del puente con un sensor (cuarto de puente), con dos ( con y con , medio puente) y con cuatro.¿Cuánto aumenta la sensibilidad en cada caso? ¿Qué configuración es exactamente lineal sin carga?
Un transductor típico se especifica con una sensibilidad de 5 µV por voltio de alimentación y por mmHg. Con V, ¿qué tensión corresponde a una presión de 120 mmHg? ¿Qué variación de las galgas supone en un puente completo?
Resumen¶
El método de mallas lleva a un sistema con la misma estructura que : simétrico, con la diagonal dominante y escrito por inspección.
Mallas y nodos dan resultados coherentes; pasar de unas incógnitas a otras es aplicar la ley de Ohm.
El número de ecuaciones se puede contar antes de resolver: por nodos y por mallas, menos las que ahorran las fuentes.
El método de nodos sirve para cualquier circuito, plano o no, y es el que se automatiza.
→ Siguiente: B3 · Construye tu mini-SPICE
- Miguel-Medina, T. (2026). Electrónica en Ingeniería Biomédica — Volumen I. Autopublicación. 10.5281/zenodo.22913382