基礎 · 読了まで18分

mAhとは?電池の容量、Wh、動作時間の計算をわかりやすく解説

mAhとは何か、Whとの違いは?Arduinoプロジェクトの電流を測り、電池の持続時間を計算し、単3、9V、18650、LiPoの各電池を比べます。

mAhとは何かを簡単に言うと、mAh(ミリアンペアアワー)は電池に蓄えられる電荷の量を表す容量の単位です。1 mAhは1ミリアンペアの電流が1時間流れることを意味します。つまり2000 mAhと表示された電池は、理論上は20 mAを消費する回路を100時間、200 mAを消費する回路を10時間動かせます。ただし、この数値だけでは不十分です。電池の電圧、流す電流、温度、電池と回路の間にあるレギュレーターによって、実際の動作時間は大きく変わります。

Arduino、ESP32、Raspberry Pi Picoで電池駆動のプロジェクトを作るとき、最初に浮かぶ疑問はいつも同じです。この電池で何時間、何日もつのか。このガイドでは、mAhとWhの意味、単3、9V、18650、LiPoの各電池の実際の容量、テスターとINA219でプロジェクトの消費電流を測る方法、式を使った動作時間の計算、電池の直列接続と並列接続、Cレートとは何か、そして9V電池がなぜ不向きなのかを、すべて実際の数値で説明します。

18650 Li-ion充電池
18650 Li-ionセル:公称電圧3.6〜3.7 V、実際の容量は2000〜3500 mAhで、エネルギーにすると約7〜13 Whです。

mAhとは?電池の容量の意味

電流はアンペア(A)、容量はアンペアアワー(Ah)で表します。小さな電池には、その1000分の1のミリアンペアアワーを使います。1 Ah = 1000 mAhです。物理的には電荷のことで、1 mAhは3.6クーロンに相当します。メーカーは、決められた放電電流で、決められた終止電圧になるまで放電して容量を測ります。電流が大きくなるほど電池の内部抵抗で失われる電圧が増え、化学反応が追いつかなくなり、終止電圧に早く達します。そのため同じ電池でも、大きな電流では取り出せるmAhが少なくなります。寒さも容量を下げ、アルカリ電池は0 °C以下で目に見えて弱くなります。下の表は、Energizerの単3(AA)アルカリ電池のデータ(0.8 Vまで、21 °C)をもとに、流す電流によって容量がどう変わるかを示しています。

連続電流容量の目安動作時間の目安
25 mA3000 mAh120時間
100 mA2500 mAh25時間
250 mA2000 mAh8時間
500 mA1500 mAh3時間

違いは歴然です。電流を20倍にすると、動作時間は20分の1ではなく40分の1になります。ですから、ラベルのmAhは最良の場合の値と考えてください。実際のプロジェクトでは、もう1つ損失があります。電池が完全に空になる前に回路が止まってしまうことです。Arduino Unoのレギュレーターは入力が7 Vを下回ると5 Vを保てなくなり、リチウム電池1セルは寿命を縮めないよう3.0〜3.3 Vあたりで使用をやめる必要があります。そのとき電池に残っているエネルギーは使われないままです。

Whとは?mAhとの違い

mAhがわかるのは電荷の量だけです。電池のエネルギーを求めるには電圧を掛ける必要があります。エネルギーの単位はワットアワー(Wh)で、式はWh = mAh × V / 1000です。たとえば3.7 V、3000 mAhの18650セルは3.7 × 3 = 11.1 Whを蓄えています。2500 mAhの単3電池は計算上1.5 × 2.5 = 3.75 Whですが、アルカリ電池の平均電圧は放電中に1.2〜1.3 Vまで下がるため、実際は3 Wh前後です。そのため、電圧の違う電池をmAhだけで比べると誤解を招きます。550 mAhの9V電池は2500 mAhの単3電池よりずっと小さく見えますが、約4 Whで、エネルギーは少し多いのです。プロジェクトでどちらが長くもつかは、間に入るレギュレーターの種類によって決まります。これは動作時間の計算の節で説明します。電力と電流の関係(P = V × I)をすばやく計算するには、オームの法則計算ツールを使えます。

モバイルバッテリーに書かれたmAhは、内部にある3.6〜3.7 Vのリチウムセルを基準にした値です。10000 mAhのモバイルバッテリーは約37 Whを蓄えていますが、USB出力で5 Vに昇圧するときに約15%が失われるため、5 Vで使えるのは6000〜6500 mAhだけです。航空会社がモバイルバッテリーの機内持ち込み制限をmAhではなく100 Whで決めているのも、このためです。

単3、9V、18650、LiPoの電池の比較表

