【功率监测与控制系统DIY活动过程贴】功率信息检测与实时显示
本文介绍了 NUCLEO-F411RE 开发板通过硬件 I2C 实现 INA219 功率传感器的驱动与串口信息打印 ,并进一步结合 IIC 驱动 OLED 的项目设计,实现功率数据采集与实时显示。
项目介绍
一、介绍 INA219 功率传感器模块;
二、使用 STM32CubeMX 新建工程,并添加驱动工程代码;
三、获取 INA219 传感器数据,并通过串口发送功率信息;
四、进一步结合 OLED 实现电压、电流和功率信息的实时显示。
SEN0291 模块
DFRobot Gravity:I2C数字功率计 是一款可测量 26V, 8A 以内各类电子模块、用电设备的电压、电流和功率,最大相对误差不超过±0.2%的高分辨、高精度、大量程测量模块(首次使用需进行手动校准)。
可用于太阳能系统、电池库仑计、电机、主控板或电子模块的功耗测量、电池续航评估与实时电源参数在线监控。
模块采用 TI INA219 零温漂电流/功率监控芯片和 2W 大功率低温漂 10mΩ 合金采样电阻,
电压和电流分辨率分别可达 4mV 与 1mA,
在满量程测量条件下,电压与电流的最大测量相对误差不超过±0.2%,
并提供4个可通过拨码开关配置的I2C地址。
模块可对双向高侧电流(流经电源或电池正极的电流)进行准确测量,这在太阳能或库仑计应用,电池既需要充电,也需要放电的场合尤为有用,
用户可通过电流的正负读数了解电池的充放电状态,也可以了解电池的冲放电的实时电压、电流与功率。
在电机应用场景,可通过实时监控电机电流是否由于堵转或负载过大导致电流过大,从而及时采取保护措施。
此外,也可以使用该模块测量各类电子模块或整个项目的实时功耗,从而评估电池的续航时间。
特性
高精度、高分辨率、大量程、低温漂
双向电流高侧测量
兼容3.3V/5V控制器
精致小巧,方便项目嵌入
应用场景
太阳能系统
电池库仑计
电子模块功耗评估
技术规格
供电电压(VCC):3.3V ~ 5.5V
电压量程(IN+或IN-相对GND):0 ~ 26V
电压分辨率:4 mV
电压相对误差:<±0.2%(典型值)
电流量程:0 ~ ±8A(可测双向电流)
电流分辨率:1 mA
电流相对误差:<±0.2%(典型值,需手动校准)
功率量程:0 ~ 206 W
功率分辨率:20 mW(硬件)/4mW(软件)
静态电流:0.7 mA
通信接口:Gravity I2C (逻辑电平0-3.3V)
I2C地址:4个,0x40,0x41,0x44,0x45(默认)
尺寸:30.0mm×22.0mm
重量:4g
接口说明
名称 | 功能描述 |
VCC | 电源正极(3.3~5.5V) |
GND | 电源负极 |
SCL | I2C时钟线 |
SDA | I2C数据线 |
ADDR | I2C地址选择拨码开关 |
3P TERMINAL | 电压与电流测量接线柱3P |
模块原理图
INA219 原理图
总线时序图
IIC 通信起始地址为 0x40
详见:Gravity: I2C Digital Wattmeter SKU: SEN0291-DFRobot .
12V直流电源
MEAN WELL 的 RS-15 系列单路输出开关电源是高度可靠的紧凑型 15 W AC/DC 电源。MEAN WELL 公司的电源为低功耗工业应用提供了可靠的解决方案。
其主要特点包括:较高的工作温度(高达 +70°C)、空载功耗小于 0.5 W、高效率、高可靠性以及承受 5G 振动测试和 300 VAC 浪涌输入电压的能力。
特性
通用交流输入/全范围
短路、过压和超温保护
自由空气对流冷却
电源开启 LED 指示灯
通过了 100% 满负载老化测试
空载功耗小于 0.5 W
全部使用 +105°C 长寿命电解电容器
承受 300 VAC 5 秒浪涌输入
工作温度高达 +70 °C
通过 5G 振动测试
高效率、长寿命和高可靠性
接口说明
名称 | 功能描述 |
L | 火线(交流市电) |
N | 零线(交流市电) |
GND | 地线 |
-V | 输出直流电压负极 |
+V | 输出直流电压正极 |
ADJ | 微调旋钮,调整输出直流电压 |
使用时需将前盖取下,旋转螺丝压紧导线,避免接触不良或短路,安装完成后将前盖合上,避免触电;
注意接线安全。
工程创建
实现 INA219 的硬件 IIC 驱动和串口打印信息。
1.打开 STM32CubeMX 软件,新建 ST 板卡工程;
2.时钟配置:采用默认设置,系统时钟频率 84MHz;
3. Pinout & Configuration 标签下选择 Connectivity - I2C2 , 右侧 Mode 选择 I2C 使能 IIC 总线功能,此时 Pinout View 中 IIC 对应的管脚被标注为 I2C2 ;
4.配置完成后,进入 Project Manager 标签栏,进行项目命名、保存路径设置、编译器选择等操作;
5.点击 Generate Code 按钮,使用 STM32CubeIDE 或 Keil 打开目标工程;
6.编译工程,0 error, 0 warning .
工程代码
介绍了 INA219 传感器的头文件 ina219.h 和驱动文件 ina219.c 的相关代码。
ina219.h
#ifndef __INA219_H #define __INA219_H #include "stm32f4xx_hal.h" #define INA219_ADDRESS (0x40 << 1) // 默认地址,左移1位 // 寄存器地址 #define INA219_REG_CONFIG 0x00 #define INA219_REG_SHUNTVOLTAGE 0x01 #define INA219_REG_BUSVOLTAGE 0x02 #define INA219_REG_POWER 0x03 #define INA219_REG_CURRENT 0x04 #define INA219_REG_CALIBRATION 0x05 // 配置选项 #define INA219_CONFIG_RESET 0x8000 #define INA219_CONFIG_BVOLTAGERANGE_32V 0x2000 #define INA219_CONFIG_GAIN_8_320MV 0x1800 #define INA219_CONFIG_BADCRES_12BIT 0x0180 #define INA219_CONFIG_SADCRES_12BIT_1S_532US 0x0018 #define INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS 0x0007 // 函数声明 void INA219_Init(I2C_HandleTypeDef *hi2c); float INA219_GetShuntVoltage_mV(void); float INA219_GetBusVoltage_V(void); float INA219_GetCurrent_mA(void); float INA219_GetPower_mW(void); uint16_t INA219_ReadReg(uint8_t reg); void INA219_WriteReg(uint8_t reg, uint16_t value); extern I2C_HandleTypeDef *hina219_i2c; #endif
ina219.c
#include "ina219.h" #include <math.h> I2C_HandleTypeDef *hina219_i2c; float currentLSB = 0.0f; float powerLSB = 0.0f; void INA219_Init(I2C_HandleTypeDef *hi2c) { hina219_i2c = hi2c; // 计算LSB // 假设使用0.1欧姆分流电阻,最大预期电流为3.2A float maxExpectedCurrent = 3.2f; currentLSB = maxExpectedCurrent / 32768.0f; powerLSB = 20.0f * currentLSB; // 写入校准寄存器 uint16_t calibrationValue = (uint16_t)(0.04096f / (currentLSB * 0.1f)); INA219_WriteReg(INA219_REG_CALIBRATION, calibrationValue); // 配置寄存器 uint16_t config = INA219_CONFIG_BVOLTAGERANGE_32V | INA219_CONFIG_GAIN_8_320MV | INA219_CONFIG_BADCRES_12BIT | INA219_CONFIG_SADCRES_12BIT_1S_532US | INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS; INA219_WriteReg(INA219_REG_CONFIG, config); } uint16_t INA219_ReadReg(uint8_t reg) { uint8_t data[2]; HAL_I2C_Mem_Read(hina219_i2c, INA219_ADDRESS, reg, 1, data, 2, HAL_MAX_DELAY); return (data[0] << 8) | data[1]; } void INA219_WriteReg(uint8_t reg, uint16_t value) { uint8_t data[2] = {value >> 8, value & 0xFF}; HAL_I2C_Mem_Write(hina219_i2c, INA219_ADDRESS, reg, 1, data, 2, HAL_MAX_DELAY); } float INA219_GetShuntVoltage_mV(void) { int16_t value = (int16_t)INA219_ReadReg(INA219_REG_SHUNTVOLTAGE); return value * 0.01f; // LSB = 10uV } float INA219_GetBusVoltage_V(void) { uint16_t value = INA219_ReadReg(INA219_REG_BUSVOLTAGE); return (value >> 3) * 0.004f; // LSB = 4mV } float INA219_GetCurrent_mA(void) { int16_t value = (int16_t)INA219_ReadReg(INA219_REG_CURRENT); return value * currentLSB * 1000.0f; } float INA219_GetPower_mW(void) { int16_t value = (int16_t)INA219_ReadReg(INA219_REG_POWER); return value * powerLSB * 1000.0f; }
头文件和驱动文件是实现 INA219 功率参数读取的关键,对于后续参数调用和输出具有重要意义。
串口打印功率
介绍了通过串口重定向实现电压、电流、功率等信息的打印输出。
printf 重定向
/* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "stdio.h" // printf used /* USER CODE END Includes */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ #ifdef __GNUC__ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif PUTCHAR_PROTOTYPE { HAL_UART_Transmit(&huart2, (uint8_t*)&ch,1,HAL_MAX_DELAY); return ch; } /* USER CODE END PD */
串口输出浮点型数据
进入项目资源管理器,右键项目,选择属性;
在弹出的对话框中,选择 C/C++ Build ,展开 C/C++ Build 并选择 Settings ;
选择 Tool Settings - MCU Settings ;
勾选 Use float with printf from newlib-nano (-u printf float) ;
点击 Apply 应用自动重新构建项目,点击 Apply and Close 保存配置。
右键项目 - 属性 - C/C++ Build - Setting - Tool Settings - MCU GCC Linker - Miscellaneous - Other flags - 点击添加符号,输入 -u_printf_float ,应用并关闭。
参考:STM32CubeIDE之printf重定向及串口输出浮点型数据 . 解决STM32CubeIDE出现 The float formatting support is not enabled 错误提示 .
main.c
主函数添加 ina219 初始化、调用电压、电流读取函数,以及串口重定向输出
/* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "i2c.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "ina219.h" #include "stdio.h" // printf used /* USER CODE END Includes */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ #ifdef __GNUC__ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif PUTCHAR_PROTOTYPE { //同样USART2改为你的串口 HAL_UART_Transmit(&huart2, (uint8_t*)&ch,1,HAL_MAX_DELAY); return ch; } void SystemClock_Config(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_I2C2_Init(); MX_USART2_UART_Init(); /* USER CODE BEGIN 2 */ INA219_Init(&hi2c2); char buffer[100]; /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ float busVoltage = INA219_GetBusVoltage_V(); float shuntVoltage = INA219_GetShuntVoltage_mV(); float current = INA219_GetCurrent_mA(); float power = INA219_GetPower_mW(); printf("Voltage: %.2f (%.2f) V, Current: %.2f mA, Power: %.2f mW\r\n",busVoltage,shuntVoltage,current,power); HAL_Delay(500); }
编译并运行工程,使用 串口调试助手 软件打开 STLINK 虚拟串口,即可获得功率信息。
硬件连接
PB9 ---- SDA (INA219)
PB10 ---- SCL (INA219)
GND (INA219) ---- Negative (Motor) ---- Negative (Power Supply)
IN+ (INA219) ---- Positive (Power Supply)
IN- (INA219) ---- Positive (Motor)
示意图
实物连接
效果
空载情况下的电压、电流和功率输出
打开电源情况下的功率输出情况
OLED显示功率
在实现串口输出的基础上,结合前面帖子构建的 OLED 功率显示框架,实现 INA219 功率读取、串口打印以及 OLED 显示。
硬件连接
PB9 ---- SDA (INA219)
PB10 ---- SCL (INA219)
GND (INA219) ---- Negative (Motor) ---- Negative (Power Supply)
IN+ (INA219) ---- Positive (Power Supply)
IN- (INA219) ---- Positive (Motor)
PB7 ---- SDA (OLED)
PB6 ---- SCL (OLED)
示意图
代码
/* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "i2c.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "ina219.h" #include "stdio.h" #include "oled.h" /* USER CODE END Includes */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ #ifdef __GNUC__ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif PUTCHAR_PROTOTYPE { HAL_UART_Transmit(&huart2, (uint8_t*)&ch,1,HAL_MAX_DELAY); return ch; } void SystemClock_Config(void); int main(void) { HAL_Init(); INA219_Init(&hi2c2); SystemClock_Config(); MX_GPIO_Init(); MX_I2C1_Init(); MX_I2C2_Init(); MX_USART2_UART_Init(); /* USER CODE BEGIN 2 */ OLED_Init(); OLED_Clear(); /* --- 1st row --- */ OLED_ShowString(0,0,"DIY",16,1); // DIY OLED_ShowCHinese(24,0,0,1); // 功 OLED_ShowCHinese(39,0,1,1); // 率 OLED_ShowCHinese(54,0,2,1); // 监 OLED_ShowCHinese(69,0,3,1); // 测 OLED_ShowCHinese(84,0,4,1); // 与 OLED_ShowCHinese(99,0,5,1); // 控 OLED_ShowCHinese(113,0,6,1); // 制 /* --- 2nd row --- */ OLED_ShowCHinese(0,2,7,0); // 电 OLED_ShowCHinese(15,2,9,0); // 流 OLED_ShowChar(30,2,':',16,0); OLED_ShowString(100,2,"mA",16,0); /* --- 3rd row --- */ OLED_ShowCHinese(0,4,7,0); // 电 OLED_ShowCHinese(15,4,8,0); // 压 OLED_ShowChar(30,4,':',16,0); OLED_ShowString(100,4,"V",16,0); /* --- 4th row --- */ OLED_ShowCHinese(0,6,0,0); // 功 OLED_ShowCHinese(15,6,1,0); // 率 OLED_ShowChar(30,6,':',16,0); OLED_ShowString(100,6,"mW",16,0); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ float busVoltage = INA219_GetBusVoltage_V(); float shuntVoltage = INA219_GetShuntVoltage_mV(); float current = INA219_GetCurrent_mA(); float power = INA219_GetPower_mW(); printf("Voltage: %.2f (%.2f) V, Current: %.2f mA, Power: %.2f mW\r\n",busVoltage,shuntVoltage,current,power); OLED_ClearLinePart(2, 45, 99); OLED_ClearLinePart(3, 45, 99); OLED_ShowDecimal(45,2,current,2,2,16,0); OLED_ClearLinePart(4, 45, 99); OLED_ClearLinePart(5, 45, 99); OLED_ShowDecimal(45,4,busVoltage,2,2,16,0); OLED_ClearLinePart(6, 45, 99); OLED_ClearLinePart(7, 45, 99); OLED_ShowDecimal(45,6,power,2,2,16,0); HAL_Delay(500); } /* USER CODE END 3 */ }
效果
电机静止
电机运行
动态
同时串口打印
12V电源
使用12V直流电源带动负载运行,通过INA219检测功率信息。
硬件连接
PB9 ---- SDA (INA219)
PB10 ---- SCL (INA219)
PB7 ---- SDA (OLED)
PB6 ---- SCL (OLED)
GND (INA219) ---- Negative (12V) ---- Negative (LOAD)
IN+ (INA219) ---- Positive (12V)
IN- (INA219) ---- Positive (LOAD)
示意图
实物连接
动态展示
串口打印功率
总结
本文介绍了 NUCLEO-F411RE 开发板通过硬件 I2C 实现 INA219 功率传感器的驱动与串口信息打印 ,并进一步结合硬件 IIC 驱动 OLED 的项目设计,实现功率数据采集与实时显示,工程使用 SMT32CubeMX 软件快速构建,为相关产品及项目的开发设计提供了参考。