【複雑怪奇】マイコンボードの電源供給

# はじめに
先日、このようなツイートが私のタイムラインに流れてきました。電源OFF時に何かしらの現象が発生。高価なマイコンボードを焼いてしまったようです。

https://twitter.com/bbee7358/status/1664257509627158528?s=20

多くの有識者の方から考察がなされており、勉強になるなぁと感じて追いかけていました。
私の経験上でもマイコンボードの電源供給では苦労したポイントがあったので、今回の現象とは違いますが、せっかくなので共有してみようかと思い今回の記事を書きました。

# 市販のマイコンボードへの電源の問題
市販のマイコンボードは様々な使い方に対応するべく、様々な電源供給が可能になっています。主に以下の3種類が挙げられるでしょう。
- USB電源
- 内部のレギュレータ電源
- 外部のレギュレータ/DC-DCで制御された電源

これらを単独で用いれば問題は起きないのですが、先に上げたツイートの例のように多少複雑なシステムを構成すると、**複数の電源が様々なタイミングで入力され、動作不安定、PCと接続不能、最悪焼損などの問題が発生**する可能性があります。

## USB電源と他の電源との衝突
ラジコン用のモータやサーボなど、5Vより高い電源以外を使う場合、Arduinoの内部電源をモータ用の電源と共通化する構成がシンプルでしょう（電源構成①）。
![電源1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/4ea8db4b-214c-e4af-ad24-c27ba8bc0c62.png)
また、プロダクトによってはマイコンボード内のレギュレータでは電流容量不足になるので、外部にDCDCを別途採用する場合もあるでしょう（電源構成②）。
![電源2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/ee06b1ee-0b55-7f86-b50a-fc523935c65d.png)

