玩舵机和电机的都懂一个道理:动力这东西,光看标称参数是不够的,得知道它真实吃了多少电。测电压电流,很多人第一反应是拿万用表怼上去串个表笔,但电机一动,指针乱跳,你还盯着表腾不出手看串口。我更愿意在回路上挂一颗 INA219,I2C 直接读数,电压、电流、功率一次全给,精度官方标 ±1%,比肉眼盯表靠谱得多。

这篇把它接 Arduino 的路子从头到尾捋一遍:接线、装库、跑示例、换量程,最后讲几个我踩过的坑。ESP32 的接法也顺带说一句,差别只有 I2C 引脚。
INA219 是个什么东西
INA219 是 TI 家的电流监测芯片,Adafruit 做成了小模块,官网上那种 STEMMA QT 版本,价格 9.95 美元(截至11月10日)。核心原理不复杂:模块上有一颗 0.1 欧、1% 精度的分流电阻,芯片内部的精密放大器测它两端的压差,最大输入差 ±320mV,对应最大量程就是 ±3.2A。
采样走内部 12 位 ADC,在 ±3.2A 量程下分辨率 0.8mA;如果内部增益调到 div8 档,最大电流 ±400mA,分辨率能到 0.1mA。总线电压可以测到 26V,所以 5V、12V、24V 的动力回路都罩得住。通信是 I2C,7 位地址有 0x40、0x41、0x44、0x45 四档可选,靠模块背面的 A0、A1 跳线切换,一个总线上挂多颗模块不冲突。

引脚一览:功率侧 Vin+、Vin-,I2C 侧 SDA、SCL,供电 VCC、GND。
接线:先供电,再把分流电阻串进回路
接线分两半,先说通信和供电这半。模块 VCC 接 Arduino 的 5V,GND 接 GND,SDA、SCL 对应接上。老一点的 Arduino(R3 之前)没有独立 I2C 口,SDA 在 A4、SCL 在 A5;R3 及以后,AREF 旁边多了专用 SDA、SCL 引脚;老款 Mega 的 I2C 在 20、21 号脚,别接混。ESP32 的话,硬件 I2C 默认在 GPIO21(SDA)和 GPIO22(SCL),Adafruit 那套库对带 I2C 的板子都适用。