電池公称電圧一般的な容量エネルギー無理なく流せる電流充電できる?
単4アルカリ電池1.5 V1000〜1200 mAh≈1.3 Wh低い(≈100 mA)できない
単3アルカリ電池1.5 V2000〜3000 mAh(電流による)≈3 Wh中程度(≈250 mAまでは効率的)できない
単3ニッケル水素電池1.2 V1900〜2500 mAh≈2.5 Wh高い(数A)できる
9Vアルカリ電池9 V400〜600 mAh≈4 Wh低い(≈50 mA)できない
CR2032コイン電池3 V≈235 mAh≈0.7 Whとても低い(µA〜数mA)できない
18650 Li-ionセル3.6〜3.7 V2000〜3500 mAh7〜13 Wh高い(セルにより5〜30 A)できる
1S LiPo(例:1000 mAh)3.7 V100〜5000 mAhのモデル≈3.7 WhラベルのCレートによるできる
10000 mAhのモバイルバッテリー5 V(USB)≈6000 mAh(5 V換算)≈37 Wh1〜3 Aできる

表を見るときは、次の点を覚えておいてください。重さあたりのエネルギーが最も多いのは、18650やLiPoのようなリチウムセルです。18650を1本で、単3アルカリ電池4本分の合計に近いエネルギーを、約半分の重さで蓄えられます。アルカリ電池は1年に数パーセントしか容量を失わないので、消費電流が小さく、長く置いておく機器に向いています。ただし、モーターやサーボのように大きな電流を必要とする負荷では、電圧がすぐに落ち込みます。充電式のニッケル水素電池は1.2 Vと電圧が低いものの、大きな電流も楽に流せます。低自己放電(LSD)タイプなら何か月も充電された状態を保ちます。CR2032コイン電池は、マイクロアンペアのレベルで動く時計モジュールやスリープ中のセンサー専用です。Wi-Fiに接続するESP32を動かすことはできません。

単3電池
単3電池:アルカリタイプは1.5 Vで2000〜3000 mAh、充電式のニッケル水素タイプは1.2 Vで1900〜2500 mAh。容量は流す電流によって大きく変わります。

9V電池はなぜ不向きなのか?

四角い9V電池は、スナップ端子付きのケーブルをArduinoのDCジャックに簡単に挿せるので、スターターキットによく入っています。しかし、電池で動かすArduinoプロジェクトには最も不向きな選択肢の1つです。中に小さなセルが6個直列に入っているため、容量はわずか400〜600 mAhです。Energizerのデータでは、9Vアルカリ電池を4.8 Vまで放電した場合、10 mAで約600 mAh、25 mAで570 mAh、50 mAではわずか450 mAhです。一方、Arduino UnoのレギュレーターにはDCジャックで最低7 Vが必要です。負荷がかかると電池の電圧は数時間でこれを下回り、残りのエネルギーは使えません。そのため約50 mAを消費するUnoは、9V電池ではたいてい数時間、多くの場合4〜8時間しか動きません。

  • 容量が小さい:単3電池6本のパック(6×AA)の2000〜2500 mAhに対して、わずか400〜600 mAhです。同じ9 Vでも動作時間は4分の1以下になります。
  • 内部抵抗が大きい:サーボが動き始めたり、リレーが切り替わったりすると、電圧が一瞬で落ち込み、Arduinoがリセットされます。
  • レギュレーターでの損失:Unoのリニアレギュレーターは、9 Vと5 Vの差の4 Vを熱に変えます。50 mAでは、電池から取り出す0.45 Wのうち約0.2 Wがむだになります。
  • エネルギーが高くつく:Whあたりのコストは単3電池より明らかに高く、充電式のニッケル水素9V電池では容量がわずか170〜300 mAhまで下がります。
  • 向いている用途:煙感知器、テスター、数mAしか消費せず長時間待機している機器なら、9V電池でまったく問題ありません。Arduinoには、単3電池6本のパック、2Sの18650パック、モバイルバッテリーを選んでください。詳しくは「Arduinoを電池で動かす方法」で説明しています。

Arduinoプロジェクトの消費電流を測る

電池の持続時間を計算するには、まずプロジェクトがどれだけの電流を消費するかを知る必要があります。推測より測るほうが確実です。ボード自体の消費、電源LED、レギュレーターが、センサーより多くの電流を消費していることがよくあるからです。いちばん簡単なのは、テスターを電池と回路の間に直列に接続する方法です。スリープと起動を繰り返すプロジェクトでは、INA219のような電流センサーのほうがよい結果になります。短い電流のピークと本当の平均値をとらえられるからです。テスターのレンジや端子について詳しくは、「テスターの使い方」を参照してください。

  1. 回路の電源を切ります。赤のテスト棒をテスターのmA端子に、黒のテスト棒をCOM端子に挿します。電流が200 mAを超えそうなら、まず10A端子から始めてください。
  2. ダイヤルを直流電流(A⎓)に合わせます。オートレンジでなければ200 mAレンジにします。
  3. 電池のプラスのリード線を回路から外します。赤のテスト棒を電池のプラス端子に、黒のテスト棒を回路のプラス入力に当てます。こうすると、すべての電流がテスターの中を流れます。
  4. 回路を動かして値を読みます。サーボが動いているとき、Wi-Fiに接続しているとき、リレーが通電しているときもそれぞれ測り、状態ごとの電流を記録します。
  5. スリープ電流がマイクロアンペアの範囲なら、µAレンジに切り替えます。このレンジではボードが起動に必要な電流を得られないことがあります。起動中はテスト棒の間をジャンパーワイヤーでつないでおき、ボードがスリープに入ったら外してください。
  6. 測った電流を、それぞれの状態で過ごす時間とあわせて、下の平均電流の式に当てはめます。
