はじめに
LiquidCrystal_I2C.h
を使わず、LCD2004でHello Worldしました。
前回記事では、LiquidCrystal_I2C.h
を使用してLCDを制御しました。
LCD2004やI2Cアダプタについては前回記事を御覧ください。同じものを使用します。結線も同じです。
Arduino I2C LCD2004 HelloWorld | atooshi-note
ArduinoでLCDを制御する例を調べるとLiquidCrystal_I2C.h
を使った記事がたくさんヒットしますが、LiquidCrystal_I2C.h
を使わない例はあまり見かけませんでした。
RaspberrypiやPICやSTM32で駆動している例はそこそこ見つかりました。
気をつける点(自分めも)
LiquidCrystal_I2C.h
を使わない例としてはACM1602NIを駆動している例がありました。これもI2C接続ですが、LCDモジュールとI2Cアダプタがセットになっています。今回私が使用しているのはLCDとI2Cアダプタ(PCF8574T)が別で接続したものですのでプログラムそのままでは動きません。- 以下は
LiquidCrystal_I2C.h
がいい感じにやってくれていますが、自分で組むときに気をつけた点です。- 適切なディレイが必要
- 初期化手順が決まっている
- 4bitモードで制御する
- enable信号のL→H→Lは0.22us以上あける
PCF8574TとLCD2004の結線
LCD | DB7 | DB6 | DB5 | DB4 | バックライトのトランジスタのGate | E | R/W | RS | |
---|---|---|---|---|---|---|---|---|---|
PCF8574T | P7 | P6 | P5 | P4 | P3 | P2 | P1 | P0 |
プログラム
/*
wire.h使用(i2c)
#include <LiquidCrystal_I2C.h>は不使用
*/
#include <Wire.h>
#define lcdaddr 0x27
#define lcdEN 0b00000100 // Enable
#define lcdBL 0b00001000 // Back light ON
#define setDDRAMaddr 0b10000000 // Set DDRAM Address
#define setRS 0b00000001 // RS=1
#define unsetRS 0b00000000 // RS=0
void lcdinit()
{
// 一旦8bitモードに設定(3回繰り返す)
// 1回目
lcdwrite0(0x30,unsetRS); // Funcition Set DL=1:8bitバス
delay(5); // Wait for more than 4.1 ms
// 2回目
lcdwrite0(0x30,unsetRS);
delayMicroseconds(150); // Wait for more than 100 µs
// 3回目
lcdwrite0(0x30,unsetRS);
delayMicroseconds(100); // Wait for more than 40 µs
lcdwrite0(0x20,unsetRS); // 4bitモードに設定 Funcition Set DL=0:4bitバス
lcdwrite(0x28,unsetRS); // 2行表示モードに設定 Funcition Set DL=0:4bitバス,Set N=1:2桁表示
lcdwrite(0x0F,unsetRS); // 表示ON/OFF D=1:文字表示ON,C=1:下線カーソルON,B=1:ブロックカーソルON
lcdwrite(0x06,unsetRS); // エントリモードセット I/D=1:インクリメント
lcdwrite(0x01,unsetRS); // 表示クリア
lcdwrite(0x02,unsetRS); // カーソルホーム
}
// 8bit用
void lcdwrite0(byte bits,byte mode){
i2cwrite(bits | mode);
}
// 4bit用
void lcdwrite(byte bits,byte mode){
i2cwrite((bits & 0xF0) | mode); // 上位4bit
i2cwrite(((bits << 4) & 0xF0) | mode); // 下位4bit
}
void i2cwrite(byte val){
Wire.beginTransmission(lcdaddr);
Wire.write(val | lcdBL);
delayMicroseconds(1); // 0.22us以上
Wire.write(val | lcdBL | lcdEN);
delayMicroseconds(1); // 0.22us以上
Wire.write(val | lcdBL);
Wire.endTransmission();
delayMicroseconds(100); // Wait for more than 40 µs とは言いつつ50usec待ちでは動かない 100usecぐらい余裕を持っておく
}
// row:行 col:列
void setCursor(int row, int col){
int row_offsets[] = {0x00, 0x40, 0x14, 0x54}; // 0から数え始め
lcdwrite((col + row_offsets[row]) | setDDRAMaddr,unsetRS);
}
void lcdText(String s){
for(int i = 0; i < s.length(); i++){
lcdwrite(s.charAt(i),setRS);
}
}
void setup() {
delay(50); // Wait for more than 15 ms after VCC rises to 4.5 V
Wire.begin();
lcdinit();
setCursor(0,0); // カーソルを0行目0列目に移動
lcdwrite(0x30,setRS); // 数字の0を出力 HD44780 Table 4 Correspondence between Character Codes and Character Patterns (ROM Code: A00)
setCursor(1,1);
lcdwrite(0x31,setRS); // 数字の1を出力
setCursor(2,2);
lcdText("2_hello world!");
}
void loop() {
setCursor(3,0);
lcdText("3_Hello World!");
delay(1000);
setCursor(3,0);
lcdText("3_World!");
delay(1000);
}
結果
参考
参考にさせていただき、ありがとうございました。
- HD44780U datasheet | Hitachi
- I2Cインターフェース付きLCD1602表示テスト
- PCF8574Tを使ったLCD制御 #I2C - Qiita
- キャラクタLCDモジュールの使いかた
- 液晶ディスプレイを使う
- i2c_LCD
以上:)