INA3221 怎么用:ESP32 同时监测三路电压和电流

Cartoon of a black INA3221 board with three chunky shunt resistors, a red, an orange and a yellow wire each looping through its own channel, and a small blue OLED module showing three white traces

一颗 INA3221 模块可以同时盯住三路电源。把每一路电源分别穿过它的三个 0.1 Ω 采样电阻,再把 SDA 和 SCL 接到 ESP32,三路的电压、电流和功率就会通过一条 I2C 总线实时送过来。这篇教程把线接好,再把这些数字变成 OLED 上的实时读数。

INA3221 是怎么测电流的?

INA3221 测电流的办法,是在电流的必经之路上放一个阻值已知的电阻,再读它两端出现的电压。它的三个通道各是一个 0.1 Ω 电阻 —— 板上标着 R100 的那几块 —— 剩下交给欧姆定律:100 mA 流过 0.1 Ω,压降正好 10 mV。芯片的差分 ADC 读出这个压降,再通过 I2C 送出来 —— 除以电阻值就是电流,这一步 sketch 用的库替你算好了。它还在采样电阻的负载一侧测每路的电压,所以一个通道同时给出伏特、毫安和毫瓦。

采样电阻做得小是有意的。TI 数据手册给采样输入的满量程是 ±163.8 mV,所以再重的负载也只让这路电源付出很小的代价:500 mA 流过 0.1 Ω 只掉 50 mV —— 不过是 5 V 电源的百分之一 —— 这也是这块表可以长住在项目里而不把项目饿着的原因。芯片做的是高侧检测:串在正极线里、电源和负载之间,地线保持完整、大家共用 —— 要是把采样电阻放到地回路(低侧),负载眼中的“零伏”就会被采样压降抬高,所有以地为基准的信号,包括 I2C,都会跟着负载晃动。

同一个数字也解释了唯一一条可能以冒烟收场的接线规则。通道必须串联在电路里 —— 把这路电源剪开,电流从通道的一个孔进、另一个孔出。要是把一对通道孔并联跨在电源两端,你就等于把 0.1 Ω 直接接在电源和回路之间:欧姆定律会向 5 V 电源索要 50 A,最先扛不住的不是电源,就是导线或采样电阻。

卡通安全对比图:剪开的红线正确地穿过 INA3221 的采样通道,打了绿色对勾;另一条没剪开的线同时搭上两个孔,采样电阻烧得发红,打了红色叉
采样电阻要串进线里,绝不能跨在线上。把这路电源剪开、让电流穿过通道;线没剪开就同时搭上两个孔,等于直接短上一个 0.1 Ω。

三个通道完全独立 —— 板子下边缘的每对大孔只连着自己那个采样电阻,孔对在板子背面标着 VIN1+/VIN1− 到 VIN3+/VIN3−(正面只印 CH1–CH3)。它们必须共享的是地:芯片测每路电压都是相对自己的 GND 引脚,所以板子的地要和被测对象的地接在一起。

Parts list

ItemPriceQty
Soldering Service for Circuit Boards & Electronics - 10 Pins Soldering ServiceSoldering Service for Circuit Boards & Electronics - 10 Pins Soldering ServiceSOLSE10RM1.40

INA3221 出厂完全没焊:一条 8 针排针,加上你要用的通道的负载线。加购这项 10 针焊接服务,我们帮你焊好 —— 要接满三个通道的话,请先在 WhatsApp 上和我们确认针数。

动手之前要先焊什么?

INA3221 模块到手是一块光板,附一条散装的 8 针公排针 —— 十七个镀通孔全是空的,所以第一步是焊接。排针焊进顶边那排小孔(方形焊盘是第 1 脚),手法照我们的排针焊接教程来就行。通道孔对和 VPU/GND/GND 那一块是更大的走线级孔:给打算用的通道焊上几段单芯面包板线 —— 单芯线定型好、也吃锡 —— 或者装上 KF301 螺丝端子,改用螺丝压线也可以。

