ラズパイPico：電池で動作、電池の電圧をOLEDに表示

# ［記事の概要］
■ Raspberry Pi Pico の応用例が数多く発表・投稿されていますが、USBコネクタから電源を供給する例が多く電池で動作させている例は少ないです。ラズパイPicoで小さくて携帯可能なものを作ろうと思って **「電池をどのように接続するか？」** について調べました。 さらに、電池の減り具合が気になるので **「電池の電圧を表示したい」、「電池を長持ちさせたい」** に関する調査もしました。

■ この記事では **「電池の接続方法」** と **「電池電圧をOLEDに表示する」** ことについて私が試したことを紹介します。

■ **「電池を長持ちさせる方法 ⇒ スリープ動作」** に関してはその内、別の記事として投稿したいと思います。

（注）この記事はハードウェアに関することがメインです。開発環境は Windows 10でArduino IDEを使用しましたが、他の開発環境をご利用の場合でも参考になると思います。

# １. 電池の選択

⬛携帯機器や商用電源のない場所で動作するIOT機器などの電池はどのように選べばよいでしょう？　選択基準として、電圧(V)、容量(mAh)、形状、サイズ、充電の可否、入手性、価格がありますが、特に「電圧」に着目して下記の記事を投稿しましたのでご覧ください。

https://qiita.com/totuto/items/0268e0e73caeb0d545d3

⬛**単1/単2/単3/単4/単5型で1.5V、充電可能なリチウムイオン電池** のレポートもあります。

![1V5リチウム電池1+3+8.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/0d422249-ed1e-a22a-ede7-ff6391f088e1.jpeg)

⬛上記の記事に **「モバイルバッテリー」** の注意点ついて書きました。重要なことなので重複しますが、ここにも書きます。モバイルバッテリーは、高容量／小型／USBコネクタで手軽に充電可能など多くの優れた特徴があり、とても魅力的ですが・・・

:::note alert
モバイルバッテリーは携帯機器、IOT機器用としては重大な問題があります！

モバイルバッテリーはスマホの充電用に設計されていて、充電が完了して出力電流が小さくなると、オートパワーオフ機能が動作して電力供給を止めます。

Arduino, ESP32, ラズパイPicoなどのワンボードマイコンで数mA～数10mA程度の電流しか流れない機器をモバイルバッテリーに接続すると、オートパワーオフ機能が動作しておよそ15秒程度で切れてしまいます。

対策としては「IoT向けモバイルバッテリー」「IoT機器対応モバイルバッテリー」といった製品があります。
:::

# ２. 電源系統とDCDCコンバータ

■ Raspberry Pi Pico は 3.3VのDC-DCコンバータが内蔵されていて 1.8V～5.5Vの電源を供給すれば動作します。センサや表示器などのI/Oの電源が全て3.3Vで動作する場合は下図の「3.3V系システム」の構成になります。
 
**3.3V系システム**
![3V3系システム.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/ca73bee1-7003-0feb-54eb-2e8cf5820c07.jpeg)
この構成なら単3または単4電池2本、あるいはリチウム電池（公称電圧：3.7V、フル充電時：4.2V、放電終止電圧2.5V）1個でもOKです。

