ESP32入門 通信機能が標準搭載されたマイコン・ボード (7) i2clcdライブラリ

I2Cインターフェースのスレーブ・アドレス

 2019年2月現在、I2CインターフェースのキャラクタLCDモジュールは、ACM1602NI-FLW-FとAE-AQM1602Aの名のついたシリーズの2種類が入手できます。AQMシリーズは16文字2行表示のほかにAQM0802の8文字2行表示、ハーフ・ピッチのピンヘッダのAQMシリーズと2.54ピッチの変換基板を装着したAE-AQMシリーズなど多様なモデルが用意されています。
 これらのLCDモジュールのスレーブ・アドレスは固定で変更することができず、次のように設定されています。

  ACM1602NI-FLW-F     0x50
  AQMシリーズ       0x3E

 スレーブ・アドレスをチェックすると、ACMのLCDモジュールかAQMシリーズか識別することができます。
 前に制作したi2clcdは、この二つのシリーズのI2CインターフェースのLCDモジュール用のライブラリとなっています。これ以外のI2CインターフェースのLCDモジュールには対応を考慮していません。

  I2CインターフェースLCDモジュール用のライブラリを作る(7)ライブラリ完成

i2clcdの使い方

 tmp102の温度センサの測定結果を表示するプログラムの作成を例にして、i2clcdライブラリの使い方を説明します。

(1) ヘッダ・ファイルの読み込みを指定

 i2clcdライブラリを使用するために、最初に次のメッセージでi2clcd.hのヘッダ・ファイルの読み込みを指定します。

  #include <i2clcd.h>

(2) インスタンスの作成

 実際のプログラムの中で、i2clcdライブラリに設定されているいろいろな処理を行うためのインスタンスを作成します。

  i2clcd インスタンス名();

 インスタンスの作成で引数を指定しないとACM1602を対象とした設定で初期化を行います。

  i2clcd インスタンス名(byte i2cadr);  

 AQMシリーズを利用する場合は、引数にスレーブ・アドレス0x3Eを指定します。ACM1602を利用する場合は、引数に0x50を指定します。

  i2clcd インスタンス名(byte i2cadr、byte v5or33);

 AQMシリーズの場合はコントラストの設定をコマンドで行います。その設定値は電源電圧によっても異なるため、電源電圧が5Vか3.3Vかを設定します。5V電源の場合5、3.3Vの場合3と設定します。実際の処理では、5の設定時は5V電源として処理し、5以外のときは3.3Vの電源として処理します。

  i2clcd インスタンス名(byte i2cadr、byte v5or33、byte lbr);

 任意のコントラストの設定値を設定する場合のため、コントラストの設定値を設定できるものも用意されています。

 以上の設定を行った後は、次の関数を利用して具体的な処理が行えます。

① i2cwritecmd(byte cmd) コマンドcmdを書き込む 
② i2clcd::i2cwritedata(byte data) 表示データdataを書き込む
③ lcdcu_set(int x, int y) カーソルをX列、Y行にセットする 
④ lcdclear() LCDの表示をクリアしカーソルをホーム・ポジションにセット
⑤ lcdhome() カーソルをホーム・ポジションにセット
⑥ dsift_l() 左に表示をシフト
⑦ dsift_r() 右に表示をシフト
⑧ init_lcd() LCDモジュールの初期化
⑨ i2cprint( String pdata) 文字列の表示

テスト・プログラム

 i2clcdライブラリを利用して、ESP32-WROOM-32Dでi2cインターフェースのLCDモジュールへ書き込みができるか試してみます。書き込みデータは、tmp102のディジタル温度センサからの気温の測定値を用います。tmp102は2019年2月現在スイッチサイエンスで入手できます。

ヘッダ・ファイルの読み取り指定

 tmp102の温度センサの読み取りにはWireライブラリを使用するため、 #include<Wire.h>を追加します。

#include<i2clcd.h> // i2clcdライブラリのヘッダ・ファイルを読み込む
#include<Wire.h> // 温度測定のためWireライブラリのヘッダ・ファイル

変数/定数の設定

 カウンタの値をセットする変数の定義と初期値0の設定、およびtmp102のI2Cインターフェースのスレーブ・アドレスを設定します。

int n = 0;
unsigned char tmp2_adr = 0x48;

インスタンス生成

 i2clcdライブラリからAQMシリーズの書き込み処理を行うオブジェクトqlcdを生成します。このオブジェクトに用意されているメソッドで具体的な処理を行います
 AQMシリーズ、電源3V、コントラスト0x20と設定します。

i2clcd qlcd(0x3E, 3, 0x20); //具体的な処理を行うためのオブジェクトを作る