電流を測るとき、テスターを電池の両端に直接(並列に)当ててはいけません。mA端子に挿したテスターはほとんどショートと同じで、ヒューズが切れ、リチウム電池では危険なほど大きな電流が流れます。また、テスター内部のシャント抵抗によって、mAレンジでは数百ミリボルトの電圧降下が生じることがあります。Wi-Fi接続中に電流が250 mAまで跳ね上がるESP32は、これが原因でリセットすることがあります。そのような場合は10A端子を使ってください。
ボードまたはモジュール一般的な電流メモ
Arduino Uno R345〜50 mAスリープモードでも30 mA前後(USBチップ、レギュレーター、LED)
Arduino Nano(CH340)≈20 mA電源LEDが数mAを消費
Arduino Pro Mini 3.3 V / 8 MHz数mALEDとレギュレーターを外せばスリープ中はµAレベル
ESP32 DevKit、Wi-Fiオフ40〜70 mACPUの周波数による
ESP32 DevKit、Wi-Fi接続中平均80〜130 mA送信中は240 mA以上のピーク
ESP32ディープスリープ(モジュール単体)≈10 µA開発ボードではたいてい数mA
Raspberry Pi Pico(MicroPython)20〜25 mAPico WでWi-Fiをオンにすると目に見えて増える
LED(220 Ω、5 V)10〜15 mA明るさによる
16x2 I2C LCD20〜30 mA大半はバックライト
0.96インチOLED(SSD1306)10〜25 mA点灯しているピクセル数による
SG90サーボ停止中5〜10 mA、動作中100〜250 mA拘束時は0.5 A以上
HC-SR04距離センサー≈15 mA測定中
5 Vリレーモジュール(通電中)70〜80 mAコイルに通電している間ずっと
NEO-6M GPS40〜50 mA衛星を探している間

INA219で電流と使ったmAhを測る

INA219は、I2Cで動く小さな電流・電圧センサーモジュールです。基板上の0.1 Ωのシャント抵抗にかかる電圧を12ビットの分解能で測り、26 Vまでの回路で約±3.2 Aまでの電流を約0.1 mAの分解能で読み取ります。I2Cアドレスの初期値は0x40です。モジュールは測定する回路のプラス側のラインに直列に接続します。電池のプラスをVin+に、Vin−を回路のプラス入力につなぎます。測定するArduinoはUSBから電源をとり、そのGNDを測定する回路のGNDと接続します。必要なのは、Arduino IDEのライブラリマネージャからAdafruit INA219ライブラリをインストールすることだけです。INA219ではマイクロアンペアレベルのスリープ電流は測れません。それはテスターのµAレンジで測ってください。

INA219のピンArduino UnoESP32Raspberry Pi Pico
VCC5V3V33V3(OUT)
GNDGNDGNDGND
SDAA4GPIO 21GP4
SCLA5GPIO 22GP5
Vin+電池のプラス(+)電池のプラス(+)電池のプラス(+)
Vin−測定する回路のプラス入力測定する回路のプラス入力測定する回路のプラス入力
電池のマイナス(−)GND(共通)GND(共通)GND(共通)
C++ (Arduino IDE)
1// INA219 ile akım, harcanan mAh ve pil ömrü / current, used mAh and battery life with INA219
2#include <Wire.h>
3#include <Adafruit_INA219.h>
4
5Adafruit_INA219 ina219;                    // varsayılan adres 0x40 / default address 0x40
6
7const float CAPACITY_MAH = 2500.0;         // pilin etiket kapasitesi / rated battery capacity
8const float USABLE = 0.85;                 // kullanılabilir oran / usable share
9
10float usedMah = 0;                         // toplam harcanan yük / total charge used
11float secMaMs = 0;                         // son saniyenin mA x ms toplamı / mA x ms of the last second
12unsigned long startMs, lastSample, lastPrint;
13
14void setup() {
15  Serial.begin(9600);
16  if (!ina219.begin()) {
17    Serial.println(F("INA219 bulunamadi / INA219 not found"));
18    while (true) {}
19  }
20  ina219.setCalibration_32V_1A();          // 1 A'e kadar ince ölçüm / finer steps up to 1 A
21  startMs = lastSample = lastPrint = millis();
22}
23
24void loop() {
25  unsigned long now = millis();
26
27  if (now - lastSample >= 10) {            // 10 ms'de bir örnek / one sample every 10 ms
28    float mA = ina219.getCurrent_mA();
29    secMaMs += mA * (now - lastSample);    // akım x süre / current x time
30    lastSample = now;
31  }
32
33  if (now - lastPrint >= 1000) {           // saniyede bir rapor / report once a second
34    lastPrint = now;
35    usedMah += secMaMs / 3600000.0;        // mA x ms -> mAh
36    secMaMs = 0;
37    float avgMa = usedMah / ((now - startMs) / 3600000.0);   // ortalama akım / average current
38    float volts = ina219.getBusVoltage_V() + ina219.getShuntVoltage_mV() / 1000.0;   // pil gerilimi / battery voltage
39
40    Serial.print(F("Pil / Battery: "));
41    Serial.print(volts, 2);
42    Serial.print(F(" V | Ort / Avg: "));
43    Serial.print(avgMa, 1);
44    Serial.print(F(" mA | Harcanan / Used: "));
45    Serial.print(usedMah, 2);
46    Serial.print(F(" mAh"));
47    if (avgMa > 0.5) {
48      Serial.print(F(" | Sure / Runtime: "));
49      Serial.print(CAPACITY_MAH * USABLE / avgMa, 1);   // saat / hours
50      Serial.print(F(" h"));
51    }
52    Serial.println();
53  }
54}