下記のように3.3VのDCDCコンバータを使用すると単3または単4電池1本でも動作します。
![3V3系システム(2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/6c3e752c-6a5f-bad2-bc46-24bbd4dbf515.jpeg)

5Vで動作するものがある場合は下記のような「5V系システム」の構成になります。5Vの電池というものは存在しないのでDC-DCコンバータが必要です。（モバイルバッテリーは5Vの電池とみなすこともできますが、前述のような問題があります）

**5V系システム**
![5V系システム.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/1da4a4f1-5c6d-dd96-ab5c-1a5b4cac4d0c.jpeg)
この場合、電池の電圧は？

■ DC-DCコンバータは、入力電圧が出力電圧より高いものは「降圧型」、または「ステップダウン型」、「Buck（ICのカタログで見かけます）」ともいいます。逆に入力電圧が出力電圧より低いものは「昇圧型」「ステップアップ型」「Boost」といいます。Pico 内蔵のDC-DCコンバータは出力：3.3Vに対して入力電圧は1.8V～5.5Vと昇圧と降圧の両方に対応しています。

・出力5Vで降圧型コンバータの場合、5V以上の電池が必要です。電池の個数やサイズをコンパクトにしたい場合は昇圧型にすると良いでしょう。

【参考】下記の記事では、DC-DCコンバータの市販各社へのリンクと実際に使用して電圧の変動を評価したことを報告しました。

https://qiita.com/totuto/items/0268e0e73caeb0d545d3

# ３. ラズパイPicoの電源関係のピンと電源回路

電源回路の動作は、Raspberry Pi Pico Datasheet の「4.4. Powerchain」の項で説明されています（英文）。

https://datasheets.raspberrypi.com/pico/pico-datasheet.pdf

エレホビカさんのブログでは、これを分かり易く解説し、さらにスリープ動作に関して実際に応用した例もハードとソフトの詳しい説明付きで報告されていて大変参考になりました。

https://elehobica.blogspot.com/2021/08/raspberry-pi-pico-1.html

https://elehobica.blogspot.com/2021/08/raspberry-pi-pico-2.html

ラズパイPicoの電源関係のピンは基板の36～40ピンに集中しています。
![ラズパイPico電源関係のピン.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/ade1cde6-2be3-6e08-1f90-d184184f9e25.jpeg)

| ピンNo.| 信号名|機能|
|:-:|:-:|:--|
|40|VBUS|USBコネクタからの電源入力 (5V)|
|39|VSYS|外部電源入力(1.8V～5.5V)|
|38|GND|0V|
|37|3V3_EN|DCDCコンバータのイネーブル入力|
|36|3V3 (OUT)|3.3V出力|

■ USBコネクタを接続するとVBUS（40ピン）に5Vが出て、DCDCコンバータを経由して3V3（36ピン）に3.3Vが出力されます。
■ USBコネクタから供給ではなく電池を使用する時はVSYS（39ピン）に接続します。
■ 3V3_EN（37ピン）とGPIO23でDCDCコンバータの動作を制御できます。
■ GPIO24でUSB接続の有無が分かります。

![ラズパイPico電源回路.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/9a5865dd-ac35-0920-abe1-b75edea5f8ed.jpeg)

# ４. ラズパイPicoを電池で動かす（ＳＢＤ使用時）
電池はVSYS（39ピン）から供給します。図の(V)の部分は、仮に単3型アルカリ電池2本(3V) とします。USBコネクタが接続されたとき（VBUS=5V）、電池への逆流防止対策としてショットキーバリアダイオード（SBD, 図のD）を入れるのが簡単ですがSBDの電圧降下が気になります。

例えばSBDの降下電圧VFが0.4Vと仮定し、アルカリ電池は新品のときは1.65V程度ありますが公称電圧1.5Vとして2本の場合、
　　　VSYS = 1.5(V) × 2 - 0.4(V) = 2.6(V) 
とDCDCコンバータの入力電圧1.8V～5.5Vの範囲内です。

電池の電圧が下がると、どこまで動作可能でしょうか？
　　　ｘ(V) × 2 - 0.4(V) = 1.8(V)
これを解くと x = 1.1　電池1本当たり1.1V に下がるまで動作するということです。アルカリ電池が 1.1Vというのはかなり弱った状態だと思います。

![ラズパイPico-VSYS-SBD.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/880913d3-967e-8a3c-0f8f-1c44b98f6941.jpeg)

# ５. ［実験］ラズパイPicoの動作電圧のテスト（SBD使用時）
SBD経由での電池接続は問題なさそうですが実際のところどうなのか試してみました。

ショットキーバリアダイオードは、ブレッドボードに挿せるアキシャル型で、且つ秋月電子通商で販売されているものという条件では SBM245Lがいいかなと思いました。

![秋月のSBM245L.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/471ee414-1fe8-6a31-dea1-43e144c6af82.jpeg)
・逆電圧：45V
・平均順電流：2A
・ピーク順電流：50A
・順電圧：0.33V(0.5A)

テストの機材は、ラズパイPicoで0.96インチOLEDを表示するという構成です。電源関係の接続は下図のようになりますが、実際には電池の代わりに実験用電源装置を使用しました。

![ラズパイPico-VSYS-SBD-電池.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/103c84ae-233e-dc66-2992-52c3c52dd2b2.jpeg)

以下のテストをしました。
① USBの供給電圧5.0VをVBUS（40ピン）から供給した場合の電流を測定する。 
② 単3電池2本相当の3.0VをSBDを経由して VSYS（39ピン）に供給した場合の電流を測定する。
③ 電池電圧が下がっていくと何Vまで動作するか。

![写真R-Pico電圧５V.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/6bdfec50-04cb-07a6-a2e8-57d084e9c6a9.jpeg)
① VBUS（40ピン）に5.0V

![写真R-Pico電圧3V.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/666e4c6e-19fb-93bc-294c-43c2a72ec123.jpeg)
② VSYS（39ピン）にSBD経由で3.0Vを供給。VSYSは2.75V

![写真R-Pico電圧1V8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/6d536bf2-7b49-a781-a61e-e679d259c0f4.jpeg)
③ VSYS（39ピン）にSBD経由で1.8Vを供給。VSYSは1.51V
| 供給電圧 (a)|VSYS電圧 (b)|降下電圧 (a-b)|電流 (d)|電力 (a*d)|
|:-:|:-:|:-:|:-:|:-:|
|5.0V|   ||25mA|125mW|
|3.0V|2.75V|0.25V|39mA|117mW|
|1.8V|1.51V|0.29V|91mA|163.8mW|

・VSYSの入力電圧の仕様は1.8V~5.5Vですが、実際には少し余裕があるようです。
・SBDの降下電圧は、電流や温度によって変化します。

![SBM245L-VF-IF特性曲線.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/233d20ed-13f1-fae9-c58c-d5b94da8959f.jpeg)

# ６. ラズパイPicoを電池で動かす（MOSFET使用時）
![ラズパイPico-VSYS-FET.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/3f9791a4-072c-3dfd-e33a-d9e41dedc7e7.jpeg)
USBコネクタ接続時（VBUS=5V）の電池への逆流防止対策として図のようにPチャネルMOSFETを使用すると、電圧降下はほとんど無いので計算上は電池電圧が0.9V に下がるまで動作します。
　　　0.9(V) × 2 - 0 = 1.8 (V) 
エレホビカさんのブログでMOSFETの選び方（下記）や、DとSが通常の使い方と逆になっている理由が説明されているのでご覧ください。

:::note info
PチャネルMOSFETの選定基準
① ON抵抗が充分に小さい(0.1Ω未満) 
② 電流容量に余裕のあるもの (3A以上)
③ ゲートスレッショルド電圧はバッテリーの電圧で完全にONにする必要があるためスレッショルド電圧の低いもの (2.5V以下) 
非SMD部品で適当なものが見つからずSMD部品のIRLML6401にしましたとのこと。
:::
秋月電子通商にはIRLML6401が無くIRLML6402が販売されていて、特性値は6401に近いので6402でもいいかなと思い試してみました。ブレッドボードに取り付けるためにSOT-23変換基板を使用しました。
![IRLML6402とピッチ変換基板.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/f6fc62fe-7c8b-a0ea-86dd-0247879ed7c7.jpeg)

|IRLML6401|min| |max|
|:-:|:-:|:-:|:-:|
|RDS(on) (@4.5V) | | |0.050Ω|
|ID (@25°C)| | |-4.3A|
|VGS(th)|-0.40V|-0.55V|-0.95V|

|IRLML6402|min| |max|
|:-:|:-:|:-:|:-:|
|RDS(on) (@4.5V) | | |0.065Ω|
|ID (@25°C)| | |-3.7A|
|VGS(th)|-0.40V|-0.55V|-1.2V|

# ７. ［実験］ラズパイPicoの動作電圧のテスト（MOSFET使用時）

テスト機材はSBD使用時と同様、ラズパイPicoで0.96インチOLEDを表示するという構成です。電源回りの接続は下図のようになりますが、実際には電池の代わりに電源装置（実験用電源）を使用しました。

![ラズパイPico-VSYS-FET-電池.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/de0b46f2-3e70-edba-8ef2-9b450edd7e0c.jpeg)

以下のテストをしました。

④ 単3電池2本相当の3.0Vを、MOSFET経由で VSYS（39ピン）に供給する。USBコネクタやVBUSには電源を接続しない。2秒毎にLEDを点滅し点灯時／消灯時の時の電流を測定する。

⑤ VSYS（39ピン）に単3電池2本を接続した場合、電池電圧が下がっていくと何Vまで動作するか？　また、その時の電流を測定する。

**結果 ④⑤**
| 供給電圧 [a]|VSYS（39ピン）電圧|電流（LED消灯時）|電流（点灯時）[b]|電力 [a*b]|
|:-:|:-:|:-:|:-:|:-:|
|3.00V|2.99V|33mA|36mA|108mW|
|1.80V|1.77V|70mA|75mA|135mW|
|1.53V|1.47V|87mA|92mA|141mW|

![写真R-Pico+IRLML6402②.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/02b27272-6172-c4b9-eada-41564bde123a.jpeg)

電源装置を例えば1.53Vに設定しても負荷に接続すると1.52Vと表示されました。また、VSYSの電圧測定はテスターを使用し、電源装置の電圧表示と同一計器ではないため計器間の誤差があるかもしれません。

# ８. ラズパイPicoに 二次電池と充電回路を接続

下図は、Raspberry Pi Pico にリチウム電池等の二次電池と充電器を接続する方法（概略）を示したものです。エレホビカさんのブログにリチウム電池と充電モジュールを使用した具体的な回路図と分かり易い説明があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/2a397ffa-3710-8663-0981-4827552b028e.png)

