Arduino UNO R4の登場で広がるArduinoの世界(4)i2clcdaqmライブラリの作成

 Arduino用のライブラリの作成はArduino.ccのホームページに示された「Writing a Library for Arduino」の方法に従って、i2clcd.cpp、i2clcd.h、keywords.txt、library.propertiesの四つのファイルを作成ました。テストで使用したスケッチはexamplesのフォルダにセットします。
 
 
 
I2C接続のLCDモジュールはAQM1602
 
 このライブラリの対象となるI2C接続のLCDモジュールはAQM1602とします。ACM1602のモジュールも対象としていましたが、ACM1602のモジュールはArduinoのAVRのモデルと異なるとI2Cアドレス・エラーが生じて正常な動作ができない場合があります。そのため、安定な動作が期待できるAQM1602の系統のLCDモジュールを対象としました。
 
接続のための条件
  • I2Cスレーブ・アドレス 0x3E
  • 電源電圧は3.3V、5Vの両方の電源に対応する
  • 必要に応じて、電圧、輝度、アドレスについて設定できるようにする
 
i2clcdaqm.cppのソース・ファイルの作成
 
 I2CインターフェースのLCDモジュールAQM1602の具体的な処理は、i2clcdaqmライブラリのi2clcdaqm.cppに記述します。
 このi2clcd.cppは次に示すように、ヘッダ・ファイルの設定、コンストラクタの定義、i2cによるコマンド書き込み関数とデータの送信処理の関数を用意します。ここまでが具他的なLCDモジュールへの制御と表示のための準備です。
 

 
 コマンド書き込み関数i2cwritecmd()を用いて、モジュールを制御するためのコマンド書き込み、初期化、表示のクリア、カーソルの位置設定などの処理を行います。表示データの書き込みの関数i2cwritedata()を利用して、LCDモジュールのカーソルで指定された表示位置にデータを表示するために、データをバイト単位で書き込みます。
 文字データはバイト単位で書き込み表示されます。数値データなどは文字列に変換し変換された文字をバイト単位で書き込んでいます。

 
 
i2clcdaqm.cppの内容
 
 上記に示した構成を、i2clcdaqm.cppの名のライブラリの中核となるファイル作成します。
 
必要なヘッダ・ファイルの読み込み
 
#include <i2clcdaqm.h>
#include <Arduino.h>
#include <Wire.h>
 
 ●コンストラクタの設定 
 
 コンストラクタは、クラスからオブジェクト(インスタンス)の生成と初期値の設定などを自動的に実行されます。引数のない場合、電圧値のみ引数とする場合、電圧値と輝度を引数とする場合、電圧値と輝度とアドレスを引数とすると場合の四つのコンストラクタを用意してあります。
 引数がない場合、電圧は3V、輝度は0x23,アドレスは0x3Eとしてオブジェクトが生成されます。
 
i2clcdaqm::i2clcdaqm( )  {
_v5or33 = 3;
_br =0x23;
_addr = 0x3E;
}
 
 電圧値は引数の値(3または5)として、輝度は0x23,アドレスは0x3Eとしてオブジェクトが生成されます。
 
i2clcdaqm::i2clcdaqm(byte v5or33) {
_v5or33 = v5or33;
_br = 0x23;
_addr = 0x3E;
}
 
 電圧値は引数の値(3または5)として、輝度は引数,アドレスは0x3Eとしてオブジェクトが生成されます。
 
i2clcdaqm::i2clcdaqm(byte v5or33,byte lbr) {
_v5or33 = v5or33;
_br = lbr;
_addr = 0x3E;
}
 
 電圧値は引数の値(3または5)として、輝度は引数の値,アドレスも引数の値でオブジェクトが生成されます。
 
i2clcdaqm::i2clcdaqm(byte v5or33,byte lbr,byte i2cadr){
_v5or33 = v5or33;
_br = lbr;
_addr = i2cadr;
}
 
 コマンドを書き出すための関数の本体で、メソッドの具体的な記述を行います。
 バイトの引数をコマンドとして書き込み、戻り値はエラーの有無を示します。
 
int i2clcdaqm::i2cwritecmd(byte cmd){
  Wire.beginTransmission(_addr);
  Wire.write(0x00);
  Wire.write(cmd);
  return Wire.endTransmission();
}
 
 バイトの引数を表示データとして書き込む関数。戻り値はエラーの有無を示します。
 