このコードは10ミリ秒ごとに電流を読み取り、電流 × 時間を足し合わせて使ったmAhを求めます。こうすることで、Wi-Fiの送信やサーボの動きのような短い電流パルスも平均に含まれます。1秒に1回、電池の電圧、それまでの平均電流、使った容量、定格容量の85%をもとにした推定動作時間をシリアルモニタに表示します。少なくとも1回分の動作サイクル全体、たとえばスリープと起動の1サイクルが収まる時間は動かしたままにしてください。1 Aを超える負荷ではsetCalibration_32V_2A()を使います。同じコードはESP32でもGPIO 21と22でそのまま動きます。シリアルモニタの使い方は「Arduinoのシリアルモニタ」を参照してください。

動作時間の計算:容量 / 電流 × 効率

平均電流がわかれば、基本の式は簡単です。動作時間(時間) = 容量(mAh) / 平均電流(mA) × 効率。効率の係数は0.85から始めるのがよいでしょう。この係数は、大電流や低温で失われる容量、電池が完全に空になる前に回路が止まること、電池の劣化を考慮したものです。この式が使えるのは、電池と回路の間にレギュレーターがない場合か、リニアレギュレーター(Unoの5 Vレギュレーター、AMS1117、7805)の場合です。リニアレギュレーターでは入力電流と出力電流が等しく、電圧の差は熱になるからです。昇圧(ブースト)や降圧(バック)モジュールのようなスイッチング方式のコンバーターを使う場合は、エネルギーで計算してください。動作時間(時間) = 電池のエネルギー(Wh) × 効率 / 負荷の電力(W)。この場合の効率は、コンバーターの85〜90%の効率に、電池の使える割合を掛けたもので、0.75〜0.8とするのが現実的です。

シナリオ平均電流または電力電池計算動作時間の目安
Uno+センサー、6×AAパックをDCジャックへ55 mA単3アルカリ電池、2500 mAh2500 / 55 × 0.85≈39時間
同じUnoを9Vアルカリ電池で55 mA9V、≈450 mAh450 / 55 × 0.85≈7時間(実際はもっと短い)
Nano+DHT11+OLED、3×AAを5Vピンへ35 mA単3アルカリ電池、2500 mAh2500 / 35 × 0.85≈61時間
ESP32 DevKitで常時Wi-Fi、18650+5 V昇圧5 V × 110 mA = 0.55 W18650、3000 mAh(11.1 Wh)11.1 × 0.8 / 0.55≈16時間
PicoのVSYSに単3ニッケル水素電池3本(3×AA)≈0.1 W3 × 1.2 V × 2000 mAh = 7.2 Wh7.2 × 0.8 / 0.1≈58時間

スリープと起動を繰り返すプロジェクトでは、まず平均電流を求める必要があります。平均電流 = (起動中の電流 × 起動時間 + スリープ電流 × スリープ時間) / 合計時間。たとえば、10分ごとに5秒間起動して120 mAを消費し、残りの595秒は10 µA(0.01 mA)でスリープするESP32モジュール単体の平均は、(120 × 5 + 0.01 × 595) / 600 ≈ 1.01 mAです。3000 mAhの18650なら、3000 / 1.01 × 0.85 ≈ 2520時間、つまり約3.5か月になります。同じコードをスリープ中に5 mAを消費する開発ボードで動かすと、平均は5.96 mAに上がり、動作時間は約18日に縮みます。この計算を手でする代わりに、電池寿命計算ツールを使うこともできます。容量、起動中とスリープ中の電流、起動の間隔を入力するだけです。平均電流が0.1 mAを下回ると、電池の自己放電も決め手になります。Li-ionセルは1か月に容量の約2〜3%を失います。

ESP32:起動時間を測って電池の持続時間を見積もる

ESP32の消費電流は、動作モードによって数千倍も変わります。Espressifのデータシートによると、チップはWi-Fiで送信中に最大240 mA、受信中に約100 mA、Wi-Fiオフ(モデムスリープ)で20〜68 mA、ライトスリープで約0.8 mA、ディープスリープではわずか10 µAを消費します。そのため電池の持続時間を本当に決めるのは起動している時間です。Wi-Fiへの接続には1〜3秒かかることが多く、この数秒で使うエネルギーは何時間ものスリープより多くなります。下のコードは、起動するたびにボードが起動していた時間をRTCメモリに保存し、測った電流の値を使って平均電流と推定の電池持続時間を計算します。

