132浏览
查看: 132|回复: 0

[讨论] Beetle 树莓派RP2350 - 便携INA219功率计

[复制链接]
本帖最后由 无垠的广袤 于 2025-5-12 04:33 编辑

Beetle 树莓派RP2350 - 便携INA219功率计
本文介绍了 DFRobot Beetle RP2350 开发板结合 INA219 模块实现功率计,并通过 LabVIEW 上位机串口采集 INA219 电流、电压数据的项目设计。

项目介绍
本项目包括 INA219(关键部件)芯片介绍、工作原理、参数特点等信息,在此基础上实现工程代码编写、硬件测试等流程,最终实现功率计制作。结合LabVIEW上位机,实现功率数据采集和曲线分析等。

INA219 模块
DFRobot Gravity:I2C数字功率计 是一款可测量 26V, 8A 以内各类电子模块、用电设备的电压、电流和功率,最大相对误差不超过±0.2%的高分辨、高精度、大量程测量模块(首次使用需进行手动校准)。
可用于太阳能系统、电池库仑计、电机、主控板或电子模块的功耗测量、电池续航评估与实时电源参数在线监控。

Beetle 树莓派RP2350 - 便携INA219功率计图15

模块采用 TI INA219 零温漂电流/功率监控芯片和 2W 大功率低温漂 10mΩ 合金采样电阻,
电压和电流分辨率分别可达 4mV 与 1mA,
在满量程测量条件下,电压与电流的最大测量相对误差不超过±0.2%,
并提供4个可通过拨码开关配置的I2C地址。
模块可对双向高侧电流(流经电源或电池正极的电流)进行准确测量,这在太阳能或库仑计应用,电池既需要充电,也需要放电的场合尤为有用,
用户可通过电流的正负读数了解电池的充放电状态,也可以了解电池的冲放电的实时电压、电流与功率。
在电机应用场景,可通过实时监控电机电流是否由于堵转或负载过大导致电流过大,从而及时采取保护措施。
此外,也可以使用该模块测量各类电子模块或整个项目的实时功耗,从而评估电池的续航时间。


特性
  • 高精度、高分辨率、大量程、低温漂
  • 双向电流高侧测量
  • 兼容3.3V/5V控制器
  • 精致小巧,方便项目嵌入

接口说明
Beetle 树莓派RP2350 - 便携INA219功率计图14


[td]
名称
功能描述
VCC
电源正极(3.3~5.5V)
GND
电源负极
SCL
I2C时钟线
SDA
I2C数据线
ADDR
I2C地址选择拨码开关
3P TERMINAL
电压与电流测量接线柱3P

模块原理图

Beetle 树莓派RP2350 - 便携INA219功率计图13


INA 原理图

Beetle 树莓派RP2350 - 便携INA219功率计图12


总线时序图
IIC 通信起始地址为 0x40

Beetle 树莓派RP2350 - 便携INA219功率计图11


工程代码

