这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【功率监测与控制系统DIY活动过程贴】功率计与LabVIEW数据采集

共1条 1/1 1 跳转至

【功率监测与控制系统DIY活动过程贴】功率计与LabVIEW数据采集

助工
2025-05-14 00:44:46     打赏

【功率监测与控制系统DIY活动过程贴】功率计与LabVIEW数据采集

本文介绍了 NUCLEO-F411RE 开发板通过硬件 I2C 实现 INA219 功率传感器的驱动与 OLED 显示的功率计,并进一步结合 LabVIEW 上位机,通过串口中断采集功率数据的项目设计。

项目介绍

一、介绍 LabVIEW 软件及其关键组件、工具、模块、VISA 串口程序包等;

二、使用 STM32CubeMX 新建工程,并添加驱动工程代码、串口中断查询代码;

三、创建 LabVIEW 上位机,通过串口发送指令,获取 INA219 传感器数据功率信息;

四、运行 LabVIEW 上位机程序, OLED 实时显示电压、电流和功率信息,同时 LabVIEW 前面板显示功率演化曲线、数据保存,实现功率演化数据的采集。

LabVIEW

LabVIEW (Laboratory Virtual Instrument Engineering Workbench)是 National Instruments(NI)公司开发的一种图形化编程语言。主要用于数据采集、仪器控制、工业自动化以及测试测量系统的开发。

2023年,NI 被艾默生电气(Emerson)收购。

关键组件

1.前面板(Front Panel) 用户交互界面,包含按钮、图表、指示灯等控件。

2.程序框图(Block Diagram) 图形化编程区域,通过连线连接函数、结构和子VI。

3. VI(Virtual Instrument) LabVIEW程序的基本单元,每个VI包含前面板和程序框图,可嵌套使用。

4. 工具包与模块

DAQmx:数据采集驱动;

Vision Development Module:机器视觉处理;

LabVIEW NXG:新一代Web化设计工具。

详见:艾默生旗下测试和测量系统 - NI .


硬件连接

PB9 ---- SDA (INA219)

PB10 ---- SCL (INA219)

PB7 ---- SDA (OLED)

PB6 ---- SCL (OLED)

GND (INA219) ---- Negative (Motor) ---- Negative (Power Supply)

IN+ (INA219) ---- Positive (Power Supply)

IN- (INA219) ---- Positive (Motor)


示意图

oled_motor_ina219_power_uart.jpg


实物连接

uart_ina219_empty.jpg


工程创建

实现 INA219 和 OLED 的硬件 IIC 驱动、串口中断查询信息。

这里使用 STM32CubeMX 快速创建工程。

1.打开 STM32CubeMX 软件,新建 ST 板卡工程;

2.时钟配置:采用默认设置,系统时钟频率 84MHz;

3. Pinout & Configuration 标签下选择 Connectivity - 使能 I2C1 和 I2C2 以及 USART2 ;

4. 勾选使能串口中断,以实现串口发送指令查询数据;

labview_ina219_uart.jpg


5.配置完成后,进入 Project Manager 标签栏,进行项目命名、保存路径设置、编译器选择等操作;

6.点击 Generate Code 按钮,使用 STM32CubeIDE 或 Keil 打开目标工程;

7.编译工程,0 error, 0 warning .


工程代码

结合前面关于 OLED 屏幕以及 INA219 传感器的硬件 IIC 驱动方案,添加 oled.h 、 oled.c 、 oledfont.h 、ina219.h、ina219.c 文件至指定路径。

添加代码实现 printf 重定向、串口输出浮点型数据

    1.进入项目资源管理器,右键项目,选择属性;

    2.在弹出的对话框中,选择 C/C++ Build ,展开 C/C++ Build 并选择 Settings ;

    3.选择 Tool Settings - MCU Settings ;

    4.勾选 Use float with printf from newlib-nano (-u printf float) ;

    5.点击 Apply 应用自动重新构建项目,点击 Apply and Close 保存配置。

    6.右键项目 - 属性 - C/C++ Build - Setting - Tool Settings - MCU GCC Linker - Miscellaneous - Other flags - 点击添加符号,输入 -u_printf_float ,应用并关闭。

详见:【功率监测与控制系统DIY活动过程贴】OLED显示【功率监测与控制系统DIY活动过程贴】INA219功率信息检测与实时显示 .

流程图

