这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【Let'sdo第1期-DIY功率检测与控制系统】3、过程贴:219功率信息检测

共1条 1/1 1 跳转至

【Let'sdo第1期-DIY功率检测与控制系统】3、过程贴:219功率信息检测

工程师
2025-05-21 13:36:36     打赏

《Let'sdo第1期-DIY功率检测与控制系统》

目标:基础任务:INA219功率信息检测(不带负载)

Gravity I2C数字功率计

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

接口说明

SEN0291_overview.png

标号名称功能描述
1VCC电源正极(3.3~5.5V)
2GND电源负极
3SCLI2C时钟线
4SDAI2C数据线
5ADDRI2C地址选择拨码开关
63P TERMINAL电压与电流测量接线柱3P

连线图

SEN0291_connection_Arduino(CH).png

1、I2C3配置

image.png

    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**I2C3 GPIO Configuration
    PC9     ------> I2C3_SDA
    PA8     ------> I2C3_SCL
    */
    GPIO_InitStruct.Pin = GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF4_I2C3;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_8;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF4_I2C3;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* Peripheral clock enable */
    __HAL_RCC_I2C3_CLK_ENABLE();

image.png

static void MX_I2C3_Init(void)
{

  /* USER CODE BEGIN I2C3_Init 0 */

  /* USER CODE END I2C3_Init 0 */

  /* USER CODE BEGIN I2C3_Init 1 */

  /* USER CODE END I2C3_Init 1 */
  hi2c3.Instance = I2C3;
  hi2c3.Init.ClockSpeed = 100000;
  hi2c3.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c3.Init.OwnAddress1 = 0;
  hi2c3.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c3.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c3.Init.OwnAddress2 = 0;
  hi2c3.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c3.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c3) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2C3_Init 2 */

  /* USER CODE END I2C3_Init 2 */

}


2、INA219驱动

2个拨码开关头调到0,设置地址为:0x40

image.png

#define INA219_ADDRESS (0x40 << 1) // 默认地址,左移1位因为STM32 HAL库需要

// INA219寄存器地址
#define INA219_REG_CONFIG      0x00
#define INA219_REG_SHUNTVOLT   0x01
#define INA219_REG_BUSVOLT     0x02
#define INA219_REG_POWER       0x03
#define INA219_REG_CURRENT     0x04
#define INA219_REG_CALIB       0x05


void INA219_Config(I2C_HandleTypeDef *hi2c)
{
    uint8_t config[3];
	
		hi2c_ina219=hi2c;
    
    // 配置值 (32V, 1A量程,12位分辨率)
    uint16_t configValue = 0x3c1f;	//
    
    config[0] = INA219_REG_CONFIG;
    config[1] = (configValue >> 8);   // 高字节
    config[2] = configValue & 0xFF;    // 低字节
    
    HAL_I2C_Master_Transmit(hi2c_ina219, INA219_ADDRESS, config, 3, HAL_MAX_DELAY);
    
    // 校准值计算 (根据具体应用调整)
    uint16_t calValue = 4096; // 示例值,需要根据实际需求计算
    config[0] = INA219_REG_CALIB;
    config[1] = (calValue >> 8);
    config[2] = calValue & 0xFF;
    
    HAL_I2C_Master_Transmit(hi2c_ina219, INA219_ADDRESS, config, 3, HAL_MAX_DELAY);
}


3、读取电压值

float INA219_ReadBusVoltage(void)
{
    uint8_t reg = INA219_REG_BUSVOLT;
    uint8_t data[2];
    uint16_t voltageRaw;
    float voltage;
    
    // 写入要读取的寄存器地址
    HAL_I2C_Master_Transmit(hi2c_ina219, INA219_ADDRESS, &reg, 1, HAL_MAX_DELAY);
    
    // 读取2字节数据
    HAL_I2C_Master_Receive(hi2c_ina219, INA219_ADDRESS, data, 2, HAL_MAX_DELAY);
    
    voltageRaw = (data[0] << 8) | data[1];
    voltageRaw = (voltageRaw >> 3) * 4; // 转换为mV
    voltage = voltageRaw * 0.001f;      // 转换为V
    
    return voltage;
}

4、读物电流值

float INA219_ReadCurrent(void)
{
    uint8_t reg = INA219_REG_CURRENT;
    uint8_t data[2];
    int16_t currentRaw;
    float current;
    
    HAL_I2C_Master_Transmit(hi2c_ina219, INA219_ADDRESS, &reg, 1, HAL_MAX_DELAY);
    HAL_I2C_Master_Receive(hi2c_ina219, INA219_ADDRESS, data, 2, HAL_MAX_DELAY);
    
    currentRaw = (data[0] << 8) | data[1];
    current = currentRaw * 0.001f; // 1mA/LSB (取决于校准值)
    
    return current;
}


5、运行效果

	OLED_Clear();
	OLED_ShowChineseString16(0,0,(uint8_t*)"DIY功率监测与控制",1);
	OLED_Refresh();
	

		
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
     float busVoltage = INA219_ReadBusVoltage();
     float shuntVoltage = INA219_ReadShuntVoltage();
     float current = INA219_ReadCurrent();
     float power = busVoltage * current;
        
     
     printf("Bus Voltage: %.2f V\n", busVoltage);
     printf("Shunt Voltage: %.2f mV\n", shuntVoltage * 1000);
     printf("Current: %.2f mA\n", current * 1000);
     printf("Power: %.2f mW\n", power * 1000);
			
		 
     sprintf(buff,"电流:  %6.3fmA ",current*1000);
     OLED_ShowChineseString16(0,16,(uint8_t*)buff,1);
     sprintf(buff,"电压:  %6.3fV ",busVoltage);
     OLED_ShowChineseString16(0,32,(uint8_t*)buff,1);
     sprintf(buff,"功率:  %6.3fmW  ",power*1000);
     OLED_ShowChineseString16(0,48,(uint8_t*)buff,1);
	
     //第一排title循环显示效果		
     OLED_ShiftTwoRowsLeft(0, 3);
     HAL_Delay(250);
     OLED_ShiftTwoRowsLeft(0, 3);
     HAL_Delay(250);
     OLED_ShiftTwoRowsLeft(0, 3);
     HAL_Delay(250);
     OLED_ShiftTwoRowsLeft(0, 3);
     HAL_Delay(250);
		 
     OLED_Refresh();
     HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);


     }

第一排title循环显示效果:

/**
  * @brief  指定2行(16像素高)内容循环左移
  * @param  start_page: 起始页(0-6),每页8行,2页=16行
  * @param  shift_pixels: 左移的像素数(1-7)
  */
void OLED_ShiftTwoRowsLeft(uint8_t start_page, uint8_t shift_pixels) {
  if(start_page > 6) return; // 最大从第6页开始(6+1=7<8)
	uint8_t i,n;
	uint8_t temp[144][2];
	
	for (i=0;i<shift_pixels;i++)
	{
		temp[i][0]=OLED_GRAM[i][start_page];
		temp[i][1]=OLED_GRAM[i][start_page+1];
	}
	for(i=shift_pixels;i<144;i++)   //实现左移
		{
			for(n=start_page;n<start_page+2;n++)
			{
				OLED_GRAM[i-shift_pixels][n]=OLED_GRAM[i][n];
			}
		}
	for(i=0;i<shift_pixels;i++)
	{
		OLED_GRAM[144-(shift_pixels-i)][start_page]=temp[i][0];
		OLED_GRAM[144-(shift_pixels-i)][start_page+1]=temp[i][1];
	}
}


image.png

tutieshi_480x270_9s.gif






关键词: Let'sdo第1期-DIY功率检测与控制系统    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]