tmp102からの温度の読み取り関数

 戻り値が実数型の関数get_tmp102()、引数としてtmp102のスレーブ・アドレスを指定してこの関数を呼び出すと、tmp102にアクセスし温度を読み取り、摂氏の温度に変換して戻り値に設定されます。
 tmp102から最初に読み込まれたバイトは、温度データの4ビット目から11ビット目の値です。2バイト目に読み込まれた値のd4からd7までは、温度データの0ビットから3ビット目となります。

float get_tmp102(unsigned char tmp0_adr) { // 温度センサを読み取る関数
Wire.requestFrom(tmp0_adr, 2);
while (Wire.available() < 2) {
}
int tmpin = Wire.read() * 16; // d7~d0をd11~d4にシフトしている
tmpin = tmpin + (Wire.read() >> 4); // d7~d4をd3~d0にシフトして加算
return 0.0625 * tmpin; // 読み取り温度を摂氏に変換
}

1回だけ実行する関数

 setup()は初期化などの記述を行うための関数で、この中でAQMシリーズのLCDモジュールの初期化を呼びます。

void setup() {
qlcd.init_lcd(); // LCDモジュールの初期化処理
}

繰り返し実行される処理

 loop()内は、記述した処理が繰り返されます。最初にqlcd.lcdclear()でLCDモジュールをクリアしてカーソルをホーム・ポジション上段左端に設定します。カウンタの値をカウントアップしqlcd.i2cprint()でカウンタの値をString()関数で文字列にしたものを引数として表示します。その後区切り、見出しを表示した後get_tmp102()関数で読み取った温度を同様にString()関数で文字列に変換したものをLCDに表示しています。
 その後1000ms待って最初に戻り繰り返します。

void loop() {
qlcd.lcdclear(); // LCDモジュールのクリア
n = n + 1;
qlcd.i2cprint(String(n)); // カウンタの値をLCDへ表示
qlcd.i2cprint(":");
qlcd.i2cprint("temp2="); // 見出しをLCDへ表示
qlcd.i2cprint(String(get_tmp102(tmp2_adr))); // 測定温度を表示
delay(1000);
}

 以上のプログラムをArduino IDEでコンパイルしてESP32-WROOM-32Dの開発ボードにUSB経由で書き込みます。

(※)2019/02/26 13行目のWire.endTransmission(); は不要です。


 ツール>ボードでESP32 Dev Moduleを選択する必要はありますが、適切にボードの種類を選択するとArduinoで動いていたプログラムはESP32-WROOM-32Dのボードでも同様に動くことができます。
 プログラムの実行の様子を次に示します。

 次回はこのプログラムにWebServerの機能を追加し、測定された温度のデータをWebブラウザとの間で処理することを考えてみます。

付録 i2clcdのメソッド

i2cwritecmd(byte cmd)コマンドcmdを書き込む
 引数を処理したいコマンドに設定してこの関数を呼び出すと指定したコマンドの処理が実行されます。クリア、ホームなどのコマンドをあらかじめセットして引数なしで特定の処理を行う関数も用意してあります。それらの関数はこの関数を呼び出しています。

i2cwritedata(byte data) 表示データdataを書き込む 
 表示データを1バイト書き込みます。書き込まれた1バイトのデータは文字コードとして解釈され、該当する文字コードの文字もしくは記号が1文字分表示されます。

lcdcu_set(int x, int y) カーソルをX列、Y行にセットする
xが0のとき左端の位置にカーソルがセットされます。yが0のときは上段の1行目、1のとき下段の2行目にセットされます。

lcdclear() LCDの表示をクリアしカーソルをホーム・ポジションにセット
 この関数の内部では、コマンド0x01をセットしてi2cwritecmd()関数を呼び出しています。

lcdhome() カーソルをホーム・ポジションにセット
 表示内容は消去されません。この関数の内部では、コマンド0x02をセットしてi2cwritecmd()関数を呼び出しています。

dsift_l() 左に表示を1文字分シフト
 アドレスが0x00から0x3F(63)までのバッファのうち16字または8文字分が表示されています。デフォルトでは0から0x0Fのアドレスが表示されています。この表示領域が左に1文字分シフトされます。

dsift_r() 右に表示を1文字分シフト
 アドレスが0x00から0x3F(63)までのバッファのうち16字または8文字分が表示されています。デフォルトでは0から0x0Fのアドレスが表示されています。この表示領域が右に1文字分シフトされます。

init_lcd() LCDモジュールの初期化を行う
 インスタンス化でLCDモジュールのタイプ、電源などの条件を指定しているので、それらの条件に従い採用しているモジュールに最適な初期化が行われます。

i2cprint( String pdata) 文字列の表示
 Stringの文字列のオブジェクトの先頭から順番に1文字ずつ全文字LCTモジュールに表示します。

(2019/2/25 V1.0)

<神崎康宏>

前へ

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

次へ

ESP32入門 通信機能が標準搭載されたマイコン・ボード (8) i2clcdライブラリを使ってみる