INA3221 和 OLED 怎么接到 ESP32?

INA3221 的 8 针排针从方形的第 1 脚数起依次是 VS、GND、SCL、SDA,然后是 PV、CRI、WAR 和 TC。今天只用前四个 —— 其余是开漏报警输出:CRI 和 WAR 在电流越过你设定的每通道上限时触发,PV 表示所有电源都已就位,TC 用于上电时的电源时序检查;现在先都空着。芯片工作电压 2.7–5.5 V,所以 ESP32 的 3.3 V 直接给它供电:

模块引脚 ESP32 引脚 原因
INA3221 VS 3V3 芯片供电 —— 2.7–5.5 V 范围,和 3.3 V 逻辑电平天生匹配
INA3221 GND GND 总线电压读数和 I2C 总线的共同基准
INA3221 SCL D22 ESP32 Arduino 核心的默认 I2C 时钟
INA3221 SDA D21 ESP32 Arduino 核心的默认 I2C 数据
OLED GND GND 这块模块的排针是 GND 在前:GND VCC SCL SDA
OLED VCC 3V3 SSD1306 用 3.3 V 跑得很好
OLED SCL D22 和 INA3221 的 SCL 同一条线 —— 总线的意义就在这里
OLED SDA D21 和 INA3221 的 SDA 同一条线

每一跳都是模块引脚到模块引脚,所以母对母杜邦线就能全部搞定,连面包板都不用:ESP32 开发板0.96 寸 OLED 出厂就焊好了公排针,INA3221 焊上排针之后同样是公针。留意表里 OLED 的排针 GND 在前 —— 和很多常见模块正好相反。INA3221 接经典的 5 V Arduino 也一样顺:VS 接 5V,SDA 接 A4,SCL 接 A5。

然后轮到被测的电源本身。把想盯的每一路穿过一个通道:电源侧进 VIN+,负载侧从 VIN− 出,每通道最高 26 V —— 只限低压直流,任何接近市电的东西都不要碰。一套很自然的 ESP32 首发三路:通道 1 管板子自己的供电 —— 先用 USB 烧录,然后拔掉线,改由 VIN 引脚供电,5 V 电源的正极线进 VIN1+、从 VIN1− 出来接 VIN,电源的地和 ESP32 的 GND 接在一起 —— 板子吃的每一毫安都会经过采样电阻。通道 2 管 3V3 引脚到传感器那条线,通道 3 管一条电池线,比如我们 TP4056 充电教程里那条。INA3221 的 GND 要和被测项目的地接通;哪个通道读数是负的,只是那两根线接反了而已。

两个 I2C 器件怎么共用同两根线?

OLED 和 INA3221 能同住在 D21/D22 上,因为 I2C 是带地址的总线:每次通信都由主机先喊一个 7 位地址,只有认领这个地址的器件应答,其余保持沉默。这块屏应答 0x3C(模块丝印印的 0x78 是同一个地址再带上读写位);INA3221 出厂应答 0x40 —— A0 引脚接 GND 时选中的地址。板子左边缘的焊盘对可以给 A0 改接,让一条总线最多挂四块板 —— 同时监测十二路电源:

A0 焊盘桥接到 I2C 地址
GND(出厂状态) 0x40
VS 0x41
SDA 0x42
SCL 0x43

凡是多器件的 I2C 项目,动手前先跑一个 I2C 扫描 sketch,确认 0x3C0x40 都在。十秒钟的扫描,能把“屏幕怎么是黑的”变成“总线没问题,去别处找”。

监测 sketch 长什么样?

在 Library Manager 安装 Rob Tillaart 的 INA3221_RTAdafruit SSD1306(IDE 问要不要装依赖时让它装)。这个 sketch 每秒好几次打印三路的伏特、毫安和毫瓦,并在两次刷屏之间持续快速采样通道 1,记住见过的最高电流 —— 就是那行峰值保持,它的用意下一节会讲透。