通过复用 IIC 引脚 GPIO4 和 GPIO5 ,实现 INA219 模块的数据采集、终端打印以及 OLED 显示。
上传 ina219.py 至芯片根目录

  1. # The MIT License (MIT)
  2. #
  3. # Copyright (c) 2017 Dean Miller for Adafruit Industries
  4. #
  5. # Permission is hereby granted, free of charge, to any person obtaining a copy
  6. # of this software and associated documentation files (the "Software"), to deal
  7. # in the Software without restriction, including without limitation the rights
  8. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. # copies of the Software, and to permit persons to whom the Software is
  10. # furnished to do so, subject to the following conditions:
  11. #
  12. # The above copyright notice and this permission notice shall be included in
  13. # all copies or substantial portions of the Software.
  14. #
  15. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. # THE SOFTWARE.
  22. """
  23. `adafruit_ina219`
  24. ====================================================
  25. CircuitPython/MicroPython driver for the INA219 current sensor.
  26. * Author(s): Dean Miller
  27. """
  28. from micropython import const
  29. # from adafruit_bus_device.i2c_device import I2CDevice
  30. __version__ = "0.0.0-auto.0"
  31. __repo__ = "https://github.com/robert-hh/INA219.git"
  32. # Bits
  33. # pylint: disable=bad-whitespace
  34. _READ = const(0x01)
  35. # Config Register (R/W)
  36. _REG_CONFIG = const(0x00)
  37. _CONFIG_RESET = const(0x8000)  # Reset Bit
  38. _CONFIG_BVOLTAGERANGE_MASK = const(0x2000)  # Bus Voltage Range Mask
  39. _CONFIG_BVOLTAGERANGE_16V = const(0x0000)  # 0-16V Range
  40. _CONFIG_BVOLTAGERANGE_32V = const(0x2000)  # 0-32V Range
  41. _CONFIG_GAIN_MASK = const(0x1800)     # Gain Mask
  42. _CONFIG_GAIN_1_40MV = const(0x0000)   # Gain 1, 40mV Range
  43. _CONFIG_GAIN_2_80MV = const(0x0800)   # Gain 2, 80mV Range
  44. _CONFIG_GAIN_4_160MV = const(0x1000)  # Gain 4, 160mV Range
  45. _CONFIG_GAIN_8_320MV = const(0x1800)  # Gain 8, 320mV Range
  46. _CONFIG_BADCRES_MASK = const(0x0780)   # Bus ADC Resolution Mask
  47. _CONFIG_BADCRES_9BIT = const(0x0080)   # 9-bit bus res = 0..511
  48. _CONFIG_BADCRES_10BIT = const(0x0100)  # 10-bit bus res = 0..1023
  49. _CONFIG_BADCRES_11BIT = const(0x0200)  # 11-bit bus res = 0..2047
  50. _CONFIG_BADCRES_12BIT = const(0x0400)  # 12-bit bus res = 0..4097
  51. _CONFIG_SADCRES_MASK = const(0x0078)              # Shunt ADC Res. &  Avg. Mask
  52. _CONFIG_SADCRES_9BIT_1S_84US = const(0x0000)      # 1 x 9-bit shunt sample
  53. _CONFIG_SADCRES_10BIT_1S_148US = const(0x0008)    # 1 x 10-bit shunt sample
  54. _CONFIG_SADCRES_11BIT_1S_276US = const(0x0010)    # 1 x 11-bit shunt sample
  55. _CONFIG_SADCRES_12BIT_1S_532US = const(0x0018)    # 1 x 12-bit shunt sample
  56. _CONFIG_SADCRES_12BIT_2S_1060US = const(0x0048)   # 2 x 12-bit sample average
  57. _CONFIG_SADCRES_12BIT_4S_2130US = const(0x0050)   # 4 x 12-bit sample average
  58. _CONFIG_SADCRES_12BIT_8S_4260US = const(0x0058)   # 8 x 12-bit sample average
  59. _CONFIG_SADCRES_12BIT_16S_8510US = const(0x0060)  # 16 x 12-bit sample average
  60. _CONFIG_SADCRES_12BIT_32S_17MS = const(0x0068)    # 32 x 12-bit sample average
  61. _CONFIG_SADCRES_12BIT_64S_34MS = const(0x0070)    # 64 x 12-bit sample average
  62. _CONFIG_SADCRES_12BIT_128S_69MS = const(0x0078)   # 128 x 12-bit sample average
  63. _CONFIG_MODE_MASK = const(0x0007)  # Operating Mode Mask
  64. _CONFIG_MODE_POWERDOWN = const(0x0000)
  65. _CONFIG_MODE_SVOLT_TRIGGERED = const(0x0001)
  66. _CONFIG_MODE_BVOLT_TRIGGERED = const(0x0002)
  67. _CONFIG_MODE_SANDBVOLT_TRIGGERED = const(0x0003)
  68. _CONFIG_MODE_ADCOFF = const(0x0004)
  69. _CONFIG_MODE_SVOLT_CONTINUOUS = const(0x0005)
  70. _CONFIG_MODE_BVOLT_CONTINUOUS = const(0x0006)
  71. _CONFIG_MODE_SANDBVOLT_CONTINUOUS = const(0x0007)
  72. # SHUNT VOLTAGE REGISTER (R)
  73. _REG_SHUNTVOLTAGE = const(0x01)
  74. # BUS VOLTAGE REGISTER (R)
  75. _REG_BUSVOLTAGE = const(0x02)
  76. # POWER REGISTER (R)
  77. _REG_POWER = const(0x03)
  78. # CURRENT REGISTER (R)
  79. _REG_CURRENT = const(0x04)
  80. # CALIBRATION REGISTER (R/W)
  81. _REG_CALIBRATION = const(0x05)
  82. # pylint: enable=bad-whitespace
  83. def _to_signed(num):
  84.     if num > 0x7FFF:
  85.         num -= 0x10000
  86.     return num
  87. class INA219:
  88.     """Driver for the INA219 current sensor"""
  89.     def __init__(self, i2c_device, addr=0x40):
  90.         self.i2c_device = i2c_device
  91.         self.i2c_addr = addr
  92.         self.buf = bytearray(2)
  93.         # Multiplier in mA used to determine current from raw reading
  94.         self._current_lsb = 0
  95.         # Multiplier in W used to determine power from raw reading
  96.         self._power_lsb = 0
  97.         # Set chip to known config values to start
  98.         self._cal_value = 4096
  99.         self.set_calibration_32V_2A()
  100.     def _write_register(self, reg, value):
  101.         self.buf[0] = (value >> 8) & 0xFF
  102.         self.buf[1] = value & 0xFF
  103.         self.i2c_device.writeto_mem(self.i2c_addr, reg, self.buf)
  104.     def _read_register(self, reg):
  105.         self.i2c_device.readfrom_mem_into(self.i2c_addr, reg & 0xff, self.buf)
  106.         value = (self.buf[0] << 8) | (self.buf[1])
  107.         return value
  108.     @property
  109.     def shunt_voltage(self):
  110.         """The shunt voltage (between V+ and V-) in Volts (so +-.327V)"""
  111.         value = _to_signed(self._read_register(_REG_SHUNTVOLTAGE))
  112.         # The least signficant bit is 10uV which is 0.00001 volts
  113.         return value * 0.00001
  114.     @property
  115.     def bus_voltage(self):
  116.         """The bus voltage (between V- and GND) in Volts"""
  117.         raw_voltage = self._read_register(_REG_BUSVOLTAGE)
  118.         # Shift to the right 3 to drop CNVR and OVF and multiply by LSB
  119.         # Each least signficant bit is 4mV
  120.         voltage_mv = _to_signed(raw_voltage >> 3) * 4
  121.         return voltage_mv * 0.001
  122.     @property
  123.     def current(self):
  124.         """The current through the shunt resistor in milliamps."""
  125.         # Sometimes a sharp load will reset the INA219, which will
  126.         # reset the cal register, meaning CURRENT and POWER will
  127.         # not be available ... athis by always setting a cal
  128.         # value even if it's an unfortunate extra step
  129.         self._write_register(_REG_CALIBRATION, self._cal_value)
  130.         # Now we can safely read the CURRENT register!
  131.         raw_current = _to_signed(self._read_register(_REG_CURRENT))
  132.         return raw_current * self._current_lsb
  133.     def set_calibration_32V_2A(self):  # pylint: disable=invalid-name
  134.         """Configures to INA219 to be able to measure up to 32V and 2A
  135.             of current. Counter overflow occurs at 3.2A.
  136.            ..note :: These calculations assume a 0.1 shunt ohm resistor"""
  137.         # By default we use a pretty huge range for the input voltage,
  138.         # which probably isn't the most appropriate choice for system
  139.         # that don't use a lot of power.  But all of the calculations
  140.         # are shown below if you want to change the settings.  You will
  141.         # also need to change any relevant register settings, such as
  142.         # setting the VBUS_MAX to 16V instead of 32V, etc.
  143.         # VBUS_MAX = 32V    (Assumes 32V, can also be set to 16V)
  144.         # VSHUNT_MAX = 0.32 (Assumes Gain 8, 320mV, can also be
  145.         #                    0.16, 0.08, 0.04)
  146.         # RSHUNT = 0.1      (Resistor value in ohms)
  147.         # 1. Determine max possible current
  148.         # MaxPossible_I = VSHUNT_MAX / RSHUNT
  149.         # MaxPossible_I = 3.2A
  150.         # 2. Determine max expected current
  151.         # MaxExpected_I = 2.0A
  152.         # 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit)
  153.         # MinimumLSB = MaxExpected_I/32767
  154.         # MinimumLSB = 0.000061              (61uA per bit)
  155.         # MaximumLSB = MaxExpected_I/4096
  156.         # MaximumLSB = 0,000488              (488uA per bit)
  157.         # 4. Choose an LSB between the min and max values
  158.         #    (Preferrably a roundish number close to MinLSB)
  159.         # CurrentLSB = 0.0001 (100uA per bit)
  160.         self._current_lsb = .1  # Current LSB = 100uA per bit
  161.         # 5. Compute the calibration register
  162.         # Cal = trunc (0.04096 / (Current_LSB * RSHUNT))
  163.         # Cal = 4096 (0x1000)
  164.         self._cal_value = 4096
  165.         # 6. Calculate the power LSB
  166.         # PowerLSB = 20 * CurrentLSB
  167.         # PowerLSB = 0.002 (2mW per bit)
  168.         self._power_lsb = .002  # Power LSB = 2mW per bit
  169.         # 7. Compute the maximum current and shunt voltage values before
  170.         #    overflow
  171.         #
  172.         # Max_Current = Current_LSB * 32767
  173.         # Max_Current = 3.2767A before overflow
  174.         #
  175.         # If Max_Current > Max_Possible_I then
  176.         #    Max_Current_Before_Overflow = MaxPossible_I
  177.         # Else
  178.         #    Max_Current_Before_Overflow = Max_Current
  179.         # End If
  180.         #
  181.         # Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT
  182.         # Max_ShuntVoltage = 0.32V
  183.         #
  184.         # If Max_ShuntVoltage >= VSHUNT_MAX
  185.         #    Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX
  186.         # Else
  187.         #    Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage
  188.         # End If
  189.         # 8. Compute the Maximum Power
  190.         # MaximumPower = Max_Current_Before_Overflow * VBUS_MAX
  191.         # MaximumPower = 3.2 * 32V
  192.         # MaximumPower = 102.4W
  193.         # Set Calibration register to 'Cal' calculated above
  194.         self._write_register(_REG_CALIBRATION, self._cal_value)
  195.         # Set Config register to take into account the settings above
  196.         config = (_CONFIG_BVOLTAGERANGE_32V |
  197.                   _CONFIG_GAIN_8_320MV |
  198.                   _CONFIG_BADCRES_12BIT |
  199.                   _CONFIG_SADCRES_12BIT_1S_532US |
  200.                   _CONFIG_MODE_SANDBVOLT_CONTINUOUS)
  201.         self._write_register(_REG_CONFIG, config)
  202.     def set_calibration_32V_1A(self):  # pylint: disable=invalid-name
  203.         """Configures to INA219 to be able to measure up to 32V and 1A of
  204.            current. Counter overflow occurs at 1.3A.
  205.            .. note:: These calculations assume a 0.1 ohm shunt resistor."""
  206.         # By default we use a pretty huge range for the input voltage,
  207.         # which probably isn't the most appropriate choice for system
  208.         # that don't use a lot of power.  But all of the calculations
  209.         # are shown below if you want to change the settings.  You will
  210.         # also need to change any relevant register settings, such as
  211.         # setting the VBUS_MAX to 16V instead of 32V, etc.
  212.         # VBUS_MAX = 32V    (Assumes 32V, can also be set to 16V)
  213.         # VSHUNT_MAX = 0.32 (Assumes Gain 8, 320mV, can also be
  214.         #                    0.16, 0.08, 0.04)
  215.         # RSHUNT = 0.1      (Resistor value in ohms)
  216.         # 1. Determine max possible current
  217.         # MaxPossible_I = VSHUNT_MAX / RSHUNT
  218.         # MaxPossible_I = 3.2A
  219.         # 2. Determine max expected current
  220.         # MaxExpected_I = 1.0A
  221.         # 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit)
  222.         # MinimumLSB = MaxExpected_I/32767
  223.         # MinimumLSB = 0.0000305             (30.5uA per bit)
  224.         # MaximumLSB = MaxExpected_I/4096
  225.         # MaximumLSB = 0.000244              (244uA per bit)
  226.         # 4. Choose an LSB between the min and max values
  227.         #    (Preferrably a roundish number close to MinLSB)
  228.         # CurrentLSB = 0.0000400 (40uA per bit)
  229.         self._current_lsb = 0.04  # In milliamps
  230.         # 5. Compute the calibration register
  231.         # Cal = trunc (0.04096 / (Current_LSB * RSHUNT))
  232.         # Cal = 10240 (0x2800)
  233.         self._cal_value = 10240
  234.         # 6. Calculate the power LSB
  235.         # PowerLSB = 20 * CurrentLSB
  236.         # PowerLSB = 0.0008 (800uW per bit)
  237.         self._power_lsb = 0.0008
  238.         # 7. Compute the maximum current and shunt voltage values before
  239.         #    overflow
  240.         #
  241.         # Max_Current = Current_LSB * 32767
  242.         # Max_Current = 1.31068A before overflow
  243.         #
  244.         # If Max_Current > Max_Possible_I then
  245.         #    Max_Current_Before_Overflow = MaxPossible_I
  246.         # Else
  247.         #    Max_Current_Before_Overflow = Max_Current
  248.         # End If
  249.         #
  250.         # ... In this case, we're good though since Max_Current is less than
  251.         #     MaxPossible_I
  252.         #
  253.         # Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT
  254.         # Max_ShuntVoltage = 0.131068V
  255.         #
  256.         # If Max_ShuntVoltage >= VSHUNT_MAX
  257.         #    Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX
  258.         # Else
  259.         #    Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage
  260.         # End If
  261.         # 8. Compute the Maximum Power
  262.         # MaximumPower = Max_Current_Before_Overflow * VBUS_MAX
  263.         # MaximumPower = 1.31068 * 32V
  264.         # MaximumPower = 41.94176W
  265.         # Set Calibration register to 'Cal' calculated above
  266.         self._write_register(_REG_CALIBRATION, self._cal_value)
  267.         # Set Config register to take into account the settings above
  268.         config = (_CONFIG_BVOLTAGERANGE_32V |
  269.                   _CONFIG_GAIN_8_320MV |
  270.                   _CONFIG_BADCRES_12BIT |
  271.                   _CONFIG_SADCRES_12BIT_1S_532US |
  272.                   _CONFIG_MODE_SANDBVOLT_CONTINUOUS)
  273.         self._write_register(_REG_CONFIG, config)
  274.     def set_calibration_16V_400mA(self):  # pylint: disable=invalid-name
  275.         """Configures to INA219 to be able to measure up to 16V and 400mA of
  276.            current. Counter overflow occurs at 1.6A.
  277.            .. note:: These calculations assume a 0.1 ohm shunt resistor."""
  278.         # Calibration which uses the highest precision for
  279.         # current measurement (0.1mA), at the expense of
  280.         # only supporting 16V at 400mA max.
  281.         # VBUS_MAX = 16V
  282.         # VSHUNT_MAX = 0.04          (Assumes Gain 1, 40mV)
  283.         # RSHUNT = 0.1               (Resistor value in ohms)
  284.         # 1. Determine max possible current
  285.         # MaxPossible_I = VSHUNT_MAX / RSHUNT
  286.         # MaxPossible_I = 0.4A
  287.         # 2. Determine max expected current
  288.         # MaxExpected_I = 0.4A
  289.         # 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit)
  290.         # MinimumLSB = MaxExpected_I/32767
  291.         # MinimumLSB = 0.0000122              (12uA per bit)
  292.         # MaximumLSB = MaxExpected_I/4096
  293.         # MaximumLSB = 0.0000977              (98uA per bit)
  294.         # 4. Choose an LSB between the min and max values
  295.         #    (Preferrably a roundish number close to MinLSB)
  296.         # CurrentLSB = 0.00005 (50uA per bit)
  297.         self._current_lsb = 0.05  # in milliamps
  298.         # 5. Compute the calibration register
  299.         # Cal = trunc (0.04096 / (Current_LSB * RSHUNT))
  300.         # Cal = 8192 (0x2000)
  301.         self._cal_value = 8192
  302.         # 6. Calculate the power LSB
  303.         # PowerLSB = 20 * CurrentLSB
  304.         # PowerLSB = 0.001 (1mW per bit)
  305.         self._power_lsb = 0.001
  306.         # 7. Compute the maximum current and shunt voltage values before
  307.         #    overflow
  308.         #
  309.         # Max_Current = Current_LSB * 32767
  310.         # Max_Current = 1.63835A before overflow
  311.         #
  312.         # If Max_Current > Max_Possible_I then
  313.         #    Max_Current_Before_Overflow = MaxPossible_I
  314.         # Else
  315.         #    Max_Current_Before_Overflow = Max_Current
  316.         # End If
  317.         #
  318.         # Max_Current_Before_Overflow = MaxPossible_I
  319.         # Max_Current_Before_Overflow = 0.4
  320.         #
  321.         # Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT
  322.         # Max_ShuntVoltage = 0.04V
  323.         #
  324.         # If Max_ShuntVoltage >= VSHUNT_MAX
  325.         #    Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX
  326.         # Else
  327.         #    Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage
  328.         # End If
  329.         #
  330.         # Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX
  331.         # Max_ShuntVoltage_Before_Overflow = 0.04V
  332.         # 8. Compute the Maximum Power
  333.         # MaximumPower = Max_Current_Before_Overflow * VBUS_MAX
  334.         # MaximumPower = 0.4 * 16V
  335.         # MaximumPower = 6.4W
  336.         # Set Calibration register to 'Cal' calculated above
  337.         self._write_register(_REG_CALIBRATION, self._cal_value)
  338.         # Set Config register to take into account the settings above
  339.         config = (_CONFIG_BVOLTAGERANGE_16V |
  340.                   _CONFIG_GAIN_1_40MV |
  341.                   _CONFIG_BADCRES_12BIT |
  342.                   _CONFIG_SADCRES_12BIT_1S_532US |
  343.                   _CONFIG_MODE_SANDBVOLT_CONTINUOUS)
  344.         self._write_register(_REG_CONFIG, config)
