秋月の16桁×2行のI2Cキャラクタ液晶を使う 漢字表示までAQM1602XA-RN-GBW
秋月にて550円で入手したI2Cキャラクタディスプレーを使う。
I2Cのキャラクタディスプレーは初めてなので記事にしておきたい。
この製品はキャラクタディスプレーをST7032iで制御する仕様になっておりました。
なので、マイコンと直接やり取りするのはST7032となります。
データシートにはArduinoと接続する為のソースが掲載されておりましたので、
そちらを最初に動かして・・・
動かないぞ。と・・・・
今回は3.3Vのarduinoを使う予定でしたが、
5Vに切り替えてそのままのソースでやってみると、
ちゃんと動く。
悩む。5Vで動く、3.3Vでは動かないソース
これは秋月のページのデータシートに乗っかっているやつです。
#include <Wire.h>
#define LCD_ADRS 0x3E
char moji[] ="AQM1602XA-RN-GBW";
//SCL=A5=LCDNo2 SDA=A4=LCDNo3
void setup()
{
Serial.begin(9600);
Serial.println("AQM1602 ver1.0");
Serial.println("start:");
Wire.begin();
init_LCD();
}
void loop() {
Serial.println("p 3");
for(int i = 0; i < 16; i++) {
writeData(moji[i]);
}
Serial.println("p 4");
writeCommand(0x40+0x80); // 2LINE TOP
for(int i = 0; i < 16; i++) {
writeData(i+0xb1);
}
Serial.println("p 5");
while(1){}//stop
}
//データ書き込み
void writeData(byte t_data)
{
Wire.beginTransmission(LCD_ADRS);
Wire.write(0x40);
Wire.write(t_data);
Wire.endTransmission();
delay(1);
}
//コマンド書き込み
void writeCommand(byte t_command)
{
Wire.beginTransmission(LCD_ADRS);
Wire.write(0x00);
Wire.write(t_command);
Wire.endTransmission();
delay(10);
}
//液晶初期化
void init_LCD()
{
delay(100);
writeCommand(0x38);
delay(20);
writeCommand(0x39);
delay(20);
writeCommand(0x14);
delay(20);
writeCommand(0x73);
delay(20);
writeCommand(0x52);
delay(20);
writeCommand(0x6C);
delay(20);
writeCommand(0x38);
delay(20);
writeCommand(0x01);
delay(20);
writeCommand(0x0C);
delay(20);
}
悩む。
コントラストの調整が合わないのでは?と当たりをつけて
で、紙のソースと比較したところ、
コントラストに関連する部分ですが
インターネットだと
writeCommand(0x52);
紙だと
writeCommand(0x56);
となっていました、
ですので髪に合わせてみた所
ちゃんと動くではないですか。
というわけで、
漢字 年月日 で表示する所までできた。
写真