// ESP32 + INA3221:三路电源的实时电压、电流和功率,显示在 0.96 寸
// OLED 上。两个器件共用一条 I2C 总线:SDA = D21,SCL = D22。
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <INA3221.h>            // Rob Tillaart 的库 "INA3221_RT"

Adafruit_SSD1306 oled(128, 64, &Wire, -1);
INA3221 ina(0x40);              // 出厂地址;A0 焊盘可改成 0x41-0x43

float peak = 0;                 // 开机以来通道 1 见过的最高电流,mA

void setup() {
  Serial.begin(115200);
  Wire.begin();                 // ESP32 默认:SDA 21,SCL 22

  if (!ina.begin()) {
    Serial.println("INA3221 not found at 0x40 - check wiring and address");
    while (true) delay(100);
  }
  ina.setShuntR(0, 0.100);      // 板上那三个 R100 采样电阻
  ina.setShuntR(1, 0.100);
  ina.setShuntR(2, 0.100);

  oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);   // 这块模块应答 0x3C
  oled.setTextColor(SSD1306_WHITE);
}

void loop() {
  // 两次刷屏之间持续快速采样通道 1,记住最高读数 ——
  // WiFi 发射突发就是靠这个抓到的。
  for (int i = 0; i < 40; i++) {
    float mA = ina.getCurrent_mA(0);
    if (mA > peak) peak = mA;
    delay(5);
  }

  oled.clearDisplay();
  oled.setTextSize(1);
  for (uint8_t ch = 0; ch < 3; ch++) {
    oled.setCursor(0, ch * 12);                    // 每路一行
    oled.print("CH");
    oled.print(ch + 1);
    oled.print(" ");
    oled.print(ina.getBusVoltage(ch), 2);          // VIN− 处的电压
    oled.print("V ");
    oled.print(ina.getCurrent_mA(ch), 0);          // 采样压降 / 0.1 Ω
    oled.print("mA ");
    oled.print(ina.getPower_mW(ch), 0);            // 前两者相乘
    oled.print("mW");
  }
  oled.setCursor(0, 44);
  oled.print("CH1 peak: ");
  oled.print(peak, 0);
  oled.print(" mA");
  oled.display();
}

编译出来是 307,644 字节 —— 不到 ESP32 sketch 空间的四分之一。这个库从不凭空造数:它读原始的采样电压寄存器,除以你在 setShuntR() 里告诉它的 0.1 Ω,再乘上总线电压得到功率 —— 所以换一块采样电阻不同的板子,只需要改那一行。

这些数字能告诉你什么 —— 又有什么测不了?

INA3221 的分辨率直接来自它的 ADC 步进。采样寄存器以 40 µV 为一格,40 µV 除以 0.1 Ω 就是 0.4 mA —— 读数能显示的最小电流变化。4095 格叠满就是 ±163.8 mV 满量程,再除以同一个 0.1 Ω 得到上限:每通道约 ±1.6 A。超过满量程后读数只会钳住、不再上升 —— 钉在 1638 mA 附近的读数要当作“爆表”,而不是测量值。

明明万用表就能测电流,还值得做一块实时监测表的理由,是时间。手持表每秒只刷新几次,显示的是平滑后的值 —— 对稳定负载正合适,对 ESP32 正相反:它的 WiFi 发射是毫秒级的突发,一平均就融进背景里了。INA3221 是连续转换的 —— 默认每次转换 1.1 ms,三个通道的采样电压和总线电压大约每 7 ms 扫一轮 —— sketch 的峰值保持把扫到的都留住。监测 sketch 自己从不打开无线电,所以得给它点东西抓 —— 把你项目的 WiFi 代码合并进来,或者干脆加一个光秃秃的 WiFi.begin() 连接,它的发射突发正是这种尖峰。看着峰值那一行远远高出待机读数,我们 ESP32 供电教程里“弱电源会在 WiFi 突发时掉电重启”的提醒,就从一句忠告变成了你桌上的一个数字。

