Current and Voltage Sensing Design
1:54
Preparing guidance for user request.
Using Knowledge Base Tool.
Using Calculator Tool.
Using Calculator Tool.
Using Calculator Tool.
Planning guidance and queries.
AC mains ─────┐ ┌── H-bridge (4 × [IRLZ44N](https://www.flux.ai/search?type=components&q=IRLZ44N))
│ │
│ [100 µH Inductor](https://www.flux.ai/search?type=components&q=100uH%20Inductor)
│ │
Injection ►●───────────────────────┴───► Load / Grid
│
│ (shunt branch) DC bus 24 – 48 V
│ │
│ ┌───► [220 µF Capacitor](https://www.flux.ai/search?type=components&q=220uF%20Capacitor)
│ │
┌────────────▼────────────┐ ┌─────▼───────────────────────────┐
│ Sensors & Conditioning │ │ Power Inverter Stage │
│ │ │ (PWM-driven H-bridge + LC path) │
│ ┌─────────────────────┐ │ └─────────────────────────────────┘
│ │ [ACS712ELCTR-30A-T] │─┤
│ └─────────────────────┘ │
│ (current) │
│ ┌─────────────────────┐ │
│ │ R-R divider + RC │─┤ (voltage)
│ └─────────────────────┘ │
└────────┬──────┬────────┘
│ │ 3.3 V analog, VREF=3.3 V/2
▼ ▼
[TLV9062](https://www.flux.ai/search?type=components&q=TLV9062) (dual op-amp: bias & anti-alias)
│
▼ ┌───────────────────────────────────────┐
12-bit ADC0/1 ◄──────┤ Raspberry Pi Pico │
│ – Goertzel @ 250 Hz (block N=100) │
│ – PI current loop (2 kHz) │
│ – PWM (50 kHz) on GPIO 2/3 (A/B) │
└───────┬──────────────┬────────────────┘
│ │
[IR2110](https://www.flux.ai/search?type=components&q=IR2110) (high/low-side gate driver, isolated 12 V)
│
▼
Gates
2. Signal-conditioning notes
| Channel | Sensor | Full-scale design | Anti-alias RC | Notes (Flux KB: “ADC filter design”) |
|---|---|---|---|---|
| Current | ACS712ELCTR-30A-T (66 mV / A) | ±30 A ⇒ ±1.98 V around 1.65 V mid-supply | R = 1 kΩ, C = 330 nF → fc ≈ 480 Hz | Keeps aliasing below Fs/10 yet passes 250 Hz with <3 dB loss. |
| Voltage | Divider 230 VRMS→±2 V (ratio ≈ 1:75) | ±325 Vpk ⇒ ±2.17 V around 1.65 V | R = 4.7 kΩ, C = 100 nF → fc ≈ 340 Hz | Divider impedance (4.7 k ∥ 75 Ω) ≤ 4 kΩ, within Pico ADC acquisition spec. |
k = N·f / Fs = 100·250 / 5000 = 5 (integer bin)
w0 = 2π·k / N = π/10 = 0.314159265 rad
coeff= 2·cos(w0) = 1.902113032 (mathematical constant)
MicroPython
C-like pseudocode (SDK)Python
import array, math, rp2, machine FS = 5000 # Hz N = 100 # samples / block K = 5 COEFF= 1.902113032 # 2*cos(pi/10) adc = machine.ADC(0) timer= machine.Timer() samples = array.array('H', [0]*N) # raw 12-bit samples idx = 0 ready = False def adc_isr(t): global idx, ready samples[idx] = adc.read_u16() # 0…65535 idx += 1 if idx >= N: idx = 0 ready = True timer.init(freq=FS, mode=machine.Timer.PERIODIC, callback=adc_isr) def goertzel(buf): s_prev = s_prev2 = 0.0 for x in buf: # scale 0…65535 → ±1 v = (x/65535.0 - 0.5)*2 s = v + COEFF*s_prev - s_prev2 s_prev2, s_prev = s_prev, s real = s_prev - s_prev2*math.cos(math.pi/10) imag = s_prev2*math.sin(math.pi/10) mag = math.sqrt(real*real + imag*imag) phase= math.atan2(imag, real) return mag, phase # radians while True: if ready: ready = False mag, ph = goertzel(samples) # Invert phase for compensation ref_phase = ph + math.pi # Store for PI current loop
C
#define FS 5000 #define N 100 #define K 5 #define COEFF 1.902113032 // 2*cos(pi/10) void goertzel(uint16_t *buf, double *mag, double *phase) { double s_prev = 0, s_prev2 = 0; for (int i = 0; i < N; i++) { double v = ((double)buf[i]/65535.0 - 0.5)*2.0; double s = v + COEFF*s_prev - s_prev2; s_prev2 = s_prev; s_prev = s; } double real = s_prev - s_prev2*cos(M_PI/10.0); double imag = s_prev2*sin(M_PI/10.0); *mag = sqrt(real*real + imag*imag); *phase = atan2(imag, real); }
i_ref(t) = -Î₅ * sin(2π·5f₀·t + φ₅)Î₅ , φ₅ are Goertzel magnitude & phase.e = i_ref − i_meas
d = Kp*e + Ki*∫e dt
duty = clamp( 0.5 + d , 0 … 0.95 )
Kp = 0.2, Ki = 50 (tune per section 9). Update at 2 kHz (every 2ⁿᵈ sample) to ease MCU load.Python
from machine import Pin, PWM import math, array, machine, rp2 # === USER SETTINGS === FS = 5000 N = 100 Kp = 0.2 Ki = 50 PWM_FREQ = 50000 # 50 kHz switching COEFF= 1.902113032 # === HARDWARE === adc_i = machine.ADC(0) # current pwm_a = PWM(Pin(2)) pwm_b = PWM(Pin(3)) for p in (pwm_a, pwm_b): p.freq(PWM_FREQ) duty_a = duty_b = 32768 pwm_a.duty_u16(duty_a) pwm_b.duty_u16(duty_b) samples = array.array('H', [0]*N) idx = 0; ready = False integrator = 0.0 def tim_cb(t): global idx, ready samples[idx] = adc_i.read_u16() idx += 1 if idx >= N: idx = 0 ready = True machine.Timer().init(freq=FS, mode=machine.Timer.PERIODIC, callback=tim_cb) def goertzel(buf): s_prev = s_prev2 = 0.0 for x in buf: v = (x/65535 - 0.5)*2 s = v + COEFF*s_prev - s_prev2 s_prev2, s_prev = s_prev, s real = s_prev - s_prev2*math.cos(math.pi/10) imag = s_prev2*math.sin(math.pi/10) mag = math.sqrt(real*real + imag*imag) phase= math.atan2(imag, real) return mag, phase while True: if ready: ready = False mag, ph = goertzel(samples) # Build one-cycle reference ref = [ -mag*math.sin(2*math.pi*5*i/N + ph) for i in range(N) ] # PI loop over the same block for i in range(N): i_meas = (samples[i]/65535 - 0.5)*2*30 # back-scale to amperes err = ref[i] - i_meas integrator += err / FS duty = 0.5 + Kp*err + Ki*integrator duty_clamped = min(max(duty, 0.05), 0.95) pwm_val = int(duty_clamped*65535) pwm_a.duty_u16(pwm_val) pwm_b.duty_u16(65535 - pwm_val)
7. PWM & gate-drive guidance
| Parameter | Recommendation (bench ≤ 100 W) |
|---|---|
| Fsw | 50 kHz (far above 250 Hz target, below IR2110 10 MHz limit) |
| Dead-time | 1 µs (set in PWM hardware) |
| Gate driver | IR2110 with local 100 nF + 10 µF decoupling (Flux KB: “designing gate drive circuits”) |
| Vgs | 10–12 V isolated DC/DC; include 10 Ω series gate resistors & 100 kΩ pull-down (Flux KB) |
| MOSFETs | Logic-level IRLZ44N or similar, RDS(on) ≈ 20 mΩ |
9. Tuning & 60 Hz adaptation
| Item | 50 Hz (given) | 60 Hz variant |
|---|---|---|
| ffund | 50 Hz | 60 Hz |
| 5th harmonic | 250 Hz | 300 Hz |
| Keep Fs | 5 kHz | 6 kHz (gives 100 samples/block) |
| k (Goertzel) | 5 | 5 |
| w0 | 2π·5/100 = π/10 | 2π·5/100 = π/10 (same) |
| Re-compute COEFF | unchanged | unchanged |
| PI gains | Increase Kp, Ki by ~20 % to match 20 % higher electrical frequency. |
fc ≤ Fs/10.Ready.
Reviews
Inspect
Raspberry Pi Pico
Controls
Properties
Assets
id=SC0915--3DModel-STEP-56544
id=PinHeader_1x04_P2.54mm_Vertical
id=PinHeader_1x20_P2.54mm_Vertical
id=PinHeader_1x20_P2.54mm_Vertical
Welcome 👋
Flux accelerates your PCB design with AI.
Create your account to start using this component and bring your ideas to life.