flowchart_labview.jpg

main.c 关键代码如下

/* 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"
#include "string.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* -------- Private variables ------*/
#define CMD_LENGTH 3
uint8_t uart_rx_buffer[CMD_LENGTH];  // 接收指令缓冲区
uint8_t uart_rx_index = 0;          // 接收索引
uint8_t command_received = 0;       // 指令接收完成标志
/* USER CODE END PTD */

/* 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 */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
void process_command(void);
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
// 串口接收回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART2) {
        uart_rx_index++;
        if(uart_rx_index >= CMD_LENGTH) {
            uart_rx_index = 0;
            command_received = 1;  // 设置指令接收完成标志
        }
        // 重新启动接收
        HAL_UART_Receive_IT(&huart2, &uart_rx_buffer[uart_rx_index], 1);
    }
}

// 处理接收到的指令
void process_command(void)
{
    // 检查指令前缀是否为0x55 0xAA
    if(uart_rx_buffer[0] == 0x55 && uart_rx_buffer[1] == 0xAA)
    {
        switch(uart_rx_buffer[2])
        {
            case 0x10:  // 读取电压
            {
                float busVoltage = INA219_GetBusVoltage_V();
                printf("%.2f\r\n",busVoltage);
                break;
            }

            case 0x11:  // 读取电流
            {
                float current = INA219_GetCurrent_mA();
                printf("%.2f\r\n",current);
                break;
            }

            case 0xFF:  // 读取功率
            {
                float power = INA219_GetPower_mW();
                printf("%.2f\r\n",power);
                break;
            }

            default:
                // 无效指令,可以发送错误码
                uint8_t error_code = 0xEE;
                HAL_UART_Transmit_IT(&huart2, &error_code, 1);
                break;
        }
    }
    command_received = 0;  // 清除标志
}

void data_display()
{
     float busVoltage = INA219_GetBusVoltage_V();
  //float shuntVoltage = INA219_GetShuntVoltage_mV();
  float current = INA219_GetCurrent_mA();
  float power = INA219_GetPower_mW();
  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);
}
/* USER CODE END 0 */

int main(void)
{
  HAL_Init();

  /* USER CODE BEGIN Init */
  INA219_Init(&hi2c2);
  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_I2C2_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
  // 启动串口接收中断
  HAL_UART_Receive_IT(&huart2, &uart_rx_buffer[0], 1);
  // OLED display frame
      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 BEGIN 3 */
   if(command_received)
   {
    process_command();
    data_display();
   }
   HAL_Delay(0);
  }
  /* USER CODE END 3 */
}

★ 注意用户自定义代码需写入 /* USER CODE BEGIN x */ 和 /* USER CODE END x */ 之间,确保CubeMX再次生成工程,代码不会被覆盖。

保存代码,编译工程,运行程序,则固件上传至 NUCLEO-F411RE 开发板,程序运行。

LabVIEW 上位机

介绍了 LabVIEW 上位机向开发板发送串口指令,获取 INA219 传感器电压和电流数据,并绘制功率数值演化曲线。

前面板

功能实现:

1.配置串口

2.运行程序

3.点击 Start 开始采集数据

4.点击 Stop 停止采集

5.点击 Terminate 终止程序。

labview_ina219_uart_motor_panel.jpg

程序框图

Page 1

labview_ina219_uart_motor_block1.jpg

Page 2

labview_ina219_uart_motor_block2.jpg

效果

打开串口调试助手,以十六进制发送 55 AA 10 获得电压信息,发送 55 AA 11 获得电流信息,发送 55 AA FF 获得功率信息。

LabVIEW 上位机演示

演示了开启电机瞬间的电压、电流以及功率的变化情况。

INA219_power_labview_uart.gif

分析

可以看出,直接采集 INA219 传感器获取的数据存在较大的抖动,可采取 滤波算法 (软件滤波、低通滤波、滑动平均等)进行参数优化,使输出功率更为稳定、更符合实际情况。


总结

本文介绍了 NUCLEO-F411RE 开发板通过硬件 I2C 实现 INA219 功率传感器的驱动与 OLED 显示,并进一步结合 LabVIEW 上位机,通过串口中断采集功率数据的项目设计,为相关产品及项目的开发设计提供了参考。





关键词: 功率     监测     LabVIEW     数据采集     INA219    

共1条 1/1 1 跳转至

回复

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