树莓派PICO使用INA226测量电流和总线电压(2)

        上一篇文章里,我们讲了如何设置配置寄存器(0x01),在测量电流之前,还需要设置校准寄存器(0x05),校准寄存器非常关键,如果不设置这个寄存器,INA226是不会工作的。

        在设置寄存器之前,有一个概念必须了解:LSB,即最低有效位(least significant bit)。这个值非常的关键,因为它就是ADC能提供的分辨率,在手册里,提供了如何计算校准值的方法,其中最关键的就是计算LSB。

        在计算校准值之前,我们必须知道IN+和IN-之间的电阻大小,在这儿我建议根据电流极限,尽可能使用较大的采样电阻。因为PCB的铜箔也有电阻,虽然值并不大,但也能达到毫欧级别。所以,在设计线路的时候,尽可能将采样电阻贴紧INA226,减少线路带来的误差。

        

        依照手册给出的公式,我们必须人为的指定一个最大的测量电流,然后用这个值除以 32768,即2的15次方,得到的值,就是电流的最低有效位。比如,在这个方案里面,我选择的电流最大测量范围是0.512A,不用奇怪我为啥用一个带三位小数的值,因为 512 是2的9次方。

        根据公式 2,current_lsb = 0.512 / 32768 = 0.000015625;大概15.625 uA。

        然后根据公式 1 计算校准值,因为已知分流器是0.1Ω,计算如下:

        cal = 0.00512 / ( 0.000015625 * 0.1 ) = 3276.8;取整之后,得到 3276,这个就是校准值。

        当然,也可以根据实际情况,将 current_lsb 做略微的调整,比如

        从 0.000015625 调整到 0.000016(16 是 2的4次方),然后计算

        cal = 0.00512 / ( 0.000016 * 0.1 ) = 3200;这样就不存在取整的问题。

        得到 cal 之后,将 current_lsb 和 cal 单独保存下来,后面的计算还需要这两个值。

        计算 cal 的代码如下:


uint8_t config_register         = 0x00;
uint8_t shunt_register          = 0x01;
uint8_t bus_voltage_register    = 0x02;
uint8_t current_register        = 0x04;
uint8_t calibration_register    = 0x05;


double current_lsb = 0.0;
double calibration = 0.0;

uint16_t INA226Calibration(double shunt_resistor, double max_expected_current)
{
    current_lsb = max_expected_current / 32768;
    calibration = 0.00512 / current_lsb;
    calibration = calibration / shunt_resistor;
    return (uint16_t)( calibration );
} 

接下来,就是设置校准寄存器:

        

void setup() 
{
    // put your setup code here, to run once:
    Serial.begin( 115200 );
    i2c_init( i2c_default, 100*1000 );
    gpio_set_function(I2C_SDA, GPIO_FUNC_I2C);
    gpio_set_function(I2C_SCL, GPIO_FUNC_I2C);
    gpio_pull_up(I2C_SDA);
    gpio_pull_up(I2C_SCL);
    bi_decl(bi_2pins_with_func(I2C_SDA, I2C_SCL,GPIO_FUNC_I2C));

    
    uint16_t config = INA226Config( IAT_4, ICT_588US, ICT_8244US, IOM_CONTINUOUS_SHUNT_AND_BUS_VOLTAGE );

    uint8_t data_1[3];
    data_1[0] = config_register;
    data_1[1] = config >> 8;
    data_1[2] = config & 0x00ff;    

    i2c_write_blocking(i2c_default, 0x40, data_1, sizeof(data_1), false );


    uint16_t cal = INA226Calibration( 0.1, 0.512 );

    uint8_t data_2[3]; 
    data_2[0] = calibration_register;
    data_2[1] = cal >> 8;
    data_2[2] = cal & 0x00ff;

    i2c_write_blocking(i2c_default, 0x40, data_2, sizeof(data_2), false );
}

        这两个寄存器设置完成之后,INA226就开始工作了。此时,已经可以通过代码读取INA226的测量数据了。 代码如下:

    for( ;; )
    {
        uint16_t readed = 0;

        i2c_write_blocking(i2c_default, 0x40, & current_register, sizeof(current_register), true );
        i2c_read_blocking (i2c_default, 0x40, (uint8_t *) & readed, sizeof(readed), false );

        readed = readed >> 8 | readed << 8;

        Serial.printf( "%X, %d, %f, %fA\n", cal, config, calibration, readed * current_lsb );
    }

         读取出来的值,需要做大小端交换,然后将这个值乘以 current_lsb,就能得到电流读数。在我的例子中,电压3.3V,电阻调整在1.6k附近,读出来的数据范围和计算数据范围吻合。

