今から始める電子工作 ⑫ データを表示する その2 OLEDディスプレイ
前回の内蔵LEDマトリクスは、少し離れるとしっかりと文字も読めて利用しやすいです。けれど、温度とか湿度を表示するにはもっと文字数をたくさん一度に表示できる表示器が望ましいです。
マイコンには、I/Oポートのように、一つのピンに一つの機能を割り当てて利用するもの以外に、バスという形態があります。デバイスとやり取りをする信号は1本や2本、もしくは3本必要で、そのほかに電源があるので、最小3線で一組です。バスと呼びます。
- 信号1本 1-Wireバス
- 信号2本 I2Cバス
- 信号2本 USBバス
- 信号3本 SPIバス
いずれもシリアル・バスです。シリアス通信はD0、D1を利用するシリアル通信(RS-232C、UARTとも呼ばれる)がありますが、バス形式ではないです。
シリアルに対して、パラレル・バスというのが昔はよく使われましたが、廃れました。何しろ、接続するために20本や30本を束ねた太いケーブルを引き回すので、短距離の通信にしか使えません。
●OLEDグラフィック・ディスプレイ
最初は、I2Cバスを利用します。アイ・スクエアド・シーと呼びますが、アイ・ツー・シーでも意味は通じます。Arduino UNO 3には、一組だけ利用できたのですが、UNO 4では2組用意されています。バスなので、一組だけでも、複数のデバイスをつなげられます。
(デバイス;センサICや表示器などを指す)
①、①' は、同じものです。どちらを利用しても同じです。
②は、QWIICという名称がついていますが、Stemma QT/Qwiicとも呼ばれます。JST製の4ピン・コネクタです。ArduinoはMKRシリーズで4ピン・コネクタを使っていましたが、内部の配線は同じではありません。
①と②は、I2Cバスですが、物理的に異なるバスです。スケッチで利用するときも、別々のインスタンス名を使います。
I2Cのクロックはデフォルトが100kHzと低速です。なので、省電力なセンサなどの利用が多いです。グラフィック・ディスプレイではデータの転送量が多いので、小型の製品が大半です。少し大型になるとSPIバスが使われます。こちらはデフォルト10MHzです。
多くのデバイスで400kHzにしても動きます(データシートで確認のこと。スケッチでは1文追加)。1MHzやそれ以上に対応したデバイスもあります。
今回利用するOLEDディスプレイです。SparkFanの製品で、スイッチサイエンスから入手しました。I2Cバスなので、接続するのは4線ですが、このモデルは、4ピンのコネクタが2組用意されていて、ワンタッチで接続ができてしまいます。ひとつつないだら、次もコネクタ同士で接続していくというとても便利な仕組みです。
それぞれのデバイスは、ユニークなアドレスがふられているので、区別してアクセスできます。アドレスがぶつかる場合は、基板上のジャンパで変更できる製品もあります。
◆細長い形状(上) Qwiic - OLED ディスプレイ(0.91インチ/128x32) I2Cアドレス;0x3c、コントローラ;SSD1306
◆正方形に近い形状(下) Qwiic - OLED ディスプレイ(1.3インチ/128x64) I2Cアドレス;0x3d、コントローラ;SSD1306
どちらも動作電圧は3.3Vです。QWIICコネクタには3.3Vの電圧が出ています。
どちらもI2Cバスにプルアップ抵抗が挿入されています。基板上で切り離せるようになっています。I2Cバスはプルアップ抵抗が必須です。二つ以上のデバイスをつなぐときは、一つのデバイスだけのプルアップ抵抗を残し、ほかは使わないようにするのがセオリーです。ただ、二つぐらいなら、両方のプルアップ抵抗は残していても、抵抗値が合成されて低めの値になりますが、普通はそのままでも動作します。
●接続
コネクタをよく見ると、接点は中央より上面に並んでいます。基板上のコネクタとケーブルのコネクタを上寄りの接点同士を合わせるように差し込みます。軽くクリック感があります。抜くときは、コネクタの両端の突起物をつかんで引っ張ります。
今回は、マイコン・ボードとデバイスのボードの両方にコネクタが搭載されていますが、片方がピンヘッダの製品もあります。4ピン・コネクタとピンヘッダがセットになって接続ケーブルも市販されているので、それらを使うと接続はスムーズです。
下の写真は自作したものです。初期、信号線のケーブルの色は現在とは異なっていました。
I2Cは、UM10204がたぶん最新のマニュアルで、Inter integrated circuitの略にあるように、プリント基板上の近距離配線を想定しています。1mのケーブルにセンサをつけた製品も市販されていますが、スイッチサイエンスでは、5cmから20cmの接続ケーブルを用意しているので、入手します。
●OLEDグラフィック・ディスプレイはライブラリを利用
文字を表示する、円形の図形を表示するなど、グラフィック・ディスプレイは表示機能が多岐にわたります。メーカの用意したライブラリを使うと、たやすく描画ができます。
Arduino IDEの左にあるLibrary Managerツールをクリックして、「SparkFun OLED」を検索します。
見つかったSparkFun Qwiic OLED Adruino Library をインストールします。
サンプル例を読み込みます。
スケッチ例-> SparkFun Qwiic OLED Adruino Library -> Example-01_Hello
この事例は①のI2Cバスに接続したものなので修正します。
その前に、製品にインスタンスを合わせます。細長いほうは、次のように変更します。
//QwiicMicroOLED myOLED; //QwiicTransparentOLED myOLED; QwiicNarrowOLED myOLED; //Qwiic1in3OLED myOLED;
正方形に近いほうは、次のように変更します。
//QwiicMicroOLED myOLED; //QwiicTransparentOLED myOLED; //QwiicNarrowOLED myOLED; Qwiic1in3OLED myOLED;
setup()内の修正です。QWIICコネクタは二つ目のI2Cバスで、Wire1を明示します。2か所あります。
Wire1.begin(); // Initalize the OLED device and related graphics system if (myOLED.begin(Wire1) == false)
実行します。
(資料)
SparkFun Arduino UNO R4 WiFi Qwiic Kit Hookup Guide
Arduino UNO R4 WiFi Qwiic Connector
●アナログ電圧の測定値を表示する
A0端子を3.3Vへつないでいます。
スケッチです。
myOLED.rectangleFill()は、計測値を表示する領域を白色で塗りつぶしています。
#include <SparkFun_Qwiic_OLED.h> //QwiicNarrowOLED myOLED; Qwiic1in3OLED myOLED; float Vref = 4.5; float LSB = Vref / 16384; // V void setup(){ Serial.begin(115200); delay(1000); Serial.println("Running OLED Display analogData"); Wire1.begin(); // Initalize the OLED device and related graphics system if (myOLED.begin(Wire1) == false){ Serial.println("Device begin failed. Freezing..."); while (true) ; } Serial.println("Begin success"); // Fill a rectangle on the screen that has a 4 pixel board myOLED.rectangleFill(4, 4, myOLED.getWidth() - 8, myOLED.getHeight() - 8); String hello = "A0 voltage"; // top line message // Draw the text - color of black (0) myOLED.text(5, 5, hello, 0); myOLED.display(); analogReadResolution(14); } void loop(){ float analogData = analogRead(0) * LSB; String sensorValueSTR = String(analogData, DEC); char Buf[10]; sensorValueSTR.toCharArray(Buf, 7); Serial.println(analogData, 4); // uint8_t x0, uint8_t y0, uint8_t width, uint8_t height, uint8_t clr) myOLED.rectangleFill(4, 24, 50, 9, 1); myOLED.text(5, 25, Buf, 0); myOLED.display(); delay(1000); // Do nothing }
実行している様子です。
I2Cを利用するには、まずWire.hをincludeします。また、デバイスには固有のスレーブ・アドレスの指定が必要です。いずれも、Sparkfanのライブラリの中に隠れて表には出ていません。
Graphics Methodsのtextを読んでいると、表示するtextは、charではなくString型でもよいようなので、修正しました。
void loop(){ float analogData = analogRead(0) * LSB; String sensorValueSTR = String(analogData,4); Serial.println(analogData, 4); // uint8_t x0, uint8_t y0, uint8_t width, uint8_t height, uint8_t clr) myOLED.rectangleFill(4, 24, 50, 9, 1); myOLED.text(5, 25, sensorValueSTR, 0); myOLED.display(); delay(1000); // Do nothing }
(資料)