Arduino UNO R4でI2Cモジュールが使えない！？原因と解決事例紹介

# 0. 背景
Arduino UNO R4が発売して早一年とちょっと、皆様も少しずつ使われ始めたのではと思います。
今回はそんな新作のArduino UNO R4で起こったちょっとしたトラブルについて説明していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/2459bab3-a8f6-7e94-91ff-4a09f148c37c.png)
* 画像引用元:[スイッチサイエンスより](https://www.switch-science.com/products/9000?srsltid=AfmBOorlDUhe18y_yyKXZ4jhF3vCWpdAm03apAPH1PR6Fp0ar_oJ73-t)

※問題解決には以下のフォーラムがとても参考になりました。本記事の内容は以下のフォーラムを詳細に説明したものとなります。
https://forum.arduino.cc/t/problem-using-arduino-uno-r4-minima-and-i2c/1166142/8

# 1. トラブル内容
Arduino UNO R3で使用していた以下のモジュールをArduino UNO R4でも試そうとしていました。しかし、うまくいきませんでした。
※MPU-6050モジュールは姿勢角度センサーでロボットやドローン等によく使われます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/17035d8d-32e4-d42b-4ae0-1715c681c6e4.png)
画像引用元：[REES52 MPU-6050 使用 ３軸ジャイロスコープ・３軸加速度センサー モジュール amazon買い物リンク](https://www.amazon.co.jp/ps61003-MPU-6050-%E4%BD%BF%E7%94%A8-%EF%BC%93%E8%BB%B8%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AD%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97%E3%83%BB%EF%BC%93%E8%BB%B8%E5%8A%A0%E9%80%9F%E5%BA%A6%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC-%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB/dp/B008BOPN40)

## 1.1 Arduinoとモジュールの結線図
上記モジュールをArduino UNO R4と下図のように結線しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/f132368b-f993-6b42-6c59-446110d46dcc.png)
上図：[Wokwi](https://wokwi.com/projects/new/arduino-uno)で作成
### 接続ピンリスト
|Arduino UNO R4|MPU-6050モジュール|
|---|---|
|5V|VCC|
|GND|GND|
|A4|SDA|
|A5|SCL|

## 1.2 プログラム
結線が完了しましたのでプログラムを書いて動作を確認してみましょう。
今回はMPU-6050ライブラリのbasic_readings.inoを試してみます。
上記スケッチは該当ライブラリをインストールできていればファイル>スケッチ例>Adafruit MPU6050>basic_readingsにあります。
※インストールできていない場合はインストールしてから上記ディレクトリを参照してください。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/dc9b2a67-0337-b1a3-968b-3a237d147179.png)
## 1.3 動作結果
このプログラムを書いて動かしてみると下図のシリアルモニタより、フェイルしたとなってしまっています。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/de43eba2-6dfd-03ce-810d-10b8619b61a1.png)

# 2. 原因結論
ズバリ！！
**Arduino Uno R4のマイコンが原因で引き起こされていました。**
さらに言うと、マイコンのI2CのHIGH認識電圧が高く、マイコンがHIGHと認識できず、通信できないことが分かりました。

# 3. 原因　詳細
では上記問題の原因について詳細を述べていきます。
ちなみにArduino UNO R3で上記配線とプログラムで実施すると成功することが確認できました(下図)。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/8d40db8e-ef64-a5d0-4fa9-a61bd229c5cb.png)

## 3.1 R3とR4の差分について
上記の検証よりArduino UNOのバージョンが3から4に上がることで問題が発生したと考えられます。では、その原因となった差分は一体何か...見た目についてはArduinoのピン配列等、特に変わっていません。

しかし、H/Wの性能や回路図として変わった点が複数あります。(もちろんS/Wから見ても変わった点はあります）
今回はH/Wの変更点の一つのマイコンの変更について見ていきましょう。

R3ではMicrochip Technology社（旧Atmel社）の「ATMEGA328P-PU」というマイコンを使用していました。しかし、R4ではRenesas社の「R7FA4M1AB3CFM」を採用しています。今回はこのマイコンの差が原因となっていました。

## 3.2 I2Cの通信方式
２章で検証したMPU-6050との接続はI2Cを使用しています。このI2Cについて説明していきます。（既にご存じの方も多いと思いますが...）
I2Cはクロックに同期させてデータを通信する同期式のシリアル通信です。I2CではSCLとSDAの2線でデータをやり取りできます（電源線は別途必要です）。SCLがクロックを出して、SDAでデータ入出力を行います。また、通信する場合にはマスタとスレーブというように役割を付けて通信を行います。

ここで重要なのがSCL、SDAはいずれもオープンドレインということです。オープンドレインの説明は省略しますが、下図のようにプルアップ抵抗を挿入する必要があります。そしてこれらの抵抗の先の電圧がI2CのHIGHの電圧となります。
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/df880750-699b-a0eb-3361-a796ae2e391d.png)

* I2Cの詳細について>[ローム社　I2C](https://www.rohm.co.jp/electronics-basics/micon/mi_what7)
* オープンドレイン（オープンコレクタ）の詳細について>[オープンコレクタ、オープンドレインとは](https://detail-infomation.com/open-collector/)

## 3.3 マイコンのHIGH電圧について
I2CではHIGHとLOWの電圧を時間的に切り替えて通信しています。LOWは0Vですが、HIGHは前述のようにプルアップ抵抗先の電圧になります。

ここで、マイコンが何ＶになったらHIGHと認識するかついて調査していきます。
この値はマイコンやモジュールのDSや設計ドキュメントの電気的特性を見ればわかります。

下図はATMEGA328P-PU（Arduino UNO R3搭載マイコン）のDS抜粋（P.332 Table30-1）です。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/e97339b1-d1b0-cfdd-3e22-11810b2cbb78.png)
Arduino UNOの通常動作電圧5V(=VCC)より、HIGHと認識する最低電圧VIH(min)は0.6×5V=3Vです。

一方でR4に搭載のR7FA4M1AB3CFMでは、ユーザーマニュアルハードウェアより、下図に記載のVIH(min)は5V×0.8=4.0Vとなります。[^1]
※図の上にあるIICはSMBusモード選択時です。今回の場合はSMBusではないので下部にあるVIHが対象となります。
![051.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/16a2cc62-787a-593a-e49a-44445da4094e.png)

以上より、Arduino UNO R4ではI2Cの最低HIGH電圧が少し高くなっていることが分かりました。

## 3.4 回路のHIGH電圧
では、今回の回路のHIGH電圧はいくらでしょうか。回路図から読み解いていきましょう。

検証で使用した配線を回路図で示すと下図のようになっています。注意してほしいのがプルアップ抵抗とその先の電源はMPU-6050モジュール内で配線されています。また、プルアップ先の電源はモジュール内のレギュレータから生成されています。この電圧が3.3Vのため、この電圧がI2CのHIGH電圧となります。つまり…

R4（R7FA4M1AB3CFM）のHIGH認識最低電圧4.0V>I2CバスHIGH電圧3.3V

よって、マイコンがHIGHと認識できず、通信できないことが分かります。
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/dbc4f9bf-3cbf-916d-c286-3480c8570974.png)
* MPU-6050モジュールの回路図については多数情報がありますが↓の情報を参考にしました。
https://forum.arduino.cc/t/mpu6050-schematic/662491

# 4. 解決策　一例
上記トラブルの解決方法はいくつかありますが、一番安全な方法はレベルシフト回路を間に挟むことです。
すると、Arduino側では5VのHIGH-LOW、MPU-6050モジュール側では3.3VのHIGH-LOWとなります。
回路図としては下概略図のようになります。H/W専門の記事ではないので詳細な回路図についてはここでは省略します。
![09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/84ddad10-1bed-554b-407a-bda826dc96ca.png)

実際にレベルシフト回路を挿入してみて動作を確認してみた結果、無事正常動作を確認できました。
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/c46eddb6-2a13-3848-6429-92cbdcaf13e4.png)

* [レベルシフト回路について詳細](https://analogista.jp/level-shift/)

## 4.1 NG実施例
ここではダメな解決実施例を紹介します。
3章で説明した回路図より、プルアップ抵抗先を5Vにすればいいのではと思うかもしれません。しかし、MPU-6050は3.3Vで動作するICであり、その電圧よりも高い電圧を信号ラインに加えてしまうと壊れてしまいます。
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/3329211a-af57-ff4f-b3bb-579c696bfed5.png)

以下、MPU-6050のDS抜粋（p.14）
![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/4e528b20-c004-48b6-d10b-18ca168754ce.png)


# 5. まとめ
今回はArduinoのバージョン違い=マイコンの違いで、I2Cが動作できないトラブルが発生しました。記事の中でたくさん補足したい点がありましたが、S/Wから見ても電子工作初心者から見てもわかりやすいように表現いたしました。ツッコミについてはぜひコメントにお書きいただければと思います。
Arduino UNO R4については筆者個人的に開発を進めていますので、機会があれば新しく記事にしたいと思います。

# 参考資料
* [Problem? using Arduino Uno R4 Minima and I2C](https://forum.arduino.cc/t/problem-using-arduino-uno-r4-minima-and-i2c/1166142/8)
本記事の参考にさせていただきましたフォーラムです。
* [Arduino UNO R4公式情報](https://www.renesas.com/ja/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ra-partners/arduino-uno-r4)
* [R4に搭載マイコン公式情報(R7FA4M1AB3CFM)](https://www.renesas.com/ja/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ra4m1-32-bit-microcontrollers-48mhz-arm-cortex-m4-and-lcd-controller-and-cap-touch-hmi)
* [R3に搭載マイコンDS(ATMEGA328P-PU)](https://akizukidenshi.com/goodsaffix/atmega328.pdf)
* [ローム社　I2Cについて](https://www.rohm.co.jp/electronics-basics/micon/mi_what7)
* [オープンコレクタ、オープンドレインについて](https://detail-infomation.com/open-collector/)
* [レベルシフト回路について](https://analogista.jp/level-shift/)
* [MPU-6050モジュールの回路図参考フォーラム](https://forum.arduino.cc/t/mpu6050-schematic/662491)

[^1]: 元にさせていただきました[フォーラム](https://forum.arduino.cc/t/problem-using-arduino-uno-r4-minima-and-i2c/1166142/8)では3.5VがVIHと説明されていますが、DSをよく見ると注1の端子が対象となっています（下図）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/d509e6f4-f605-f81d-6547-f82804da6175.png)
Arduino UNO R4のI2CはP100とP101ピンを使用しているので下部にある5V*0.8=4.0VがHIGHの最低電圧となります。
下図Arduino UNO R4の回路図抜粋
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100334/a6a8aef8-1e28-3fd2-cfac-c52309ed706c.png)