C++ (Arduino IDE)
1// ESP32 derin uyku ve pil ömrü tahmini / ESP32 deep sleep and battery life estimate
2RTC_DATA_ATTR int bootCount = 0;               // derin uykuda silinmez / survives deep sleep
3RTC_DATA_ATTR unsigned long lastAwakeMs = 0;   // önceki uyanık süre / previous awake time
4
5const float ACTIVE_MA = 120.0;      // ölçtüğün uyanık akım / measured awake current
6const float SLEEP_MA = 0.01;        // ölçtüğün uyku akımı (10 µA) / measured sleep current (10 µA)
7const int SLEEP_S = 600;            // 10 dakika uyku / 10 minutes of sleep
8const float CAPACITY_MAH = 3000.0;  // 18650 kapasitesi / 18650 capacity
9const float USABLE = 0.85;          // kullanılabilir oran / usable share
10
11void setup() {
12  Serial.begin(115200);
13  bootCount++;
14
15  // Burada sensörü oku ve veriyi gönder / read the sensor and send the data here
16  delay(500);                       // örnek iş yükü / sample workload
17
18  if (lastAwakeMs > 0) {
19    float awakeS = lastAwakeMs / 1000.0;
20    float avgMa = (ACTIVE_MA * awakeS + SLEEP_MA * SLEEP_S) / (awakeS + SLEEP_S);
21    float days = CAPACITY_MAH * USABLE / avgMa / 24.0;
22    Serial.printf("Uyanis / Wake #%d, uyanik / awake: %.2f s\n", bootCount, awakeS);
23    Serial.printf("Ortalama / Average: %.3f mA, pil omru / battery life: %.0f gun / days\n", avgMa, days);
24  }
25
26  lastAwakeMs = millis();           // bu uyanışın süresi / duration of this wake
27  Serial.flush();
28  esp_sleep_enable_timer_wakeup((uint64_t)SLEEP_S * 1000000ULL);   // mikrosaniye / microseconds
29  esp_deep_sleep_start();           // loop() hiç çalışmaz / loop() never runs
30}
31
32void loop() {
33}

最初の起動では時間を保存するだけです。2回目以降の起動ごとに、前回の起動時間を使って平均電流と電池の持続日数を計算して表示します。ACTIVE_MAとSLEEP_MAは、自分のボードでテスターを使って測った値を入力してください。millis()は起動時のブートローダーの時間を数えないので、起動時間に0.1〜0.3秒の余裕を加えると、より現実的な結果になります。スリープモードと起動要因について詳しくは「ESP32のディープスリープ」を、電池駆動で起きることのある再起動の問題については「ESP32のブラウンアウトエラー」を参照してください。

電池の直列接続と並列接続

電池を直列に接続する(1本のプラスを次のマイナスにつなぐ)と、電圧は足し算になり、容量(mAh)は変わりません。1.5 V、2500 mAhの単3電池を4本直列にすると、6 V、2500 mAhになります。並列に接続する(プラス同士、マイナス同士をつなぐ)と、電圧は変わらず、容量が足し算になります。3000 mAhの18650を2本並列にすると、3.7 V、6000 mAhになります。どちらの場合も、合計エネルギー(Wh)はセルの数とともに増えます。リチウムパックでは、この構成をS(直列)とP(並列)の文字で表します。たとえば2S2Pは、並列にした2組を直列につないだ4セルのパックを意味します。

構成(3000 mAhの18650)電圧(公称 / 満充電)容量エネルギー主な用途
1S1P3.7 V / 4.2 V3000 mAh11.1 WhESP32、Pico、昇圧してArduino
1S2P3.7 V / 4.2 V6000 mAh22.2 Wh長時間動くESP32のセンサーステーション
2S1P7.4 V / 8.4 V3000 mAh22.2 WhArduinoのDCジャック、ロボットカー
2S2P7.4 V / 8.4 V6000 mAh44.4 Whモーター付きのロボット
3S1P11.1 V / 12.6 V3000 mAh33.3 Wh12 VのLEDテープ、降圧して5 V
  • 同じセルを使う:直列や並列のパックには、同じメーカー、同じ容量、同じ使用期間、同じ充電状態の電池を使います。弱いセルはほかより先に空になり、負担がかかります。
  • 並列にする前に電圧をそろえる:Li-ionセルを並列に接続する前に、セル間の電圧差は0.1 V以内にしてください。そうしないと、満充電のセルから空のセルへ、制御されない大きな電流が流れ込みます。
  • 直列のリチウムパックには保護が必要:2S以上のパックには、各セルを監視するバランス機能付きの保護基板(BMS)を使います。1セル用のTP4056モジュールでは直列パックは充電できません。
  • 充電式と使い切りの電池を混ぜない:アルカリ電池とニッケル水素電池を同じパックに入れないでください。電圧も内部抵抗も違います。
  • 並列接続は負荷を分け合う:1S2Pのパックでは各セルが電流の半分を受け持ちます。そのため並列パックは長くもつうえ、大電流でも発熱が少なくなります。

Cレートとは?