# ９．電池の電圧検出
ラズパイPicoには内蔵のA/DコンバータでVSYSの電圧を検出する回路（GPIO29をADC3として使用）があります。200KΩと100KΩで1/3に分圧した回路なのでADCで入力して変換した電圧値の3倍が電池電圧です。

![ラズパイPico電源回路.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/9a5865dd-ac35-0920-abe1-b75edea5f8ed.jpeg)
![ラズパイPico-VSYS電圧検出回路.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/71de5cb2-20cd-4a4a-ca6b-8fbc9b2d4e45.jpeg)
［訳］ADC GPIO ピンには VDDIO へのダイオードがあります (他の GPIO にはありません)。FET は、3V3 電源がオフ (VSYS は存在しても3V3_EN が Low) のとき、ADC3 ピンのダイオードを介して 3V3 ネットへのリークを停止します。

**［参考］** imo Lab.さんの下記サイトによると・・・

https://garchiving.com/how-to-use-analogread-with-pico/

:::note info
■ADC分解能は12bitで、基準電圧は何も弄らなければ3.3V。
■デフォルトの分解能は10bitのようで、12bitで利用するには
　analogReadResolution(12);
 と設定する必要がある。
:::
とのことです。この情報を参考に電池の電圧（=VSYSの電圧）をOLEDに表示するようにしてみました。