完整接线图:传感器串在电源正极与负载之间。
再说测电流这半。分流电阻必须串进被测回路:Vin+ 接被测电路电源的正极,Vin- 接负载的正极引脚,再从电源负极拉一根线回 GND 共地。这样接是高位检测,传感器同时量得到负载电压。
官方接线页专门用红框提醒过一件事:像直流电机这种启动瞬间猛抽电流的负载,会在电源线上打出尖峰,INA219 可能直接被冲得复位、读数乱跳。真要在电机回路上用,得并一颗大电容把电机和电源隔离开,再加续流二极管挡住反电动势。舵机同理——堵转那一下的电流冲得比标称高好几倍,这是玩过舵机的人都知道的脾气。另外所有电压都是相对处理器地测的,共地这根线不能省,省了负载电压就飘。
装库、跑示例、看读数
库不用手找。打开 Arduino IDE 的库管理器,搜 Adafruit INA219,装官方库。装完从 File 菜单进 Examples,找 Adafruit_INA219 下面的 getcurrent 示例。下面的代码我按 how2electronics 页面上的示例逐字符搬过来,只把尖括号的 include 换成引号写法(站点会吃掉尖括号,两种写法在 Arduino 工具链下等价):
#include "Wire.h"
#include "Adafruit_INA219.h"
Adafruit_INA219 ina219;
void setup(void)
{
Serial.begin(9600);
while (!Serial)
{
delay(1);
}
// Initialize the INA219.
if (! ina219.begin())
{
Serial.println("Failed to find INA219 chip");
while (1)
{
delay(10);
}
}
// To use a slightly lower 32V, 1A range (higher precision on amps):
//ina219.setCalibration_32V_1A();
// Or to use a lower 16V, 400mA range, call:
//ina219.setCalibration_16V_400mA();
Serial.println("Measuring voltage, current, and power with INA219 ...");
}
void loop(void)
{
float shuntvoltage = 0;
float busvoltage = 0;
float current_mA = 0;
float loadvoltage = 0;
float power_mW = 0;
shuntvoltage = ina219.getShuntVoltage_mV();
busvoltage = ina219.getBusVoltage_V();
current_mA = ina219.getCurrent_mA();
power_mW = ina219.getPower_mW();
loadvoltage = busvoltage + (shuntvoltage / 1000);
Serial.print("Bus Voltage: "); Serial.print(busvoltage); Serial.println(" V");
Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
Serial.print("Load Voltage: "); Serial.print(loadvoltage); Serial.println(" V");
Serial.print("Current: "); Serial.print(current_mA); Serial.println(" mA");
Serial.print("Power: "); Serial.print(power_mW); Serial.println(" mW");
Serial.println("");
delay(1000);
}上传完开串口监视器,波特率 9600。五个读数的含义要说清:Bus Voltage 是 GND 到 Vin- 之间的电压,也就是被测电路看到的总电压;Shunt Voltage 是分流电阻两端的压差(毫伏);Current 由欧姆定律从分流压差算出来;Power 芯片直接算好给你。负载电压要自己加一下:loadvoltage = busvoltage + shuntvoltage / 1000,代码里就是这么干的,直接抄就行。
高位检测为什么省事
传统测电流是把万用表串进回路的地线一侧,也就是低位检测。这么干有个隐患:地线上多了个几百毫欧的电阻,被测电路的参考地就不再是电源地,ADC 读数、PWM 都可能跟着歪。INA219 用的是高位检测,分流电阻串在电源正极那一侧,地线一根到底,被测电路完全无感。这也解释了为什么官方要求共地:芯片测的所有电压都以处理器的地为参考,那根 GND 回路线一断,读数就没有意义了。
功率不用自己乘。芯片内部有专门的功率寄存器,电流和总线电压测完直接在片内算好,getPower_mW() 拿回来的就是现成的毫瓦数。做电池功耗统计的时候,一分钟采一次点,功率曲线对时间积分,耗电毫安时就能算出来,整套监控不用外加任何器件。
量程校准:小电流要把档位降下来
默认初始化是 32V、2A 量程。测小电流的话精度会吃亏,代码里那两行注释就是为此准备的:setCalibration_32V_1A() 换成 32V、1A 量程,量程小了电流精度更高;setCalibration_16V_400mA() 再降一档,16V、400mA。想吃到 0.1mA 分辨率,就得用 400mA 这档——测舵机静态电流、传感器功耗这类几十毫安级的东西,这一档才算用到了点子上,3.2A 量程下 0.8mA 步进,小电流读数晃得厉害。
反过来,大电流回路别硬上高档位:分流电阻最大只吃 ±320mV 压差,超量程读数会饱和。Adafruit 那颗模块还留了一手,0.1 欧电阻可以拆下来换,进阶玩家换更小的分流值就能扩量程,代价是分辨率,自己权衡。
实测效果与几个坑
how2electronics 的实测是用四颗不同颜色的 LED 当负载,逐颗点亮看电流功率变化,串口读数跟理论值对得上,图像清晰。他们那套测试电路值得照着搭一遍,先验证模块好用,再上真负载。这种验证顺序我建议照搬:先用几毫安的静态负载确认模块和库都正常,再切到电机这种带尖峰的负载,出了问题好定位——是模块的事还是电源的事,一步就分清。

最后收几个坑:一是地址冲突,两颗模块都挂总线上时,A0、A1 跳线必须拨开,四档地址里挑两个不同的;二是读数全是 0 或者初始化失败,九成是 SDA/SCL 接错脚,先查是不是把 A4/A5 和专用 I2C 口搞混,失败时库会打印 Failed to find INA219 chip,看到这句直接查线;三是电机类负载没加去耦电容,读数乱跳甚至模块复位,官方也点过名,电容和续流二极管别省;四是量程没选对,小电流用默认 2A 档,读数跳动看不出趋势;五是供电别想当然,模块 5V 或 3V 都能跑,但跟主控逻辑电平保持一致最稳,接 ESP32 这类 3.3V 系统就用 3V 档供电。
换 ESP32 宿主也顺手
想把功耗数据扔到网上做远程监控的话,ESP32 是更好的宿主。接线只动两个脚:SDA 走 GPIO21,SCL 走 GPIO22,VCC、GND 照旧,被测回路那半完全不变。库和示例代码一字不用改,Adafruit 这套库对带 I2C 的板子都适用。C3、S3 这类变种的默认 I2C 引脚不一样,上板前对照各自引脚图确认一下,别想当然。加上 Wi-Fi 之后,舵机堵转电流、电池放电曲线都能推到手机上看,这套组合玩动力监控的人用得很多。
总的来说,九块九美金的模块,把万用表串进回路的活儿全接了,还能挂着不动持续记录。做电机动力监控、电池功耗统计这类活儿,这颗芯片是性价比最高的一条路,参数党的工具箱里该有一格是它的。











已下单,回来照着接线图搭
问下ESP32那接法,GPIO21/22直连模块SDA SCL就行?中间要不要电平转换,3.3V系统接5V供电的模块我有点虚
被电机尖峰打复位这个我踩过,深有同感,电容真不能省
上个月刚用这颗模块给小车做过电耗统计,回来对了一遍,文章里的分辨率数据没错:3.2A量程0.8mA,降档到400mA是0.1mA。补充一句,测舵机静态电流记得把量程降下来,不然读数最后一位一直在跳,看着心烦。高位检测那节讲得挺到位,很多人不知道串地线会把参考地搞歪。