Cレートは、電池を容量に対してどれだけ速く放電または充電するかを表します。1Cは電池を1時間で空にする電流で、数値は容量と同じです。2000 mAhの電池なら、1C = 2 A、0.5C = 1 A、20C = 40 Aです。時間の計算も簡単で、2Cなら約30分、0.2Cなら5時間で空になります。ドローンやラジコン用のLiPoに書かれた25Cや50Cなどの値は、最大連続放電電流を示しています。1000 mAh 25CのLiPoは25 Aを流せます。18650セルでは、たいていアンペアで直接書かれています。3500 mAhの高容量セルは8〜10 A、2500〜3000 mAhのハイレートセルは15〜30 Aを連続で流せます。充電のルールはもっと厳しく、リチウムセルの標準的な充電電流は0.5C前後、最大でも1Cです。1 Aで充電するTP4056モジュールは2000 mAhの18650には適していますが、300 mAhの小さなLiPoには約3Cで負担をかけてしまいます。その場合はモジュールのRprog抵抗を交換して、充電電流を下げる必要があります。

Cレート1000 mAhのLiPo3000 mAhの18650時間の目安
0.2C200 mA600 mA5時間
0.5C500 mA1.5 A2時間
1C1 A3 A1時間
2C2 A6 A30分
10C10 A30 A(ハイレートセルのみ)6分

Raspberry Pi Picoで電池の容量を測る(MicroPython)

9900 mAhと書かれた18650セルは、ほぼ間違いなく偽物です。市販されている本物の18650で最も容量が大きいものは3500〜3600 mAh程度です。電池の本当の容量を知る唯一の方法は、既知の負荷で放電させ、時間とともに電流を足し合わせることです。Raspberry Pi Pico、負荷抵抗、MOSFETを使えば、まさにそれを行う簡単な容量テスターを作れます。PicoはMOSFETで負荷をつなぎ、分圧回路を通して電池の電圧を測り、I = V / Rで電流を計算し、電圧が終止電圧まで下がったら負荷を切り離します。分圧回路の値は分圧計算ツールで確認できます。MOSFETの配線について詳しくは「ArduinoでMOSFETを使う方法」を参照してください。

部品接続役割
電池のプラス(+)負荷抵抗の一方の端と、分圧回路の上側の抵抗へテストする電池
10 Ω、5 Wの負荷抵抗もう一方の端をMOSFETのドレインへ4.2 Vで約420 mAを流す
ロジックレベルのNチャネルMOSFET(例:IRLZ44N)ソース → GND、ゲート → 220 Ω → GP15、ゲートとGNDの間に100 kΩ負荷をオン・オフする
100 kΩ + 100 kΩの分圧回路電池のプラス → 100 kΩ → GP26 → 100 kΩ → GNDADC用に4.2 Vを2.1 Vまで下げる
電池のマイナス(−)PicoのGND共通グラウンド
Raspberry Pi PicoUSBでパソコンへ測定、記録、Thonnyへの出力
MicroPython
1from machine import ADC, Pin
2import time
3
4adc = ADC(26)                      # GP26: bölücünün orta noktası / divider midpoint
5load = Pin(15, Pin.OUT, value=0)   # GP15: MOSFET kapısı / MOSFET gate
6R_LOAD = 10.0                      # yük direnci, ohm (ölçüp yaz) / load resistor in ohms (measure it)
7DIV = 2.0                          # 100k + 100k bölücü / 100k + 100k divider
8CUTOFF = 3.0                       # Li-ion bitiş gerilimi / Li-ion end voltage
9CONV = 3.3 / 65535                 # ham değeri volta çevir / raw value to volts
10
11def battery_v():
12    total = 0
13    for _ in range(32):            # 32 ölçümün ortalaması / average of 32 readings
14        total += adc.read_u16()
15    return total / 32 * CONV * DIV
16
17mah = 0.0
18mwh = 0.0
19log = open("desarj.csv", "w")      # Pico'nun belleğine kaydedilir / saved to the Pico's flash
20log.write("dakika,volt,mA,mAh\n")
21load.value(1)                      # deşarjı başlat / start the discharge
22start = last = time.ticks_ms()
23
24while True:
25    time.sleep(30)
26    now = time.ticks_ms()
27    hours = time.ticks_diff(now, last) / 3600000
28    last = now
29    v = battery_v()                # yük altındaki gerilim / voltage under load
30    ma = v / R_LOAD * 1000         # I = V / R
31    mah += ma * hours
32    mwh += v * ma * hours
33    minutes = time.ticks_diff(now, start) / 60000
34    print("{:.0f} dk/min  {:.3f} V  {:.0f} mA  {:.0f} mAh  {:.2f} Wh".format(minutes, v, ma, mah, mwh / 1000))
35    log.write("{:.1f},{:.3f},{:.0f},{:.1f}\n".format(minutes, v, ma, mah))
36    log.flush()
37    if v <= CUTOFF:
38        load.value(0)              # yükü ayır, pili koru / disconnect the load, protect the cell
39        log.close()
40        print("Kapasite / Capacity: {:.0f} mAh, {:.2f} Wh".format(mah, mwh / 1000))
41        break