复制代码




终端打印


  1. '''
  2. Name: INA219 demo, print voltage and current
  3. Version: v1.0
  4. Date: 2025.05
  5. Author: ljl
  6. Other: Shell print voltage and current tested by INA219 sensor.
  7. '''
  8. from machine import I2C, Pin
  9. from ina219 import INA219
  10. from time import sleep
  11. import utime
  12. # I2C Initialization (SDA: GP0, SCL: GP1)
  13. i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=400000)
  14. # I2C-Scan - searching for connected Devices on the I2C Bus
  15. devices = i2c.scan()
  16. if devices:
  17.     print("I2C devices found:", [hex(device) for device in devices])
  18. else:
  19.     print("No I2C devices found. Check connections!")
  20.     while True:
  21.         pass
  22. # INA219-Sensor Initialization
  23. ina = INA219(i2c)
  24. ina.set_calibration_32V_1A()
  25. # main loop
  26. while True:
  27.     try:
  28.         current = ina.current
  29.         voltage = ina.bus_voltage
  30.         
  31.         if current <= 0.05:
  32.             current = 0
  33.             
  34.         if voltage <= 0.05:
  35.             voltage = 0
  36.             
  37.         print("{:.2f} mA  {:.2f} V".format(current, voltage))
  38.         utime.sleep_ms(250)
  39.         
  40.     except Exception as e:
  41.         print("Error reading INA219:", e)
  42.         
  43.     sleep(1)OLED 显示'''
  44. Name: INA219 demo, print and display voltage and current
  45. Version: v1.0
  46. Date: 2025.05
  47. Author: ljl
  48. Other: Shell print and OLED display voltage and current tested by INA219 sensor.
  49. '''
  50. from machine import I2C, Pin
  51. from ina219 import INA219
  52. from time import sleep
  53. import utime
  54. import ssd1306
  55. # ==== Initialized IIC OLED ====
  56. i2c = I2C(0, scl=Pin(5), sda=Pin(4),freq=400000)
  57. oled_width = 128
  58. oled_height = 64
  59. oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
  60. #i2c = I2C(0, scl=Pin(1), sda=Pin(0),freq=400000)
  61. # I2C-Scan - searching for connected Devices on the I2C Bus
  62. devices = i2c.scan()
  63. if devices:
  64.     print("I2C devices found:", [hex(device) for device in devices])
  65. else:
  66.     print("No I2C devices found. Check connections!")
  67.     while True:
  68.         pass
  69. # INA219-Sensor Initialization
  70. ina = INA219(i2c)
  71. ina.set_calibration_32V_1A()
  72. def display_VC(voltage,current): # voltage and current
  73.     oled.fill(0)  # 清屏
  74.     oled.text("Voltage: ", 0, 0)
  75.     oled.text("{:.2f} V".format(voltage), 0, 15)
  76.     oled.text("Current: ", 0, 35)
  77.     oled.text("{:.2f} mA".format(current), 0, 50)
  78.     oled.show()
  79. # main loop
  80. while True:
  81.     try:
  82.         current = ina.current
  83.         voltage = ina.bus_voltage
  84.         
  85.         if current <= 0.05:
  86.             current = 0
  87.             
  88.         if voltage <= 0.05:
  89.             voltage = 0
  90.             
  91.         print("{:.2f} mA  {:.2f} V".format(current, voltage))
  92.         display_VC(voltage,current);
  93.         utime.sleep_ms(250)
  94.         
  95.     except Exception as e:
  96.         print("Error reading INA219:", e)
  97.         
  98.     sleep(1)
