秋月の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]);
    }
  }
}