<前の記事 : 次の記事>
自前ライブラリAQMCHAR
Arduino IDEでスケッチを新規で作って名前をつけて保存した後、そのinoファイルが含まれるフォルダにArduinoライブラリの公式ページからLyquidCrystal.cppおよびLyquidCrystal.hをコピーする。更にそれぞれをAQMCHAR.cppとAQMCHAR.hに変更したコピーを同じフォルダに入れておく。
例えばスケッチをAQM1602test.inoとすると、同じフォルダ内には以下の5つのファイルが含まれる。
AQM1602test.inoAQMCHAR.cppAQMCHAR.hLyquidCrystal.cppLyquidCrystal.h
Arduino IDEでこのスケッチを開いていると以下のように上部にタブが並ぶようになる。
ちなみに、この自前ライブラリが出来たらスケッチの内容は以下のように出来るようになる。極めて普通というか自然というか。
AQM1602test.ino
#include <Wire.h>
#include "AQMCHAR.h"
AQMCHAR lcd=AQMCHAR(0x3E);
void setup() {
Wire.begin();
lcd.begin(16,2);
lcd.setContrast(10);
lcd.print("AQM1602XA-RN-GBW");
lcd.setCursor(0,1);
for(byte i=0xB1;i<0xB1+16;i++) lcd.write(i);
delay(3000);
lcd.home();
}
byte cnt=0;
void loop() {
lcd.write(cnt++);
delay(10);
}
まずはヘッダファイルAQMCHAR.h
冒頭のラベルLiquidCrystal_hをAQMCHAR_hに変更する。但し、変更しなくても問題ない。単に重複しないラベルならなんでもいいからだ。
この下にはHD44780(日立)の定義が並んでいるが、その最後に以下を追加する。
#define LCD_EXTENDED_IS 0x01
#define LCD_NORMAL_IS 0x00
これは拡張モードに関する定義でオリジナルのHD44780には無い。今は初期化とコントラスト調整に少しだけ簡易的に使っているが、そのうち整理していきたい。
コンストラクタの定義は前の記事にも示したように、以下のようなシンプルなものだ。
class AQMCHAR : public Print {
public:
AQMCHAR(uint8_t addr);
void begin(uint8_t cols, uint8_t rows);
LyquidCrystalの方には初期化シーケンスとしてinitが用意されていたが、初期化はbegin内で行うことにしてある。setup()内でWire.bigin()してからlcd.begin(16,2);のように初期化する。
コントラストはコマンドで設定する必要があるのでvoid command(uint8_t);の後に
void setContrast(uint8_t);
を追加する。privateの辺りは以下のようにハードウェア関連の接続情報は全て削除してある。I2Cアドレスを保管しておくuint8_t adr;を追加してある。
private:
uint8_t _adrs;
uint8_t _displayfunction;
uint8_t _displaycontrol;
uint8_t _displaymode;
uint8_t _numlines;
uint8_t _row_offsets[4];
};
ライブラリ本体: AQMCHAR.cpp
ライブラリの本体であるAQMCHAR.cppの冒頭には#include "Wire.h"を追加しておく。コンストラクタはシンプルで、I2Cアドレスを内部変数に保管するだけだ。
AQMCHAR::AQMCHAR(uint8_t adrs) {
_adrs=adrs;
}
LCD側の初期化はLiquidCrystalでは4ビットモードと8ビットモードを選べるようになっているが、I2C版だと8ビットモード固定でいい。また8ビットモードを確定するために
command(LCD_FUNCTIONSET | _displayfunction);
を4回呼んでいるが、この部分はこのまま残しておいても削除してもどちらでもいい。
秋月の使用例では、初期化中に送るコマンドは0x38, 0x39, 0x14, 0x73, 0x52, 0x6c, 0x38, 0x01, 0x0cだったが、特有部分は「0x39, 0x14, 0x73, 0x52, 0x6c,」の拡張モードだけである。コメント行を削除した初期化ルーチン全体を以下に示す。拡張モードに関するところはちょとゴニョゴニョと誤魔化した。そのうち整理する。
void AQMCHAR::begin(uint8_t cols, uint8_t lines) {
_numlines = lines;
setRowOffsets(0x00, 0x40, 0x00 + cols, 0x40 + cols);
if(lines==1) _displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x10DOTS;
else _displayfunction = LCD_8BITMODE | LCD_2LINE | LCD_5x8DOTS;
command(LCD_FUNCTIONSET | _displayfunction | LCD_NORMAL_IS); delay(20);
command(LCD_FUNCTIONSET | _displayfunction | LCD_EXTENDED_IS); delay(20);
byte inits[]={0x14,0x73,0x52,0x6c,};
for(byte i=0;i<sizeof(inits);i++) {
command(inits[i]);
delay(20);
}
command(LCD_FUNCTIONSET | _displayfunction | LCD_NORMAL_IS); delay(20);
_displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
display();
clear();
_displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
command(LCD_ENTRYMODESET | _displaymode);
}
新たに追加すべき関数としてコントラスト設定setContrast(uint8_t)がある。ほとんどGeminiに書いてもらったが初期化直後じゃない場合はちょっと設定が変わってしまうかもしれない。
void AQMCHAR::setContrast(uint8_t contrast) {
if (contrast > 63) contrast = 63;
command(LCD_FUNCTIONSET | _displayfunction | LCD_EXTENDED_IS);
command(0x70 | (contrast & 0x0F));
command(0x54 | ((contrast >> 4) & 0x03));
command(LCD_FUNCTIONSET | _displayfunction | LCD_NORMAL_IS);
delay(1);
肝心のコマンドとデータ送信部分は以下のようにした。send関数を用意してみたがなぜか_adrがスコープ外と言われてコンパイルできなかったので、commandとwriteの中身はそのままI2Cの2バイト送信とした。
void AQMCHAR::command(uint8_t value) {
Wire.beginTransmission(_adrs);
Wire.write(0x00);
Wire.write(value);
Wire.endTransmission();
delay(10);
}
size_t AQMCHAR::write(uint8_t value) {
Wire.beginTransmission(_adrs);
Wire.write(0x40);
Wire.write(value);
Wire.endTransmission();
return 1; // assume success
}
これでライブラリ化は完了であり、特に問題なくコンパイルできている。
結論
元のライブラリがあれば簡単な修正でオリジナルライブラリ化が容易であることがわかった。素性のわからないライブラリをインストールしたくなかったり、やっぱり自分で書きたかったりした場合にすぐに対応できそうだ。こういう車輪の再発見みたいな作業も嫌いじゃない。
<前の記事 : 次の記事>
投稿者の人気記事

-
akira.kei
さんが
前の木曜日の13:45
に
編集
をしました。
(メッセージ: 初版)
-
akira.kei
さんが
前の木曜日の17:08
に
編集
をしました。
-
akira.kei
さんが
前の木曜日の17:59
に
編集
をしました。
-
akira.kei
さんが
前の木曜日の18:46
に
編集
をしました。
-
akira.kei
さんが
前の木曜日の18:50
に
編集
をしました。
-
akira.kei
さんが
前の木曜日の18:51
に
編集
をしました。
-
akira.kei
さんが
前の木曜日の18:53
に
編集
をしました。
-
akira.kei
さんが
前の木曜日の18:55
に
編集
をしました。
-
akira.kei
さんが
前の木曜日の18:57
に
編集
をしました。
ログインしてコメントを投稿する