复制代码



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

代码
串口以十六进制发送 55 AA 1055 AA 11 分别获得电压和电流数值。

  1. '''
  2. Name: INA219 demo, print and UART voltage and current
  3. Version: v1.0
  4. Date: 2025.05
  5. Author: ljl
  6. Other: UART send voltage and current which data tested by INA219 sensor.
  7. '''
  8. from machine import Pin, I2C, UART
  9. from ina219 import INA219
  10. import utime
  11. import ssd1306
  12. # ==== Initialized IIC OLED ====
  13. i2c = I2C(0, scl=Pin(5), sda=Pin(4),freq=400000)
  14. oled_width = 128
  15. oled_height = 64
  16. oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
  17. #i2c = I2C(0, scl=Pin(1), sda=Pin(0),freq=400000)
  18. # I2C-Scan - searching for connected Devices on the I2C Bus
  19. devices = i2c.scan()
  20. if devices:
  21.     print("I2C devices found:", [hex(device) for device in devices])
  22. else:
  23.     print("No I2C devices found. Check connections!")
  24.     while True:
  25.         pass
  26. # INA219-Sensor Initialization
  27. ina = INA219(i2c)
  28. ina.set_calibration_32V_1A()
  29. # Initialize UART (change pins as needed for your board)
  30. uart = machine.UART(1, baudrate=9600, tx=Pin(8), rx=Pin(9))
  31. comdata = bytearray(3)
  32. def display_VC(voltage,current): # voltage and current
  33.     oled.fill(0)  # 清屏
  34.     oled.text("Voltage: ", 0, 0)
  35.     oled.text("{:.2f} V".format(voltage), 0, 15)
  36.     oled.text("Current: ", 0, 35)
  37.     oled.text("{:.2f} mA".format(current), 0, 50)
  38.     oled.show()
  39. def receive_data():
  40.     for i in range(3):
  41.         while not uart.any():  # Wait for data to be available
  42.             pass
  43.         comdata = uart.read(1)[0]  # Read one byte
  44.         utime.sleep_ms(2)  # Small delay between bytes
  45. def test_do_data():
  46.     if comdata[0] == 0x55 and comdata[1] == 0xAA:
  47.         try:
  48.             if comdata[2] == 0x10:
  49.                 voltage = ina.bus_voltage
  50.                 if voltage <= 0.05:
  51.                     voltage = 0
  52.                 uart.write("{:.2f}\r\n".format(voltage))
  53.             elif comdata[2] == 0x11:
  54.                 current = ina.current
  55.                 if current <= 0.05:
  56.                     current = 0
  57.                 uart.write("{:.2f}\r\n".format(current))
  58.         except Exception as e:
  59.                 uart.write("Error reading sensor.\r\n")
  60. # Serial acquire data
  61. def uart_acquire():
  62.     if uart.any() >= 3:
  63.         receive_data()
  64.         test_do_data()
  65.     utime.sleep_ms(0)  # Small delay to prevent busy-wait
  66. # main loop
  67. while True:
  68.     uart_acquire()