### ケース1 モータ電源をONしながらPCに接続して衝突
この電源構成でバッテリ側電源をONしたままUSBを接続(ソフトの書き換えやシリアルモニタなど）したらどうなるでしょうか？

![電源_X1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/36c40c76-cf6e-145c-1af1-5b83fb40c629.png)
![電源_X2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/cd47e769-88c8-bce5-9b29-a563e8b6a293.png)
マイコンボードにUSBを接続すると電源が入ることからも分かるとおり、PCからはUSBの5Vが供給されいます。一方、元々電源も入っているので、マイコンボード内のレギュレータ出力や外部のDC-DCコンバータも5Vの電圧を出力しています。
同じ場所に2つの電源が供給された場合、電源間に存在する僅かな電圧差により大きな電流が流れてしまいます。なので、基本的に**同じ線に複数の電源を接続してはいけません**。

### ケース2 モータ電源をOFFしながらPCに接続してオーバーロード
また、電源構成②でバッテリがOFF時には衝突は起きないかわりオーバーロードが懸念されます。
一般にPCのUSB電源は0.5A程度しか供給できないので、5V系に繋がっている負荷が大きい場合は過負荷になってしまうからです。
![電源_X3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/8d072674-2bef-a8a9-3129-66f873b00244.png)

大抵の場合、リセッタブルヒューズによる保護が働いたり、PC側で問題のある負荷だと判定されてUSB電源だけカットされるはずですが、場合によっては**PCのシャットダウン。運が悪いとUSBポートが破壊**されることもありえます。

# 対策
USBを差すときはマイコンボード取り外して、単体で書き換えれば問題は起きませんが、それではスマートでないですし、USB-UARTでログも取れないので別の対策を考えます。
（なお、USBから電源供給されないよう、USBケーブルの5V線やパターンをカットする方法もあります。ただ、システムの電源をONしないと書き換えができなくなるのは個人的には避けたいです。なぜなら、マイコン書き換え中に電源の入っているモータ等が暴走する可能性を払拭できないからです。）

## 要件分析
まず、入力される電源(バッテリ、USB)に対して、各電源系統がどの電源を使用すべきかを表にまとめます。
| バッテリ | USB |モータ系 | 外部5V   | 内部5V   | 内部3.3V | 
| -------- | --- | -------- | -------- | -------- | -------- | 
| ✕       | ✕  | OFF      | OFF      | OFF      | OFF      | 
| ✕       | ◯  | OFF      | OFF      | USB      | USB      | 
| ◯       | ✕  | バッテリ | バッテリ | バッテリ | バッテリ | 
| ◯       | ◯  |  バッテリ | バッテリ | バッテリ | バッテリ | 

この表から分かるとおり、USBからはマイコン側だけに接続&バッテリ使用時はUSB電源を繋げない。という要件になります。

## 実装

### ダイオード
このような都合のよい動きを実現する部品としてはダイオードがあります。
ダイオードは見た目通り矢印の方向にだけ電流を通す特性があります。

<img width="240" alt="ダイオード" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/d55d5ae8-c8a7-2b54-dbf4-176b0423138f.png">

このダイオードを下図のように組み合わせると、電圧が高い方の電源のみが選択される回路になります。これを**ダイオードOR回路**といいます。
![D-OR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/2d0e11f0-9f9b-f622-8ab2-0128c62c360c.png)

### 設計
#### 電源構成①の場合
USBでPCから供給される5Vに対してダイオードORを適応すると、先の表を満たすような電源の切り替えを自動的に行うことができます。

![電源_cm1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/2d2fc502-6316-1875-5983-ecef417325e4.png)
#### 電源構成②の場合
DC-DCが生成する5V電源とUSBでPCから供給される5Vに対してダイオードORを適応すると、先の表を満たすような電源の切り替えを自動的に行うことができます。
このとき、バッテリ接続中にも関わらずUSBからの電源供給されることが無いよう、DC-DCの設定電圧を少し(0.5V程度)上げておくとより確実に切り替えが行えます。また実際にはダイオードでのドロップ電圧(-0.6V)が発生するので、それを補う効果もあります。
![ソリューション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/67e879ef-4324-6066-8d1a-b50803e38df4.png)

# しかし現実は・・・
この一見完璧な対策ですが、マイコンボードのUSB電源にダイオードが設定されていない場合、**マイコンボードの改造**が必要になります。
しかも、マイコンボードの種類によりダイオード有無が異なり、ひどい場合では同じシリーズのボードで互換性をうたいながら違う構成だったりするので、まさに**複雑怪奇な世界**です(タイトル回収)。

## セーフな例
幸い、いくつかのマイコンボードでは予めダイオードが設定されています。こちらはArduino Unoの例ですが、USB電源にPchMOSによるスイッチが設定されています。このスイッチは、USB電源が入力されるとONしますが、VINが入力されている間はOFFとなります(寄生ダイオードがいますが、ちゃんと逆流しない方向になっています）。また、5V端子が入力されている間も、レギュレータU1の内蔵ダイオードを経由して駆動できるのでOFFとなります。
ただし、**GPIOのVinや5Vピンにはダイオードが無いので別途設けてください**[^1]。
![スクリーンショット 2023-06-04 105514.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/4e0896c3-410a-224b-9cae-b3f328e8540e.png)

【追記】
脳内シミュレーションでは不安があるのでLTSpiceでシミュレーションしてみました。DCジャックのみのタイミング①、USBのみのタイミング②、オーバーラップしているタイミングの③。各タイミングで電源の電流値を測りました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/48dfd18f-c4fc-c08b-e615-29096692ba38.png)

![波形sim.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/bde18320-8689-5426-8bab-c23b6e6bb4c7.png)
USBから電流を持ち出しているのは②のUSBのみが供給されているタイミングになっています。
（回路に詳しい人はVpmosがタイミング②のみでONになっていることから理解できると思います）
|  電源端子 | タイミング① | タイミング② | タイミング③ | 
| --- | ---| ---| ---|
| DCジャック | 約33mA | 約0mA | 33mA |
| USB | 約0mA | 約33mA | 約0mA |


Arduino Microも同じようにPMOSのスイッチが付いています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/cdc4b589-bdf3-90d7-9afc-03b08380376c.png)
なお、UNOの回路もMicroの回路も、Vinの電圧次第な面があるのでご注意ください。(どうやらUNOは6.6V以下だと不味いらしい[^2]）。

Arduino NanoEveryは単純なダイオードのため、VINではなく5V入力で良さそうです(もちろん外付けダイオードが必要)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/e3bc65dd-f901-5437-e986-967d9543af2b.png)

## ダメな例
件のTenssy4の場合、一見PchMOSの寄生ダイオードが使えそうにも見えるのですが、常時ONなのでNGです。ただ、USB電源を切り離せるパターンがあるので、そこにダイオードを入れれば良さそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/3f1c55f8-ad5a-a765-a0f5-101c07134d4c.png)
AE-ATMEGA-328 MINI(秋月電子製ArduinoProMini互換ボード)の場合はJ1を介して直結されています。J1をカットしてしまい、ダイオードを入れてしまえばOKでしょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/74c4dda5-21ca-d831-e932-c4f0346f924c.png)

# まとめ
Arduinoを始めとした最近のマイコンボードは、回路の知識がなくても使えますが、少々複雑なプロジェクトになると思わぬトラブルに見舞われることがあります。
回路を自分で設計するレベルまでは不要だとしても、なんとなく分かるぐらいには勉強するしかなさそうです。
**不安であれば、シミュレーションするとか、壊れても問題ない環境でのテストをおすすめします。**

[^1]: [本当は怖いArduino電源回路](https://geekyfab.com/entry/arduino_power_circuit)
[^2]: [VIN power + USB Power Arduino Forum](https://forum.arduino.cc/t/vin-power-usb-power/397029)