Make Blocks #3阶段2 - 基于INA219的电流和功率监测模块
该项目使用了INA219,实现了电流监测模块的设计,它的主要功能为:电流监测。
标签
电流
INA219
Make Blocks
立冬的雪
更新2026-07-30
38

任务介绍

本次任务的核心目标是开发一款电流和功率监测模块。设计一款电流和功率监测模块,能实时测量直流回路的电压、电流,并输出功率值,可用于电源效率分析、电池电量监测等场景。基本要求:

  1. 使用高侧电流监测专用IC(推荐INA219、INA226 等)
  2. 支持0~26V总线电压(测量输入端),电流量程由分流电阻决定
  3. 数字接口输出(I2C优先)
  4. 板载分流电阻(推荐0.1Ω/1W或更低,1%精度)
  5. 提供输入和输出接线端子

当然了整体的设计方案我们参考了通过接口smokeBUS,我们提供标准2.54mm控制输入接口,大功率接口使用的是螺钉式接线端子。
0

模块介绍

本次选择的是INA219来完成本次的任务,INA219是一款高精度的电流/电压监测芯片,常用于嵌入式系统和电源管理。它通过内置的放大器和模数转换器(ADC)测量流过电路的电流,同时还能监测电源电压,从而计算功率。使用时,通常把它串联在电源和负载之间,芯片内部会把微小的电压降放大,再通过I²C接口把测量结果传给微控制器,比如Arduino或树莓派。它的优势在于体积小、精度高,而且可以同时测量电压、电流和功率,非常适合对电源状态要求严格的项目,比如电池管理、电机驱动或太阳能系统。INA219还能处理高达26V的电压,最大测量电流可达3.2A,支持软件校准,保证数据稳定可靠,而且芯片自带保护机制,防止过流或短路损坏。对于开发者来说,它无需复杂外接电路,只需几根线就能实现实时监测,比传统电流表方便很多,而且数据可以直接在程序中使用,方便做能耗统计、异常报警或自动控制。总的来说,INA219是一款操作简单、功能全面、适合各种电子项目的智能电流电压监控芯片。

原理图和PCB模块介绍
0

原理图

基于INA219的mikroBUS接口电流检测模块,完全遵循mikroBUS标准外设接口规范设计,核心依托INA219零漂移双向电流/功率监测芯片,可在0V至26V的总线电压范围内,高精度同步采集电流、电压与功率数据,全温域测量精度最高可达0.5%,支持双向电流检测,能精准识别充放电等不同电流流向。模块将INA219的I2C通信引脚、电源引脚完整映射到mikroBUS标准接口的对应针脚,无需自定义接线即可直接对接所有支持mikroBUS生态的开发板,板载的4.7K限流电阻完成I2C信号阻抗匹配,搭配100nF电源滤波电容有效抑制供电纹波,保障通信与测量稳定性,外置100毫欧精密采样电阻预留扩展端口,可按需调整采样量程适配不同功率的被测电路,配套的电源指示灯可直观反馈模块供电状态,无需复杂硬件调试,借助成熟的开源驱动库即可快速完成数据读取与校准配置,大幅降低嵌入式项目中电源功耗监测的开发门槛。

原理图
0

INA219电流检测专用PCB,整体布局紧凑规整,核心INA219芯片放置在板面中心区域,采样电阻采用开尔文布线设计,将大电流路径与微小电压采样路径完全分离,避免走线电阻压降影响测量精度,板上A0、A1引脚预留I2C地址配置位,可灵活修改设备地址规避多节点通信冲突,VCC SEL引脚支持供电配置切换,配套的LED1电源指示灯搭配限流电阻直观反馈模块供电状态,板边CN1外设接口完整引出所有通信与电源引脚,完全适配mikroBUS标准接口规范,I2C通信走线短且阻抗连续,搭配周边阻容元件完成信号滤波与阻抗匹配,整体大面积铺铜连通GND网络,有效抑制电磁干扰,保障0-26V总线电压、双向电流的高精度稳定采集。

PCB
0

3D效果图
0

实物图

软件调试

我们本次主要是进行一下芯片驱动进行电流和电压的采集,这次我们使用带屏十二指神探进行主要的软件设计,进行可视化的显示。