卡通图:一条电流曲线上有又高又窄的尖峰,下方的黄色万用表只显示一条被平均抹平的直线,而蓝色 OLED 模块忠实地重现了这些尖峰
同一根线,两种看法:万用表的显示把毫秒级的 WiFi 突发平均进背景里,连续采样的监测表却把它们抓住并保持。

我们从真实客户身上看到的常见错误

通道被跨接在电源上,而不是串进电源里。这就是前面说的并联短路 —— 0.1 Ω 直接横在电源两端。这路电源必须剪开,让全部电流从 VIN+ 进、VIN− 出。

电压读数正常,电流永远是零。只把 VIN+ 搭上电源而不剪开它,电压照测不误,但负载的电流仍走原来的老路 —— 一点也不经过采样电阻,自然无从读起。

没和被测项目共地。芯片测每路总线电压都是相对自己的 GND 引脚。监测板用一个电源、项目用另一个电源,地又没接通,电压读数就会飘成乱数。

OLED 按习惯当成 VCC 在前来接。这块屏的排针是 GND VCC SCL SDA,地在最前,照别的模块的习惯接线就等于把供电接反。每次上电前都把丝印读一遍。

2 A 的负载“测出” 1.6 A。那是 ±163.8 mV 采样量程在钳位,不是真实电流 —— 这块板的舒适区,正是大多数 ESP32 项目所在的 1.6 A 以下世界。

常见问题

INA3221 能测超过 1.6 A 吗?

用这块板上的 0.1 Ω 采样电阻不行:芯片 ±163.8 mV 的采样输入除以 0.1 Ω,每通道上限约 ±1.638 A,到顶后读数就钳住了。芯片本身只看得见毫伏,所以用更小采样电阻的板子拿分辨率换量程 —— 0.4 mA 的步进也按同比例变大。

INA3221 和 INA219 有什么区别?

INA219 是同一个思路 —— 高侧 I2C 采样监测 —— 但一颗芯片只有一个通道。INA3221 在一个地址后面给你三个通道,外加每通道可编程的警告和临界报警 —— 要盯住整个项目的供电树,它更合适。

INA3221 能配 ESP32 这类 3.3 V 开发板用吗?

能。芯片的供电范围是 2.7–5.5 V,直接吃 ESP32 的 3V3 引脚,I2C 线也工作在安全的 3.3 V 电平。26 V 那个数字是被测电源的上限,不是芯片自己供电的上限。

为什么我的电流读数是负的?

电流从 VIN+ 流向 VIN− 记为正,所以负号只说明那个通道的两根线接反了 —— 什么也没坏。把两根线对调,或者留着这个符号看电流双向流动,比如一条又充又放的电池线。

这个项目需要用到报警引脚(PV、CRI、WAR、TC)吗?

不需要 —— sketch 通过 I2C 轮询读数,从不碰它们。它们是为不写软件的硬件反应准备的:每个通道都能在电流越过设定上限的瞬间把 CRI 或 WAR 拉低。这些引脚是开漏的;VPU 孔只给电源就位(PV)输出提供偏置,管不到其他报警脚。

卡通桌面搭建图:黑色 ESP32 开发板用彩色杜邦线连着黑色 INA3221 监测板和蓝色 OLED 模块,一根红线绕进其中一个测量通道
完工的监测表:母对母杜邦线把共享的 I2C 总线从 ESP32 引到两块模块,被测的那路电源绕过通道 1 焊好的引线。

当每一路的真实电流都变成看得见的数字,供电问题就不再靠猜。采样电阻串进线里、地接在一起,下次哪里掉电重启,你会知道是哪一路干的 —— 还差多少毫安。

最后更新:2026年8月。有问题?WhatsApp 联系我们

Leave a Reply

Your email address will not be published. Required fields are marked *