![ラズパイPico＋OLED＋FET+電池の回路図２.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/26d37c27-d899-e89b-7c4c-777f0499aad3.jpeg)

![ラズパイPico＋OLED＋電池の実体配線図.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/8be32aa4-a036-52c4-5172-a9f88236ad38.jpeg)

■ I2Cのピン割り当てのデフォルト設定は pins_arduino.h で定義されています。以前は
```C++
// Wire
#define PIN_WIRE_SDA  (6u) // GPIO6 Picoの9ピン
#define PIN_WIRE_SCL  (7u) // GPIO7 Picoの10ピン
```
でしたが RP2040 ライブラリをアップデート (2.2.0 ⇒ 3.4.1) したら下記のように変更されてました。
```C++
// Wire
#define PIN_WIRE_SDA  (4u) // GPIO4 Picoの6ピン
#define PIN_WIRE_SCL  (5u) // GPIO5 Picoの7ピン
```
■ 実体配線図では電池とスイッチが別になってますが、実際には秋月で買ったフタとスイッチ付きの電池ケースを使用しました。写真にはスイッチは写ってません。

![ラズパイPico-VSYS-FET-電池実物.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834831/16c5ad17-ca94-074a-b6f8-b60269f33f82.jpeg)
電池ケースのフタは外してます。

