電流・電圧を簡単に測定することができるセンサーモジュール(INA219)をRaspberry Pi Pico(ラズパイPico)から使ってみます。
以前、INA219をArduinoから使ったことがあるのですが、今回は同じ内容をそのままPicoでやってるだけです。Picoの開発環境はArduinoIDEを使用するため、内容はほとんどArduinoと同様になります。
結線
INA219モジュールとの結線方法です。
▼INA219▼
秋月だったかAmazonだったか忘れてしまったのですが、以前入手したモジュールです。I2C通信でマイコンとやり取りします。
▼結線▼
ブレッドボードで結線してます。
INA219 Vcc ⇔ Pico 3V3(OUT)(36pin) INA219 Gnd ⇔ Pico Gnd(38pin) INA219 Sda ⇔ Pico GP16(I2C0 SDA) INA219 Scl ⇔ Pico GP17(I2C0 SCL)
▲PicoとINA219との結線。Picoの場合、I2C通信に使用するピンがある程度自由に決められます。特に意味はありませんが今回はGP16/17ピンに割り当ててます。(ブレッドボード上で近くのピンにしたかっただけです。)
▲で電流・電圧を測定したい回路にINA219のVin+、Vin-を直列に挟めば準備完了。±方向はどちらでも測定可能。電流「±」で出力されて、流れる方向がわかるようになってます。
ソース
ラズパイPicoに書き込むソースです。部分的に切り取って解説していきます。ソース全体は記事最下段に掲載してます。開発環境はArduinoIDEを使用するため、このソースはそのままArduinoでも使えます。
#include <Wire.h> void setup() { //Wire.setSDA(16); //I2C0 SDA GP16 //Wire.setSCL(17); //I2C0 SCL GP17 Wire.setClock(400000); Wire.begin(); //I2C0 begin
▲まず、I2C通信を開始します。Pico(earlephilhowerのライブラリを使用)の場合、ピンアサインを変更する場合はコメントアウトします。デフォルトは確かSDA:GP4ピン、SCL:GP5ピンです。Unoの場合、A4/A5ピンになります。
int16_t config_value = 0x399F; //INA219 デフォルト Wire.beginTransmission(0x40); //INA219 デバイスアドレス Wire.write(0x00); //configアドレス Wire.write((config_value >> 8) & 0xFF); Wire.write(config_value & 0xFF); Wire.endTransmission();
▲次にINA219の初期設定です。BUS電圧レンジ±32V(LSB4mV)、シャント抵抗間電圧レンジ320mV(ゲイン/8)、±2A、12bitの設定です。詳しくはデーターシートをみましょう。難しければこのままおまじないと思って記述しましょう。一度実行するだけなのでsetup内の記述でOK。
Wire.beginTransmission(0x40); //デバイスアドレス Wire.write(0x02); //BusVoltageレジスタ Wire.endTransmission(); Wire.requestFrom(0x40, 16); while (Wire.available() < 16); BusVoltage = Wire.read() << 8 | Wire.read(); BusVoltage = (BusVoltage >> 3) * 4;
▲電圧の読み取りです。読み取るたびにこの記述を行います。この記述は、[mV]となります。
Wire.beginTransmission(0x40); // デバイスアドレス Wire.write(0x01); // Shuntvoltageレジスタ Wire.endTransmission(); Wire.requestFrom(0x40, 16); while (Wire.available() < 16); shuntvoltage_raw = Wire.read() << 8 | Wire.read(); current_mA = shuntvoltage_raw * 0.1;
▲電流値です。シャント抵抗間の電圧を測定してから電流値を計算してます。単位は、mAです。
精度確認
適当な電圧と負荷を設定して電流値の測定精度比較をしてみます。。
▼シリアルモニタ表示▼
▼精度確認▼
電圧[mV] | 抵抗[Ω] | 電流(理論値)[mA] | 電流(計測)[mA] |
3284 | 330 | 9.9 | 9.9 |
2864 | 20 | 143 | 134.6 |
4352 | 20 | 217 | 206 |
4992 | 330 | 15.1 | 14.7 |
あまり大きな電流値で測定してませんがそれなりな精度かと・・・。
ソース全体
今回の測定に使用したソース全文です。PICO用ですが、ピンアサインのところを修正するのみでArduino UNOでもそのまま使えます。
#include <Wire.h> int16_t BusVoltage_mV, ShuntVoltage_raw; float ShuntVoltage_mV, current_mA; void setup() { pinMode(25, OUTPUT); Serial.begin(115200); Wire.setSDA(16); //I2C0 SDA GP16 Wire.setSCL(17); //I2C0 SCL GP17 Wire.setClock(400000); Wire.begin(); //I2C0 begin int16_t config_value = 0x399F; //INA219 デフォルト Wire.beginTransmission(0x40); //INA219 デバイスアドレス Wire.write(0x00); //configアドレス Wire.write((config_value >> 8) & 0xFF); Wire.write(config_value & 0xFF); Wire.endTransmission(); digitalWrite(25, HIGH); } void loop() { //Get BusVoltage Wire.beginTransmission(0x40); //デバイスアドレス Wire.write(0x02); //BusVoltageレジスタ Wire.endTransmission(); Wire.requestFrom(0x40, 16); while (Wire.available() < 16); BusVoltage_mV = Wire.read() << 8 | Wire.read(); BusVoltage_mV = (BusVoltage_mV >> 3) * 4; //Get ShuntVoltage Wire.beginTransmission(0x40); //デバイスアドレス Wire.write(0x01); //ShuntVoltageレジスタ Wire.endTransmission(); Wire.requestFrom(0x40, 16); while (Wire.available() < 16); ShuntVoltage_raw = Wire.read() << 8 | Wire.read(); ShuntVoltage_mV = ShuntVoltage_raw * 0.01; // *0.01[mV] // *10[uV] current_mA = ShuntVoltage_mV * 10; //I=V/R=V/0.1=V*10 Serial.print("BusVoltage "); Serial.print(BusVoltage_mV); Serial.print("mV "); Serial.print("ShuntVoltage "); Serial.print(ShuntVoltage_mV); Serial.print("mV "); Serial.print("Current "); Serial.print(current_mA); Serial.println("mA"); delay(500); }
コメント