INA219 初始化与硬件平均

初始化这块最容易踩坑的是调用顺序。标定函数 set_calibration_* 本身会写整个 CONFIG 寄存器,所以硬件平均一定要在标定之后再设,否则会被覆盖掉。我在代码里专门加了注释提醒自己:

ina219 = INA219(i2c1, addr=INA_ADDR)



# 硬件平均必须在 set_calibration_* 之后设置,因为标定也会写 CONFIG
ina219.set_averaging(INA_HW_AVERAGE) # INA_HW_AVERAGE = 32
CALIBRATIONS = [
('32V/2A', 'set_calibration_32V_2A'),
('32V/1A', 'set_calibration_32V_1A'),
('16V/400m', 'set_calibration_16V_400mA'),
]
cal_index = 0
getattr(ina219, CALIBRATIONS[cal_index][1])()

给驱动补上 set_averaging

参考驱动原样拷进来是能用的,但它只有 12-bit 单次采样,噪声偏大。我给它补了一个 set_averaging 方法,同时设置分流 ADC(SADC)和总线 ADC(BADC)两个字段。这段是我这次改动最多的地方:


def set_averaging(self, n_samples):
"""Set hardware averaging depth on both shunt (SADC) and bus (BADC) ADCs."""
sadc_bits = {
1: ..., 2: ..., 4: ..., 8: ...,
16: _CONFIG_SADCRES_12BIT_16S_8510US,
32: _CONFIG_SADCRES_12BIT_32S_17MS,
64: _CONFIG_SADCRES_12BIT_64S_34MS,
128: _CONFIG_SADCRES_12BIT_128S_69MS,
}
# BADC[10:7]TI 手册 Table 3 的编码
badc_bits = {
1: 0x0180, 2: 0x0280, 4: 0x0300, 8: 0x0380,
16: 0x0400, 32: 0x0480, 64: 0x0500, 128: 0x0680,
}
if n_samples not in sadc_bits:
raise ValueError("n_samples must be 1, 2, 4, ... 128")
config = self._read_register(_REG_CONFIG)
config = (config & ~(_CONFIG_SADCRES_MASK | _CONFIG_BADCRES_MASK))
config |= sadc_bits[n_samples]
config |= badc_bits[n_samples]
self._write_register(_REG_CONFIG, config)

这里的关键是先用掩码把 SADC、BADC 两块清零,再或进新值,这样不会动到 CONFIG 里其它位(量程、增益那些)。badc_bits 那张表里的数值是我对着 TI 手册 SBOS448 的 Table 3 一个个填的,填错一位平均深度就不对。32 次平均对应约 17 ms 一次转换,噪声大概能压到单次的 1/5 到 1/6。

软件 EMA 平滑

硬件平均之上,我又加了一层软件的指数滑动平均。道理很简单:硬件平均管的是单次读数内部的噪声,EMA 管的是读数之间的抖动,两者叠加显示才真正稳下来。

EMA_ALPHA = 0.4
_ema_state = {'bus': None, 'shunt': None, 'curr': None, 'pow': None}

def ema_update(key, raw):
prev = _ema_state[key]
if prev is None:
sm = raw
else:
sm = EMA_ALPHA * raw + (1.0 - EMA_ALPHA) * prev
_ema_state[key] = sm
return sm

结合电子负载进行实测显示,连接如下:
0

初始状态下会看到一些共模电压的存在,正式采集后可以看到各采集数据:
0

电流比较稳定,电压采集一塌糊地,波动很大,原因可能有很多,比如我们使用的电子负载波动,可以看到0.5A电压就被拉下来了,说明也是存在很多问题,不过整体驱动采集都是成功的。

心得体会

我们这次采用了标准化接口的设计,主要也是希望可以做出一些通用的模块,不过在测试过程中发现,还是有很多需要改进的部分,比如公模电压的存在,电压采集不稳等问题,这些还是需要进一步研究,不过通过增加滤波已经可以实现比较稳定的电流检测,后续我们将通过校准功能对程序进一步优化。

附件下载
INA219-SmokeBUS.zip
INA219.zip
团队介绍
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号