**■ テストプログラム（スケッチ）**
処理内容はコメントを見て頂くとわかるかと思いますが簡単に説明します。
①OLEDにテキストを表示する。
②2秒毎にLEDを点灯／消灯する。
③LEDの点灯時と消灯時にVSYS電圧を測定しシリアルモニタとOLEDに表示する。
　また、GPIO24 をチェックしてUSB接続の有無も表示する。

電池のみで動作しているときは「USB: OFF」と表示し、電池を接続したままUSBコネクタを挿すと「USB: ON」、抜くと「USB: OFF」と表示されることを確認しました。

```C++
// VSYS電圧とUSB接続の有無をシリアルモニタとOLEDに表示する

#include <Wire.h>             // I2C
#include <Adafruit_GFX.h>     // グラフィックのコア・ライブラリ
#include <Adafruit_SSD1306.h> // OLED ライブラリ
Adafruit_SSD1306 OLED(128, 64, &Wire, -1); 
    // 4つ目の引数はRESETピン： -1はArduinoのRESETピンと共有
uint16_t raw;
float    v, vsys;
//-----------------------------------------------------------------
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);    // 内蔵LEDポートを出力に設定
  digitalWrite(LED_BUILTIN, HIGH); // 内蔵LEDを点灯
  Wire.begin();                    // I2Cを初期化
  OLED.begin(SSD1306_SWITCHCAPVCC, 0x3C); // 内部チャージ回路をON 0x78 ==> 0x3C
  OLED.clearDisplay();
  OLED.display();
  OLED.setTextSize(1);             // フォントサイズを1～で指定。
  OLED.setTextColor(WHITE);        // フォント色

  OLED.setCursor(0, 0);            // テキスト表示する座標
  OLED.print("Raspberry Pi Pico"); // テキスト
  OLED.setCursor(0, 8);
  OLED.print("OLED Display");
  OLED.setCursor(10, 16);
  OLED.print("128 x 64");
  OLED.display();                  // テキストを表示
  delay(2000);

  Serial.begin(9600);
  analogReadResolution(12);        //
  pinMode(24, INPUT);              // GPIO24 USB接続の有無
}
//-----------------------------------------------------
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // 内蔵LEDを点灯
  delay(1000);
  disp_VSYS(); // VSYS電圧を測定しシリアルモニタとOLEDに表示
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);    // 内蔵LEDを消灯
  delay(1000);
  disp_VSYS(); // VSYS電圧を測定しシリアルモニタとOLEDに表示
  delay(1000);
}
//-----------------------------------------------------
void disp_VSYS() {       // VSYS電圧と、USB接続の有無を表示
  raw = analogRead(29);  // ADC3 (GPIO29) : VSYS 電圧
  v = raw * 3.3 / 4095;  // 基準電圧=3.3V, ADC分解能＝12bit
  vsys = v * 3;          // VSYS測定回路は抵抗で1/3に分割されているので3倍する
 
  Serial.print("raw= ");     Serial.print(raw);
  Serial.print(", v= ");     Serial.print(v);
  Serial.print("V, vsys= "); Serial.print(vsys); Serial.println("V");

  OLED.clearDisplay();   // OLED 表示バッファを全てクリア
  OLED.setCursor(0, 32); OLED.print("raw  = ");  OLED.print(raw);
  OLED.setCursor(0, 40); OLED.print("v    = ");  OLED.print(v);    OLED.print("V");
  OLED.setCursor(0, 48); OLED.print("vsys = ");  OLED.print(vsys); OLED.print("V");

  if (digitalRead(24) == 1) {
    OLED.setCursor(0, 56);  OLED.print("USB: ON");  // USB電源接続あり
  } else {
    OLED.setCursor(0, 56);  OLED.print("USB: OFF"); // USB電源接続なし
  }
  OLED.display();        // テキストを表示
}
```
# 【関連記事】

https://qiita.com/totuto/items/0268e0e73caeb0d545d3

https://qiita.com/totuto/items/3e4bf52189515015cb90

https://qiita.com/totuto/items/6a3ab3c5f888d49739b1

https://qiita.com/totuto/items/2a8db63abd1d3c82880f

https://qiita.com/totuto/items/81944426dc81ab4b7e57

https://qiita.com/totuto/items/d3bc435d3d2f545c1c02