ESP32入門 通信機能が標準搭載されたマイコン・ボード (6) I2CのWireライブラリを利用する①

 前回までに、Wi-Fiの基本的な働きを確認しました。今回は、通信の結果を表示するためのI2CインターフェースのLCDモジュール、また測定などのためのI2Cインターフェースのセンサの利用を検討します。

ESP32のWireの端子

 Wireライブラリを利用してESP32-WROOM-32DでI2Cインターフェースのデバイスを利用するためには、

  • GPIO21をSDA
  • GPIO22をSCL

の設定で利用します。

 この設定はデフォルトなので、I2Cのバス・ラインを接続すると、そのためWire.begin()の宣言時にI2Cバス・ラインの端子を特別に設定しなくて利用できます。
 同様に、I2Cのポートへのアクセスも、ボードのデフォルトの設定方法であれば標準Wireライブラリがそのまま利用できます。

今回使用するI2CインターフェースのLCDモジュール

 今回使用するI2CインターフェースのLCDモジュールは、16文字2行表示のAE-AQM1602と8文字2行表示のAE-AQM0802を想定しています。これらのLCDモジュールは、Arduinoのマイコン・ボードを例にして「AQMシリーズのI2C接続LCDキャラクタ・ディスプレイを使う(1)微妙なSCLクロック」からの連載で示してあります。

  https://www.denshi.club/make/2016/10/aqmi2clcd1.html

AE-AQM1602

 16文字2行を表示できるI2CインターフェースLCDモジュールAE-AQM1602を、次に示します。AQM1602のI/O端子はハーフ・ピッチ9ピンですが、AE-AQM1602は2.56mmピッチの変換基板で、ブレッドボードに挿し込んで利用できます。I2Cのバス・ラインをプルアップするための10kΩの抵抗が変換基板には内蔵されています。


 デフォルトでは、はんだのランドが切断されていて接続されていません。内蔵のプルアップ抵抗を利用する場合は、このランドのはんだを盛ってショートし、プルアップ抵抗を有効にします。端子は、+電源、-電源、SCL、SDAの4端子です。


●AE-AQM0802
●I2Cのスレーブ・アドレスは0x3E

 AE-AQM0802、AE-AQM1602のI2Cのスレーブ・アドレスは同じ0x3Eで、変更できません。そのため、I2Cの同じバス・ラインにはいずれか一つのLCDモジュールしか接続できません。
 AE-AQM0802は5ピンの入出力端子が用意されています。+電源、-電源、SCL、SDA端子に加えて/reset端子が用意されています。この端子は、内部でプルアップされているので特に理由がない限り何も接続しなくてかまいません。
 次に示すように、+電源はESP32-WROOM-32Dからの3.3V、-電源はESP32-WROOM-32DのGNDに接続し、SCLはGPIO22、SDAをGPIO21に接続します。バス・ラインは3.3kΩでプルアップしてあります。


 この回路で、「AQMシリーズのI2C接続LCDキャラクタ・ディスプレイを使う(1)微妙なSCLクロック」の後半の「テスト・プログラム」を、ESP32-WROOM-32Dに書き込んで実行してみます。

AE-AQMシリーズの標準の電源電圧は3.3V

 前回の記事では、Arduino UNOにAE-AQM0802、AE-AQM1602をつないだので、5V電源で動かしていました。今回はESP32-WROOM-32Dが3.3V電源で駆動されているので、LCDモジュールも本来の3.3V電源で駆動します。そのため、テスト・プログラムの次の部分の変更が必要になります。
 AQMシリーズのLCDモジュールのコントラストは、コマンドの設定で行います。そのため、電源電圧が変わるとこのコントラストの設定も変更する必要があります。5V電源のときに適正なコントラストを設定していても、電源を3.3Vにすると表示のコントラストがなくなり、何も表示されなくなります。これに気が付かない場合、少しトラブルシューティングに時間がかかってしまうことがあります。

