pdf-icon

Arduino入門

2. デバイス&サンプル

Station Grove Power 電源管理システムです

Station インターフェース電源管理関連APIとケースプログラムです。

USB-A ポート出力電流 の 計算原理

Station の USB-A ポートは出力電流情報の取得のみをサポートしており、GPIO34 を通じて INA199Ax1 の出力電圧値を取得して換算することで USB-A の出力電流値を求める必要があります。この電圧値は USB-A の出力電流値とほぼ比例しています。

上記の原理図から分かるように、INA199x1 の基準電圧(REF)の理想値は:(R54\(R54+R55))MCU_VDD ,すなわち 1\2MCU_VDD です。しかし、ハードウェア部品の許容誤差と本設計構造が精密構造ではないため、この基準電圧(REF)の実際の値は実測が必要です。
INA199 の データシートを参照すると,分流抵抗(すなわち上図の $R_{44}$)の両端の電圧差を検出して電流を測定し、内部で設定されたゲイン(INA199x1 の場合50V/V),に基づいて、実時間で検出した電流信号を OUT ピンから対応するアナログ電圧信号(すなわち以下のコードの usb_vol)。に変換して出力することがわかります。USB-A ポートが無負荷の場合、INA199x1 の出力電圧値は基準電圧(REF)の実際の値に近づき、すなわち以下のコードの usb_vref です。OUT ピンの出力電圧の計算式は usb_vol = usb_vref + Io * (R44*50) で,換算すると Io = (usb_vol - usb_vref) \ (R44*50) となります。
具体的な実装は以下のコードを参照してください。

サンプルプログラム

cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
#include <Arduino.h>
#include "M5Unified.h"

#define USB_PIN 34
const float V_REF = 3.3;     // Analog reference voltage (e.g., 5V or 3.3V) due to hardware
const float Res_BITS = 12.0;   // ADC resolution (bits)
const float ADC_STEPS = (1 << int(Res_BITS)) - 1; // Number of steps (2^Res_BITS - 1)
float usb_vref;//INA199x1 REF

float get_USB_Volt(float num){
    float volt;
    for (size_t i = 0; i < num; i++) {
        volt = volt + analogRead(USB_PIN);
        delay(10);
    }

    volt = volt / num / ADC_STEPS * V_REF;
    return volt;//unit: V
}

void setup()
{
    auto cfg = M5.config();
    M5.begin(cfg);
    M5.Display.setTextDatum(middle_center);
    M5.Display.setTextColor(TFT_BLACK);
    M5.Display.setTextFont(&fonts::FreeSansOblique9pt7b);
    M5.Display.setTextSize(1);
    M5.Power.setExtOutput(false, (m5::ext_port_mask_t)(m5::ext_USB|m5::ext_PA|m5::ext_PB1|m5::ext_PB2|m5::ext_PC1|m5::ext_PC2));
    analogReadResolution(12);//Set ADC Resolution
    analogSetAttenuation(ADC_11db);//Set ADC Attenuation
    M5.Lcd.clear(TFT_WHITE); 
    M5.Power.setExtOutput(true, (m5::ext_port_mask_t)(m5::ext_USB|m5::ext_PA|m5::ext_PB1|m5::ext_PB2|m5::ext_PC1|m5::ext_PC2));
    delay(200);
    usb_vref = get_USB_Volt(5);//Obtain the output voltage of INA199 when the USB is in a no-laod state. This voltage is the reference voltage.
}

void loop()
{
    M5.Display.clear(TFT_WHITE);
    
    bool isSupplying = M5.Power.getExtOutput();
    if(isSupplying){
        M5.Lcd.setCursor(0, 10);
        float usb_vol = get_USB_Volt(5);//Obtain the real-time output voltage of INA199
        float usb_current = ((usb_vol - usb_vref) / 50.0f / 0.01f * 1000.0f);//unit:mA  usb_vol = usb_vref + Io(unit: A)*(0.01Ω*50)
        M5.Lcd.printf("USB-A %3.0fmA", usb_current);
        M5.Lcd.setCursor(0, 30);
        M5.Lcd.printf("A1%3.0fmA %1.1fV  A2%3.0fmA %1.1fV\n",
                    M5.Power.Ina3221[0].getCurrent(0) * 1000,
                    M5.Power.Ina3221[0].getBusVoltage(0),
                    M5.Power.Ina3221[0].getCurrent(1) * 1000,
                    M5.Power.Ina3221[0].getBusVoltage(1));
        M5.Lcd.setCursor(0, 50);
        M5.Lcd.printf("B1%3.0fmA %1.1fV  B2%3.0fmA %1.1fV\n",
                    M5.Power.Ina3221[0].getCurrent(2) * 1000,
                    M5.Power.Ina3221[0].getBusVoltage(2),
                    M5.Power.Ina3221[1].getCurrent(0) * 1000,
                    M5.Power.Ina3221[1].getBusVoltage(0));
        M5.Lcd.setCursor(0, 70);
        M5.Lcd.printf("C1%3.0fmA %1.1fV  C2%3.0fmA %1.1fV\n",
                    M5.Power.Ina3221[1].getCurrent(1) * 1000,
                    M5.Power.Ina3221[1].getBusVoltage(1),
                    M5.Power.Ina3221[1].getCurrent(2) * 1000,
                    M5.Power.Ina3221[1].getBusVoltage(2));
    }
    delay(1000);
}                                            

このプログラムは画面上に各 Grove のリアルタイムの出力電圧と電流情報を表示します。

API

Station の電源管理部分では M5Unified ライブラリ内のPower_Classを使用しています。詳細なAPIは以下のドキュメントを参照してください:

On This Page