int i2clcd::i2cwritedata(byte data){
int i2clcdaqm::i2cwritedata(byte data){
  Wire.beginTransmission(_addr);
  Wire.write(0x40);
  Wire.write(data);
  return Wire.endTransmission();
}
 
 x(列)、y(行)で示す位置にカーソルの座標をセットします。続くデータの表示コマンドではこのカーソルの位置に表示され、カーソルの座標が一つ進みます。
 上段左端(x=0,y=0)、下段左端(x=0,y=1)
 
void i2clcdaqm::lcdcu_set(int x, int y) {
  byte ca = (x + y * 0x40) | (0x80); 
 i2cwritecmd(ca);
}
 
 表示画面をクリアするコマンド0x01をコマンド書き込み関数で書き込み、表示をクリアします。
 
void i2clcdaqm::lcdclear() {
Serial.println( i2cwritecmd(0x01));  delay(1);
}
 
 カーソルをホーム位置にセットするコマンド0x02をコマンド書き込み関数で書き込み、コマンドの機能を実現します。
 
void i2clcdaqm::lcdhome() {
  i2cwritecmd(0x02);  delay(1);
}
 
 表示を左にシフトするコマンド0x18をコマンド書き込み関数で書き込み、コマンドの機能を実現します。
 
void i2clcdaqm::dsift_l() {
  i2cwritecmd(0x18);
}
 
 表示を左にシフトするコマンド0x1Cをコマンド書き込み関数で書き込み、コマンドの機能を実現します。
 
void i2clcdaqm::dsift_r() {
  i2cwritecmd(0x1C);
}
 
 コマンド書き込み関数を利用してLCDモジュールの初期化を行います。電圧、輝度のデータに基づいて適切な初期化のコマンドを用意します。
 
void i2clcdaqm::init_lcd() {
  byte bon = 0;
  delay(145);
  i2cwritecmd(0x38); delay(1);//
  i2cwritecmd(0x38); delay(1); //
  byte contrast = (0x70 | (_br & 0x0F));
  if (_v5or33 == 5) {  // 電圧が5Vの場合bonの値は0、それ以外は4
    bon=0;
  }
  else {
    bon=0x04;
}
  byte powercmd = ((0x50 | (bon )| (_br >> 4)));  // 電圧に適切に対応したコマンド生成
  Serial.println(powercmd);
  Serial.println(contrast);
  i2cwritecmd(0x39);  delay(1);
  i2cwritecmd(0x14);  delay(1);
  i2cwritecmd(contrast);  delay(1);
  i2cwritecmd(powercmd);  delay(2);
  i2cwritecmd(0x6C);  delay(300);
  i2cwritecmd(0x38);  delay(1);
  i2cwritecmd(0x01);  delay(2);
  i2cwritecmd(0x0C);  delay(2);
}
 
 文字列を表示するための関数、数値の場合はStringオブジェクトで文字列にして表示します。
 
void i2clcdaqm::i2cprint( String pdata) {
  int n = pdata.length();
  for (int i = 0; i < n; i = i + 1) {
    i2cwritedata( pdata.charAt(i));
    delay(1);
  }
}
 
ヘッダ・ファイル(i2clcd.h)
 
 ヘッダ・ファイルは次に示すように記述します。#ifndef i2clcdaqm_hでこのファイルが定義されていない場合にのみ、次の#defineから最後#endifの間の内容が定義されます。これによってヘッダ・ファイルの内容をダブって定義されることを防止します。
 
#ifndef i2clcdaqm_h
#define i2clcdaqm_h
 
#include "Arduino.h"
 
 クラスの定義とメンバの宣言を行っています。
 
class i2clcdaqm
{
  public:
   i2clcdaqm();
   i2clcdaqm(byte i2cadr);
   i2clcdaqm(byte lbr, byte i2cadr);
   i2clcdaqm(byte v5or33, byte lbr, byte i2cadr);
   int i2cwritecmd(byte cmd);
   int i2cwritedata(byte data);
   void lcdcu_set(int x, int y);
   void lcdclear();
   void lcdhome();
   void dsift_l();
   void dsift_r();
   void init_lcd();
   void init_lcd2();
   void i2cprint( String pdata);
private:
   byte _addr;
   byte _v5or33;
   byte _br;
};
#endif
 
 この#endifまでが定義域です。
 
キーワード・ファイル(keywords.txt)
 
 キーワード・ファイルを設定すると、KEYWORD2と設定した変数はArduino IDEのエディタが橙色で表示します。
 
i2clcdaqm  KEYWORD1
i2cwritecmd  KEYWORD2
i2cwritedata  KEYWORD2
lcdcu_set  KEYWORD2
lcdclear  KEYWORD2
lcdhome  KEYWORD2
dsift_l  KEYWORD2
dsift_r  KEYWORD2
 init_lcd  KEYWORD2
 i2cprint  KEYWORD2
 
ライブラリ・プロパティ・ファイル(library.properties)
 
 ライブラリ・プロパティは次のように設定しました。
 
name=i2clcdsqm
version=1.2.0
author=神崎康宏
maintainer=電子クラブ <alpsyk@gmail.com>
sentence=Arduino I2Cインターフェース用LCDライブラリ
paragraph=AQM0802用、3.3V、5Vの電源電圧にも対応
category=display
url=https://www.denshi.club/cookbook/arduino/r4/arduino-uno-r4arduino4.html
architectures=*
 
 
ライブラリのセット
 
 ライブラリ名と同じ名称のフォルダに、ライブラリを格納します。このフォルダにはlibrary.properties、keywords.txtの二つのファイルとsrcの名のソース・フォルダと、examplesの名のサンプル・スケッチを格納する二つのフォルダを用意します。
 
 ここではi2clcdaqmのフォルダにlibrary.properties、keywords.txtのファイルとその中のsrcフォルダにi2clcdaqm.cppとi2clcdaqm.hの二つのソースファイル、examplesフォルダにはテストで使用したi2clibtest010.inoのソースを格納するi2clcdlibtest01フォルダを用意しフォルダ内にi2clibtest010.inoをセットします。
 
 すべてのファイルとフォルダを用意します。フォルダとファイルの準備ができたらi2clcdaqmフォルダを圧縮しi2clcdaqm.zipを作成します。このフォルダを圧縮してi2clcdaqm.zipを作ります。
 
ライブラリのインストール
 
メニューバーの、
 
  スケッチ > zipライブラリをインクルード > zip形式のライブラリをインストール
 
を選択します。ライブラリのzipファイルを選択する画面が表示されます。インストールするi2clcdaqm.zip選択しボタン「開く」クリックすると、インストールされます。
 
テスト回路
 
 テスト回路はAQM1602のほかに8列×2行表示のAQM0802のLCDモジュールもテストします。AQM0802もアドレスは0x3Eで初期設定の条件も同様になります。AQM1602との違いは表示列範囲がAQM1602の半分になる以外は同じです。
 
 AQM1602は±の電源とSCL、SDAの4本の配線が必要です。AQM0802はリセットの端子が追加され5端子となっています。リセットは基板内でプルアップされていますので接続しなくてもかまいません。
 

 
 
スケッチ例
 
 サンプルのスケッチ例i2clcdlibtest01.inoは次に示すようになります。スケッチは上段に「i2clcd test」を表示し下段にはloop()関数の繰り返し1回ごとに0.05単位でカウントアップされ、数値とloop()関数の先頭から経過時間の表示の直前までの命令実行時間を表示します。単位はmsです。
 

 
 
実行結果は
 
 下段のカウントアップの値の横に、46が表示されています。これはloop()関数の13行~19行までの実行時間を表示しています。
 AQM1602とAQM0802は同じアドレスで、設定のコマンドは同じですので表示範囲が異なるだけで同じ内容が表示されます。
 

 
 AQM0802の表示データの各場所は各行40列とAQM1602と同じですが、この中の連続した8列だけが表示範囲となります。
 

 
 
AQM1602,AQM0802用のライブラリが出来上がる
 
 前回までのi2clcdライブラリはAQM1602とACM1602のLCDモジュールを対象としていました。しかしACM1602はArduino MKRシリーズ、Arduino Uno R4などでは駄々しいアドレスでもアドレス・エラーとなりI2Cの通信が正常に行えなくなっています。そのため今回作成したライブラリはAQM1602,AQM0802用として名称もi2clcdaqmとしました。
 Arduino AVRのボードでACM1602のモジュールを利用する場合はi2clcdライブラリを利用してください。 
 
 ここから  i2clcdaqm.zipをダウンロード  できます。

(2023/08/30)
 
 <神崎 康宏>
 

前へ

Arduino UNO R4 Minimaでセンサ・インターフェーシング ⑫ 温湿度センサ SHTC3

次へ

Arduino UNO R4 Minimaでセンサ・インターフェーシング ⑬ 温湿度センサ AHT20