复制代码


前面板
功能实现:

  • 配置串口
  • 运行程序
  • 点击 Start 开始采集数据
  • 点击 Stop 停止采集
  • 点击 Terminate 终止程序。


Beetle 树莓派RP2350 - 便携INA219功率计图10


程序框图

Page 1

Beetle 树莓派RP2350 - 便携INA219功率计图9

Page 2

Beetle 树莓派RP2350 - 便携INA219功率计图8

效果
Beetle 树莓派RP2350 - 便携INA219功率计图7

OLED 显示
Beetle 树莓派RP2350 - 便携INA219功率计图6

终端打印
Beetle 树莓派RP2350 - 便携INA219功率计图5

测量电机功率
在完成空载情况下功率测量的基础上,考虑加负载的情况。

负载可以是功率器件、电阻、电机等,可以较为明显地反映系统功率的变化。

硬件连接
  • GP4 ---- SDA (INA219)
  • GP5 ---- SCL (INA219)
  • GP8 ---- RXD (CH340)
  • GP9 ---- TXD (CH340)
  • GP4 ---- SDA (OLED_SSD1306)
  • GP5 ---- SCL (OLED_SSD1306)
  • GND (INA219) ---- Negative (Motor) ---- Negative (Power Supply)
  • IN+ (INA219) ---- Positive (Power Supply)
  • IN- (INA219) ---- Positive (Motor)

Beetle 树莓派RP2350 - 便携INA219功率计图4


实物连接

Beetle 树莓派RP2350 - 便携INA219功率计图3

通过对比供电接口处的电压和电流值,INA219传感器可以获得更精确的功率值。

动态演示
Beetle 树莓派RP2350 - 便携INA219功率计图2

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

Beetle 树莓派RP2350 - 便携INA219功率计图1

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


总结
本文介绍了 DFRobot Beetle RP2350 开发板结合 INA219 模块实现功率计,并通过 LabVIEW 上位机串口采集 INA219 电流、电压、功率数据监测的项目设计,为 Beetle RP2350 开发板的开发设计和产品应用提供了参考。


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail