前回、Arduino Uno R3用のバニラ味の「シールドボード」を発掘、これ幸いとI2C接続の2行x8文字のLCDを接続してみました。「問題なく」表示できたので今回は余勢を駆ってUno R4にも接続。同じく表示はできたのです。しかし電気的にヤバイことにようやく気づきました。ちゃんとよく確認しろよ、自分。
※「やっつけな日常」投稿順 Index はこちら
Arduino Uno R3/R4のI2C端子
Arduino Uno R3およびR4のピンソケット、デジタル端子がD0からD13まで並んでいる側の末尾にSDAとSCLなる端子が存在しており、これがI2C用の端子です。しかし、皆さまご存じのとおり、SDAとSCLの両端子は反対側のアナログ端子が並んでいる側のA4、A5端子でもあるのです。こんな感じ。
-
- SDA … A4
- SCL … A5
よって、アナログ端子としてA4かA5を使うならばSDAとSCLは通信には使えん。あるいはSDAとSCLをI2Cに使うならばA4とA5はアナログには使えんという排他的な関係にあります。
A4とA5をアナログ端子としても使う可能性があるため、SCLとSDAには外部のプルアップ抵抗は接続されていない、です(標準的なボード設定。)
前回作成シールドボードの問題点
上記のようにSCLとSDAに外部はプルアップ接続されていなかったので、前回は3.3V電源のLCDパネル上の3.3Vのプルアップ抵抗を活かしたまま、SCL、SDAと接続してしまいました。Arduino側はオープンドレインなので、ダイジョブだろ~という浅はかな判断っす。Arduino側のVIHのレベルが気になるものの、3.3Vまで振れてれば、多分動作するハズ、という目論見でした。
まあ、実際LCDに表示成功。
しかし今回、Uno R3に接続してあった「シールド」をUno R4に接続しなおしていて気付きました。
ArduinoのWire.h ライブラリを使っているとマイコン端子内蔵のプルアップ抵抗が生きてるのでないかい!
つまりI2Cバスに2本のプルアップ抵抗(電源電圧が異なる)が並列に両方活きている状態になっとるみたいです。内蔵のプルアップ抵抗(5Vにつりあげられてる)の値はハッキリとはしないものの10kΩから20kΩくらいはあるみたい。それに対してLCDボード上(3.3Vへプルアップ)は10kΩです。プルアップ2本で引っ張り合いになって3.3と5の中間になっている?その上、よくよく考えるとLCDコントローラ(3.3V電源)側の入力端子には当然保護ダイオードが含まれている筈。ダイオード君が頑張って3.3Vと5Vの引っ張り合いの結果のちょいと高い電圧を「壊れない」程度のところまで引っ張り下げてくれているみたい。結果、壊れもせず、通信できているのではないかと。それにVIH的には高い方向だし。
-
- 端子スペックを守るためにはやっぱりSCL、SDA信号にレベル変換をかませる方がいい
- まあ動いているみたいだから気にせず使う
レベル変換の素子を追加するのはメンドイし、電気的には気持ちが悪いし、どうしたもんか。。。
Arduino Uno R4との接続
上記のような電気的問題をハラミつつ、実機的には以下のようにArduino Uno R4 Minimaと接続しても表示は可能でした。
ただし、以下のように Wire.begin()する直前に一拍delay()を入れないと上手くっ表示してくれませなんだ(LCDパネルを制御するソースは前回のものと同じです。)それが上記の電気的問題に関係するのかは不明。なおdelay()する値は大きく1000としてますが、どのくらいの時間で動作OKなのかは確かめておりませぬ。
#include "Arduino.h" #include "AQM0802.h" AQM0802 lcd; void setup() { delay(1000); // Without this delay, LCD is not available. Wire.begin(); lcd.init(); } void loop() { lcd.displaySTR(LCD_HLINE, "Hello"); lcd.displaySTR(LCD_LLINE, "World."); }
このさい第3の方向を目指すかな。「3.3VのIO電圧のArduino端子のボードに接続」して使えば何の問題もないじゃん。やっつけだな。