ソース。
#include <Wire.h>
#define LCD_ADRS 0x3E
char moji[] ="AQM1602XA-RN-GBW";
//SCL=A5=LCDNo2 SDA=A4=LCDNo3
void setup()
{
int i;
Serial.begin(9600);
Serial.println("start ACM1602-I2C TEST version0.3");
Wire.begin(); // I2C初期化
while(1){
lcd_init(); // LCD初期化
lcd_clear(); // 全クリア
lcd_noBlink(); // カーソル点滅なし
lcd_noCursor(); // カーソル表示なし
lcd_setCursor(0, 0); // カーソル位置1行目を指定
for(i = 0; i < 16; i++) {
lcd_writeData(0x30 + (i%10)); // ダイレクト LCDデータライト
}
lcd_setCursor(0, 1); // カーソル位置2行目を指定
for(i = 0; i < 16; i++) {
lcd_writeData('A' + i);
}
delay(1000);
// 表示OFF/ON
lcd_noDisplay();
delay(1000);
lcd_display();
delay(1000);
char StrBuf[256];
// 文字列表示
lcd_clear(); // 全クリア
lcd_string("test1"); // 文字列表示
lcd_setCursor(5, 1); // カーソル位置指定
//テスト2
memset(StrBuf, 0, sizeof(StrBuf));
sprintf(StrBuf, "%c%c%c%c", 0xC3, 0xBD, 0xC4, 0x32); //テスト2 0xC3=テ, 0xBD=ス, 0xC4=ト, 0x32=2
lcd_string(StrBuf);
delay(1000);
// 数値文字列表示
for(i=0;i<1000;i++){
lcd_setCursor(10, 1); // カーソル位置指定
sprintf(StrBuf, "%d", i);
lcd_string(StrBuf);
}
delay(1000);
//
//外字
//
lcd_clear(); // 全クリア
lcd_display(); // LCD表示
lcd_setCursor(0, 0); // カーソル位置
lcd_writeData('A');
uint8_t charmap[8];
//年
charmap[0] = 0b10000;
charmap[1] = 0b11111;
charmap[2] = 0b00100;
charmap[3] = 0b11111;
charmap[4] = 0b10100;
charmap[5] = 0b11111;
charmap[6] = 0b00100;
charmap[7] = 0b00000;
lcd_createChar(0, charmap);
//月
charmap[0] = 0b01111;
charmap[1] = 0b01001;
charmap[2] = 0b01111;
charmap[3] = 0b01001;
charmap[4] = 0b01111;
charmap[5] = 0b01001;
charmap[6] = 0b10001;
charmap[7] = 0b00000;
lcd_createChar(1, charmap);
//日
charmap[0] = 0b11111;
charmap[1] = 0b10001;
charmap[2] = 0b10001;
charmap[3] = 0b11111;
charmap[4] = 0b10001;
charmap[5] = 0b10001;
charmap[6] = 0b11111;
charmap[7] = 0b00000;
lcd_createChar(2, charmap);
Serial.println("p 3");
lcd_clear(); // 全クリアしないと上で設定したキャラクタが反映されない
lcd_string("2017");
lcd_writeData(0x00); //年
lcd_string("10");
lcd_writeData(0x01); //月
lcd_string("05");
lcd_writeData(0x02); //日
Serial.println("p 4");
delay(1000);
}
}
void loop()
{
}
//---------------------------------------------------
#include <inttypes.h>
#define NUM_LINES 2
// commands
#define LCD_CLEARDISPLAY 0x01
#define LCD_RETURNHOME 0x02
#define LCD_ENTRYMODESET 0x04
#define LCD_DISPLAYCONTROL 0x08
#define LCD_CURSORSHIFT 0x10
#define LCD_FUNCTIONSET 0x20
#define LCD_SETCGRAMADDR 0x40
#define LCD_SETDDRAMADDR 0x80
// flags for display entry mode
#define LCD_ENTRYRIGHT 0x00
#define LCD_ENTRYLEFT 0x02
#define LCD_ENTRYSHIFTINCREMENT 0x01
#define LCD_ENTRYSHIFTDECREMENT 0x00
// flags for display on/off control
#define LCD_DISPLAYON 0x04
#define LCD_DISPLAYOFF 0x00
#define LCD_CURSORON 0x02
#define LCD_CURSOROFF 0x00
#define LCD_BLINKON 0x01
#define LCD_BLINKOFF 0x00
// flags for display/cursor shift
#define LCD_DISPLAYMOVE 0x08
#define LCD_CURSORMOVE 0x00
#define LCD_MOVERIGHT 0x04
#define LCD_MOVELEFT 0x00
uint8_t lcd_DisplayMode;
uint8_t lcd_DisplayControl;
void lcd_writeCmd(uint8_t cmd)
{
Wire.beginTransmission(LCD_ADRS);
Wire.write(0x00);
Wire.write(cmd);
Wire.endTransmission();
}
void lcd_writeData(uint8_t dat)
{
Wire.beginTransmission(LCD_ADRS);
Wire.write(0x40); //データの場合は0x40
Wire.write(dat);
Wire.endTransmission();
}
void lcd_init(void)
{
// init
Serial.println("p 1");
delay(100);
lcd_writeCmd(0x38); //FunctionSet
delay(20);
lcd_writeCmd(0x39); //FunctionSet 拡張モードへ移行
delay(20);
lcd_writeCmd(0x14);
delay(20);
lcd_writeCmd(0x73); //コントラスト下4ビット
delay(20);
lcd_writeCmd(0x56); //3.3Vで動かす場合は0x56みたい。
//コントラスト下2ビット
delay(20);
lcd_writeCmd(0x6C); //
delay(20);
lcd_writeCmd(0x38); //FunctionSet 拡張モードへ終了
delay(20);
lcd_writeCmd(0x01); //ClearDisplay
delay(20);
lcd_writeCmd(0x0C); //DisplayON CursorOFF BlinkOFF
delay(20);
Serial.println("p 2");
lcd_DisplayControl = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
lcd_DisplayMode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
}
void lcd_clear(void)
{
lcd_writeCmd(LCD_CLEARDISPLAY);
delayMicroseconds(2000);
}
void lcd_home(void)
{
lcd_writeCmd(LCD_RETURNHOME);
delayMicroseconds(2000);
}
void lcd_setCursor(uint8_t col, uint8_t row)
{
int row_offsets[] = { 0x00, 0x40 };
if ( row >= NUM_LINES ) {
row = NUM_LINES - 1;
}
lcd_writeCmd(LCD_SETDDRAMADDR | (col + row_offsets[row]));
}
void lcd_noDisplay()
{
lcd_DisplayControl &= ~LCD_DISPLAYON;
lcd_writeCmd(LCD_DISPLAYCONTROL | lcd_DisplayControl);
}
void lcd_display()
{
lcd_DisplayControl |= LCD_DISPLAYON;
lcd_writeCmd(LCD_DISPLAYCONTROL | lcd_DisplayControl);
}
void lcd_noCursor()
{
lcd_DisplayControl &= ~LCD_CURSORON;
lcd_writeCmd(LCD_DISPLAYCONTROL | lcd_DisplayControl);
}
void lcd_cursor()
{
lcd_DisplayControl |= LCD_CURSORON;
lcd_writeCmd(LCD_DISPLAYCONTROL | lcd_DisplayControl);
}
void lcd_noBlink()
{
lcd_DisplayControl &= ~LCD_BLINKON;
lcd_writeCmd(LCD_DISPLAYCONTROL | lcd_DisplayControl);
}
void lcd_blink()
{
lcd_DisplayControl |= LCD_BLINKON;
lcd_writeCmd(LCD_DISPLAYCONTROL | lcd_DisplayControl);
}
void lcd_scrollDisplayLeft(void)
{
lcd_writeCmd(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
}
void lcd_scrollDisplayRight(void)
{
lcd_writeCmd(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
}
void lcd_leftToRight(void)
{
lcd_DisplayMode |= LCD_ENTRYLEFT;
lcd_writeCmd(LCD_ENTRYMODESET | lcd_DisplayMode);
}
void lcd_rightToLeft(void)
{
lcd_DisplayMode &= ~LCD_ENTRYLEFT;
lcd_writeCmd(LCD_ENTRYMODESET | lcd_DisplayMode);
}
void lcd_autoscroll(void)
{
lcd_DisplayMode |= LCD_ENTRYSHIFTINCREMENT;
lcd_writeCmd(LCD_ENTRYMODESET | lcd_DisplayMode);
}
void lcd_noAutoscroll(void)
{
lcd_DisplayMode &= ~LCD_ENTRYSHIFTINCREMENT;
lcd_writeCmd(LCD_ENTRYMODESET | lcd_DisplayMode);
}
void lcd_createChar(uint8_t location, uint8_t charmap[])
{
location &= 0x07; // we only have 8 locations 0-7
uint8_t i;
lcd_writeCmd(LCD_SETCGRAMADDR | (location << 3));
for (i = 0; i < 8; i++) {
lcd_writeData(charmap[i]);
}
}
void lcd_string(char *str)
{
uint8_t i;
for(i = 0; i < 16; i++) {
if(str[i] == 0x00) {
break;
} else {
lcd_writeData(str[i]);
}
}
}