トラブルシューティング

 I2Cの通信のトラブルシューティングは、次のように行うと容易に確認できます。WireライブラリのWire.endTransmission()のリターン・コードを確認します。
 確認は、リターン・コードをシリアルモニタに表示することで行います。そのために、setup()関数にシリアル通信の初期化の設定を次のように行い。シリアルモニタが正しく動いていることを確認するために、開始の文字列を出力します。

void setup() {
Serial.begin(115200);
Serial.println("start0");
Wire.begin();
init_lcd();
}

 コマンドの送信結果のコードは、次に示すようにコマンドの書き込み関数のリターン・コードをシリアルモニタに出力しています。コードは次のように定義づけられていますから、0ならWireライブラリの処理はハード/ソフト共に成功とわかります。

        0:success
        1:data too long to fit in transmit buffer
        2:received NACK on transmit of address
        3:received NACK on transmit of data
        4:other errorSerial.println(i2cwritecmd(0x38));

 このリターン・コードは、関数の中で実行されたWire.endTransmission()の実行結果が反映されています。それ以外で動作が正しくない場合は、

  • スレーブ・アドレスの間違い
  • 処理の手順
  • ハードウェアの接続

などの検討が必要になります。今回はテストの結果0のリターン・コードが戻ってきたので、ハード、ライブラリは特に問題なく、コントラストの設定の問題に容易に絞り込まれました。
 次に、テスト・プログラムはコントラストを設定するコマンド0x51から0x55に変更しています。それ以外は前回のプログラムのままです。


テスト・プログラム

#include <Wire.h>
unsigned char lcd_address = 0x3E;
int n = 0;

int i2cwritecmd(byte cmd) {
Wire.beginTransmission(lcd_address);
Wire.write(0x00); Wire.write(cmd);
return Wire.endTransmission();
}

int i2cwritedata(byte data) {
Wire.beginTransmission(lcd_address);
Wire.write(0x40);
Wire.write(data);
return Wire.endTransmission();
}

void lcdcu_set(int x, int y) {
byte ca = (x + y * 0x40) | (0x80); i2cwritecmd(ca);
}

void lcdclear() {
i2cwritecmd(0x01); delay(1);
}

void lcdhome() {
i2cwritecmd(0x02); delay(1);
}

void dsift_l() {
i2cwritecmd(0x1C);
}

void dsift_r() {
i2cwritecmd(0x18);
}

// コントラストの設定コマンドを0x51から0x55に変更した
void init_lcd() {
delay(145);
i2cwritecmd(0x38); delay(1);
i2cwritecmd(0x39); delay(1);
i2cwritecmd(0x14); delay(1);
i2cwritecmd(0x73); delay(1);
i2cwritecmd(0x55); delay(2);
i2cwritecmd(0x6C); delay(300);
i2cwritecmd(0x38); delay(1);
i2cwritecmd(0x01); delay(2);
i2cwritecmd(0x0C); delay(2);
}

void i2cprint( String pdata) {
int n = pdata.length();
for (int i = 0; i < n; i = i + 1) {
i2cwritedata(pdata.charAt(i));
delay(1);
}
}

void setup() {
Wire.begin();
init_lcd();
}

void loop() {
i2cprint(":");
n = n + 1;
i2cprint(String(n));
delay(1000);
}

 コントラストの設定など、各コマンドのことについては「AQMシリーズのI2C接続LCDキャラクタ・ディスプレイを使う (2)拡張命令でコントラストの設定」のページに説明があるので、そちらを参照してください。

  https://www.denshi.club/make/2016/11/aqmi2clcd-2.html

 ESP32-WROOM-32DでもI2Cのポートが標準のSCL(22)、SDA(21)に設定されている場合、Wireライブラリでポートの指定の必要がありません。「I2CインターフェースLCDモジュール用のライブラリを作る」で作成したライブラリが利用できそうです。次回試してみます。

  https://www.denshi.club/make/2017/09/i2clcd-1.html

(2019/2/14 V1.0)

<神崎康宏>

前へ

MAKER UNO + で始めるSTEM (13) 日の出をキャッチ②

次へ

MAKER UNO + で始めるSTEM (14) 日の出をキャッチ③