INA219电流监测模块接Arduino:测电压电流功率

2026-11-10 20:15:36 17阅读 所属项目:ESP32 开发板

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

INA219电流传感器模块与Arduino Uno开发板

这篇把它接 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 跳线切换,一个总线上挂多颗模块不冲突。

INA219模块引脚图,标注Vin+、Vin-、SDA、SCL、GND、VCC

引脚一览:功率侧 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 的板子都适用。

INA219与Arduino接线电路图,含电源与负载

完整接线图:传感器串在电源正极与负载之间。

再说测电流这半。分流电阻必须串进被测回路: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 当负载,逐颗点亮看电流功率变化,串口读数跟理论值对得上,图像清晰。他们那套测试电路值得照着搭一遍,先验证模块好用,再上真负载。这种验证顺序我建议照搬:先用几毫安的静态负载确认模块和库都正常,再切到电机这种带尖峰的负载,出了问题好定位——是模块的事还是电源的事,一步就分清。

Arduino与INA219测试电路实物图

最后收几个坑:一是地址冲突,两颗模块都挂总线上时,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 之后,舵机堵转电流、电池放电曲线都能推到手机上看,这套组合玩动力监控的人用得很多。

总的来说,九块九美金的模块,把万用表串进回路的活儿全接了,还能挂着不动持续记录。做电机动力监控、电池功耗统计这类活儿,这颗芯片是性价比最高的一条路,参数党的工具箱里该有一格是它的。


作者:舵机老炮
链接:https://www.aiddithome.com/p/96b3737b5b56e.html
本作版权归作者所有,未经允许请勿转载。若存在违规行为,您可以点击 “举报”。


登录 后发表评论
4条评论
胶佬憨憨
1楼 · 3小时前

已下单,回来照着接线图搭

拆机党
2楼 · 3小时前

问下ESP32那接法,GPIO21/22直连模块SDA SCL就行?中间要不要电平转换,3.3V系统接5V供电的模块我有点虚

锡点
3楼 · 3小时前

被电机尖峰打复位这个我踩过,深有同感,电容真不能省

电烙铁爱好者
4楼 · 3小时前

上个月刚用这颗模块给小车做过电耗统计,回来对了一遍,文章里的分辨率数据没错:3.2A量程0.8mA,降档到400mA是0.1mA。补充一句,测舵机静态电流记得把量程降下来,不然读数最后一位一直在跳,看着心烦。高位检测那节讲得挺到位,很多人不知道串地线会把参考地搞歪。