<think>好的,我需要帮助用户编写一个基于INA226的Python测试程序,支持外部配置采样次数并输出电流电压的平均值。首先,我需要了解INA226的基本工作原理通信方式。根据用户提供的引用内容,INA226通过I2C或SMBus接口通信,可以测量电流、电压功率,并且有可配置的采样次数转换时间。 用户的需求是编写一个Python程序,能够通过外部参数指定采样次数,然后计算这些采样值的平均值。我需要考虑以下几个步骤: 1. **硬件连接确认**:根据引用[2],INA226的接线方式是INPUT接电源正极,GND接电源负极,OUTPUT接用电器件。虽然用户提到没有接OUTPUT,但硬件连接正确是程序工作的前提,需要确保I2C线路连接正确,设备地址正确。 2. **I2C通信设置**:在Python中,通常使用smbus或machine库(针对MicroPython)来操作I2C。用户提供的引用[1]中提到使用MicroPython代码,可能是在树莓派Pico上运行,因此可能需要使用特定的库。 3. **配置INA226寄存器**:根据数据手册,需要配置校准寄存器、配置寄存器等。例如,设置采样次数、转换时间,以及模式(连续或触发)。用户需要能够通过外部参数调整采样次数,这可能涉及到配置寄存器中的平均模式设置。 4. **读取电流电压值**:INA226电流电压值分别存储在特定的寄存器中,读取后需要根据校准值进行计算。校准值需要根据分流电阻最大预期电流来计算。 5. **处理外部参数**:程序需要接受外部输入的采样次数参数,例如通过命令行参数,然后循环采样指定次数,存储数据,最后计算平均值。 6. **代码结构错误处理**:确保代码结构清晰,处理可能的I2C通信错误,例如设备未连接、地址错误等。 可能的难点包括正确配置寄存器,处理不同采样次数下的数据读取,以及确保计算的平均值准确。需要查阅INA226的数据手册确认寄存器的地址配置位的含义。例如,配置寄存器中的平均模式(Averaging Mode)可以设置采样次数为1、4、16、64、128、256、512或1024次。如果用户希望外部配置的采样次数不在这些预设值中,可能需要通过软件多次读取并取平均。 此外,校准值的计算是关键,需要根据使用的分流电阻值(例如0.1欧姆)最大预期电流来计算校准寄存器中的值,以确保测量精度。 最后,代码需要模块化,方便用户调用扩展,例如将配置、采样、计算平均值的部分分开,提高可读性重用性。</think>### 基于 INA226 的 Python 测试程序实现步骤 #### 1. **硬件准备与连接** - 确保 INA226 正确连接到 Raspberry Pi Pico 的 I2C 接口(默认引脚:GPIO4/5)。 - 确认 I2C 地址(参考引用[2],默认地址为 `0x40`,可通过引脚配置为其他地址)。 #### 2. **依赖库安装** ```python from machine import I2C, Pin import time ``` #### 3. **INA226 寄存器配置** 以下是关键寄存器地址(参考数据手册): - **配置寄存器**:`0x00`(设置采样模式、转换时间等) - **电流寄存器**:`0x01`(直接读取电流值) - **线电压寄存器**:`0x02` - **校准寄存器**:`0x05`(需根据分流电阻计算) #### 4. **完整代码实现** ```python from machine import I2C, Pin import time class INA226: def __init__(self, i2c, address=0x40, shunt_resistor=0.1, max_current=3.2): self.i2c = i2c self.address = address self.shunt_resistor = shunt_resistor self.max_current = max_current # 校准计算(公式来自数据手册) self.calibration_value = int(0.00512 / (self.shunt_resistor * self.max_current)) self._write_register(0x05, self.calibration_value) # 配置寄存器:平均模式 64次,线电压转换时间 1.1ms,连续测量模式 config = 0x4000 | 0x0080 | 0x0007 # 具体位定义需参考数据手册 self._write_register(0x00, config) def _write_register(self, reg, value): data = bytearray([(value >> 8) & 0xFF, value & 0xFF]) self.i2c.writeto_mem(self.address, reg, data) def _read_register(self, reg): data = self.i2c.readfrom_mem(self.address, reg, 2) return (data[0] << 8) | data[1] def read_current(self): raw_current = self._read_register(0x01) return raw_current * self.max_current / 32768 # 转换为实际电流(单位:A) def read_voltage(self): raw_voltage = self._read_register(0x02) return raw_voltage * 1.25e-3 # 转换为实际电压(单位:V) def main(samples=10): i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=100000) ina = INA226(i2c) current_sum = 0 voltage_sum = 0 for _ in range(samples): current_sum += ina.read_current() voltage_sum += ina.read_voltage() time.sleep(0.1) # 等待采样完成 print(f"平均电流:{current_sum/samples:.3f} A") print(f"平均电压:{voltage_sum/samples:.3f} V") # 通过命令行参数调用(示例) # import sys # if len(sys.argv) > 1: # main(int(sys.argv[1])) # else: # main() ``` #### 5. **关键功能说明** - **校准计算**:根据公式 $Cal = \frac{0.00512}{R_{shunt} \cdot I_{max}}$ 设置校准寄存器[^2]。 - **平均模式**:通过配置寄存器设置硬件平均次数(代码示例中为64次),若需更高灵活性,可通过软件多次读取。 - **单位转换**:电流值需根据校准参数寄存器范围转换($I = \frac{Raw \cdot I_{max}}{32768}$)[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值