このコードは30秒ごとに負荷をかけた状態の電池電圧を測り、電流を計算し、使ったmAhとWhを足し合わせます。結果はThonnyのシェルに表示すると同時に、Picoのフラッシュにあるdesarj.csvファイル(desarjはトルコ語で「放電」)にも保存します。このファイルはあとでExcelで開いて、放電曲線を描けます(「ArduinoのデータをExcelに取り込む」)。10 Ωの負荷では、3000 mAhの18650のテストに約8〜9時間かかります。正確な結果を得るには、負荷抵抗をテスターで測ってR_LOADに入力し、電池の電圧をテスターの値と比べてDIVの係数を調整してください。単3ニッケル水素電池をテストするなら、CUTOFFを1.0 Vに、負荷抵抗を4.7 Ωに下げます。4.2 Vのとき負荷抵抗は約1.8 Wの熱を出します。5 W以上の抵抗を選び、燃えやすいものから離して置き、テスト中は目を離さないでください。PicoへのMicroPythonのインストール方法がまだわからない場合は、「Raspberry Pi Picoとは?」から始めてください。

電池の計算を活かしたプロジェクトのアイデア

  • 何か月も動く庭のセンサー:ESP32をディープスリープさせておき、1時間に1回土壌水分を測って、平均電流を1 mA未満にします。
  • 電池残量表示付きの電圧計:電池の電圧を測り、LCDにパーセントで表示します(「Arduinoで電圧計を作る」)。
  • ロボットカーに合ったパック:モーターの電流を測り、2Sの18650パックが何分もつかを計算します(「Arduinoロボットカーの作り方」)。
  • 消費電力ロガー:INA219の測定値をSDカードに書き込み、機器の1日のエネルギーの推移を記録します(「SDカードモジュール」)。
  • 18650の容量テストステーション:PicoのテスターにOLEDディスプレイを追加して、mAhをリアルタイムで表示します。
  • 電池で動く気象ステーション:10分ごとにDHT11のデータを送るESP32を、18650を1本だけで何か月も動かします。

よくある間違いと対処法

間違い結果対処法
電圧の違う電池をmAhだけで比べる電池選びを間違えるWhに換算する:mAh × V / 1000
ラベルの容量をすべて使えると考える動作時間が予想より15〜40%短い係数0.85を使い、大電流ではさらに下げる
ボード自体の消費を忘れるUnoはスリープ中でも30 mA前後を消費し、電池は何日ではなく何時間しかもたないPro Miniやモジュール単体を使い、電源LEDを外す
電流のピークを測らないWi-Fi接続時やサーボの動作時にリセット(ブラウンアウト)INA219で測り、電源に470 µFのコンデンサを追加する
スイッチング方式のコンバーターでmAhの式を使う見積もりが30〜50%ずれるエネルギー(Wh)と電力(W)で計算する
Arduinoを9V電池で動かす数時間で電池が切れ、リセットも起きる6×AA、2Sの18650パック、モバイルバッテリーを使う
Li-ionセルを3.0 V未満まで放電する容量が永久に減り、膨張のおそれもある保護回路付きセルか保護基板(BMS)、ソフトウェアでの終止電圧
非現実的なmAhが書かれた18650を買う容量は表示の3分の1程度容量テストをし、信頼できるメーカーを選ぶ
電池の持続時間を延ばす最も効果的な方法は次のとおりです。起動時間を短くする、プロセッサーをスリープさせる、電源LEDやUSBチップのないボードを選ぶ、リニアレギュレーターを自己消費電流が数マイクロアンペアのものか効率のよいコンバーターに替える、センサーにはピンやMOSFETを通して測定中だけ電源を供給する。ほとんどのプロジェクトでは、大きな電池を買うよりも、これらの対策のほうがはるかに効果があります。

これで、mAhとWhの違い、プロジェクトの電流の測り方、電池が何時間・何日もつかの計算方法がわかりました。次のステップとして、「Arduinoを電池で動かす方法」と「TP4056で18650を充電する」もご覧ください。BlueGraysアプリには、ESP32のディープスリープでの節電、LCDディスプレイ付きデジタル電圧計、Bluetooth操作のロボットカー、障害物回避ロボットなど、電池で動くプロジェクトが、ステップごとの回路図とコード付きでそろっています。

よくある質問

電池のmAhとはどういう意味ですか?

mAh(ミリアンペアアワー)は、電池に蓄えられる電荷の量を表す容量の単位です。1000 mAhの電池は、理論上は1000 mAを1時間、または100 mAを10時間供給できます。実際の動作時間は、流す電流、温度、回路が止まる電圧によって変わります。

mAhとWhの違いは何ですか?

mAhは電荷の量を、Whはエネルギーを表します。WhはmAh × V / 1000で計算するので、3.7 V、3000 mAhの電池は11.1 Whです。電圧の違う電池を比べるときは、Whのほうがずっと正確です。

mAhが大きい電池のほうがよいのですか?

同じ電圧・同じ種類の電池どうしなら、mAhが大きいほど動作時間は長くなります。ただし大きな電流を必要とする機器では、内部抵抗やCレートも重要です。9900 mAhのような非現実的な値が書かれた18650セルは、ほぼ間違いなく偽物です。

電池が何時間もつかはどう計算しますか?

動作時間(時間) = 容量(mAh) / 平均電流(mA) × 0.85の式を使います。たとえば2500 mAhの電池は、50 mAを消費する回路を約42時間動かせます。間に昇圧や降圧のコンバーターがある場合は、WhとWで計算してください。

Arduinoを9V電池で動かせますか?

短いテストなら動きますが、常設のプロジェクトにはおすすめしません。9Vアルカリ電池の容量はわずか400〜600 mAhで、Arduino Unoをたいてい数時間しか動かせません。サーボなどの負荷があると電圧が下がり、ボードがリセットします。単3電池6本のパック、2Sの18650パック、モバイルバッテリーのほうがはるかに長くもちます。

電池のCレートとは何ですか?

Cレートは、電池の容量に対する放電または充電の電流を表します。1Cは電池を1時間で空にする電流です。2000 mAhの電池なら、1C = 2 A、0.5C = 1 Aです。LiPo電池に書かれた25Cなどの値は、最大連続放電電流を示しています。

全プロジェクトを見る
DHT11で温度と湿度を測定
#55中級

DHT11で温度と湿度を測定

部屋の温度は何度で、空気は湿っているでしょうか、それとも乾燥しているでしょうか?DHT11センサーが温度と湿度を測定し、Arduinoが2行のLCDディスプレイに値を表示して、数秒ごとに更新します。センサーに異常があればエラーメッセージが表示されます。自分だけの小さな気象観測装置を作る第一歩です。

4.7(47)
73
ESP32でLEDを点滅
#103初級

ESP32でLEDを点滅

ESP32のGPIO出力の基本を学びます。デジタルピンからLEDを点灯・消灯させて、点滅させます。Arduino UNOの定番のLED点滅プロジェクトのESP32版です。Arduino環境で使う基本的な点滅コマンドは同じですが、ESP32のピン配置と3.3 VのGPIO電圧レベルはArduino UNOとは異なります。

4.7(37)
99
ESP32のディープスリープで節電(OLED + RTC RAMカウンター)
#135上級
プレミアム

ESP32のディープスリープで節電(OLED + RTC RAMカウンター)

ESP32のディープスリープモードは、CPUとほとんどの周辺機器を停止し、消費電流を約10 µAまで抑えます。電池で動くIoT機器に欠かせない機能です。このプロジェクトでは、タイマー(15秒)、外部ピン(EXT0、ボタンはGPIO 33)、タッチ(T0/GPIO 4)の3種類の復帰方法を使います。RTC_DATA_ATTRを付けた変数はディープスリープ中も保持され、起動回数、タイマーによる復帰回数、ボタンによる復帰回数を継続して記録できます。復帰するたびにSSD1306 OLEDディスプレイに復帰理由と回数を表示します。

4.3(10)
16
LCDディスプレイ付きデジタル電圧計
#56中級
プレミアム

LCDディスプレイ付きデジタル電圧計

自作の測定器で、電池や電源アダプターが出力する電圧を調べます。2つの抵抗で作る分圧回路が、高い電圧をボードで読み取れるレベルまで下げます。Arduinoが元の電圧を計算し、2行のLCDディスプレイにボルト単位で表示します。この回路では約55ボルトまでの直流電圧を測定できます。コンセントの商用電源には絶対に接続しないでください。

4.5(27)
36
L298Nで作るBluetooth操作の車
#80上級
プレミアム

L298Nで作るBluetooth操作の車

スマートフォンをリモコンにして、自作のロボットカーを操作できます。ArduinoはBluetoothモジュールを通じてスマートフォンのリモコンアプリから指令を受け取り、モータードライバーで車輪を回します。前進、後退、左右や斜めへの移動ができ、速度もスマートフォンから調整できます。停止ボタンを押すと、短いブレーキ動作でモーターがすぐに止まります。

5.0(38)
65
障害物回避ロボット
#81上級
プレミアム

障害物回避ロボット

自分で進む道を見つける、賢い車を作ってみませんか?障害物回避ロボットは、前面の超音波センサーで周囲を常に調べます。障害物を見つけると停止し、サーボモーターで左右を確認して、最も障害物の少ない方向を選んで進みます。自動運転の基礎を学ぶのにぴったりの入門プロジェクトです。

5.0(38)
49
ESP32温度データロガー(DHT22 + DS1307 RTC + microSD + OLED)
#144上級
プレミアム

ESP32温度データロガー(DHT22 + DS1307 RTC + microSD + OLED)

ESP32で日時付きの温度・湿度記録システムを作ります!DHT22で1分ごとに温度と湿度を読み取り、DS1307 RTCから取得した日時とともにmicroSDカードへCSV形式で記録します。OLEDには最新の温度を大きな文字で表示し、湿度のパーセント値、日時、総記録数も表示します。SDカードの/temp_log.csvファイルはExcel、Google Sheets、Pythonのpandasで開いて分析できます。温室の監視、家や部屋の温度管理、実験室のデータ収集、食品の保管環境や養蜂箱の監視に適しています。

4.7(7)
12