「I2C LCD Breakout」を使ってみた!

投稿者:

「Maker Conference Tokyo2013」のスイッチサイエンスブースで参考出品していた「I2C接続の小型LCDボード」が発売されました!
I2C_LCD(5V)版:http://www.switch-science.com/catalog/1407/
I2C_LCD(3.3V)版:http://www.switch-science.com/catalog/1405/

今回は「Arduinoとの接続」と「ちょっとした表示」をしてみました。

この商品でできる事

  • 横8文字×縦2行表示可能なキャラクター液晶です。
  • 1キャラクターは横5×縦8ドットです。
  • 数字と英文字(大小)とちょっとした記号とカタカナが登録されています。
  • 上記以外に6キャラクター登録可能です。
  • プログラムからコントラストが変えられます。


接続は写真の通り「これだけ」です。
#5V(または3.3V),GND,SDA(ArduinoのA4),SCL(ArduinoのA5)があれば大丈夫です
#今回はArduinoのA2を5V、ArduinoのA3をGNDとして使っています
#RESET(ArduinoのA1)は何もしていません

《2015/07/22 追記》
I2Cの信号はA4とA5端子と接続されています。この記事が書かれた時点ではArduino Uno R3が出ていなかったため説明がないのですが、Uno R3でもSDAピンとA4ピン、SCLピンとA5ピンは接続されており、SDA/SCL、A4/A5のどちらでもI2C通信を行えます。
《追記おわり》

まず最初に文字を出してみましょう。

#include <Wire.h>

#define vddPin 16    // ArduinoA2
#define gndPin 17    // ArduinoA3
#define sdaPin 18    // ArduinoA4
#define sclPin 19    // ArduinoA5
#define I2Cadr 0x3e  // 固定
byte contrast = 35;  // コントラスト(0~63)

void setup() {
  pinMode(gndPin, OUTPUT);
  digitalWrite(gndPin, LOW);
  pinMode(vddPin, OUTPUT);
  digitalWrite(vddPin, HIGH);
  delay(500);
  Wire.begin();
  lcd_cmd(0b00111000); // function set
  lcd_cmd(0b00111001); // function set
  lcd_cmd(0b00000100); // EntryModeSet
  lcd_cmd(0b00010100); // interval osc
  lcd_cmd(0b01110000 | (contrast & 0xF)); // contrast Low
  lcd_cmd(0b01011100 | ((contrast >> 4) & 0x3)); // contast High/icon/power
  lcd_cmd(0b01101100); // follower control
  delay(200);
  lcd_cmd(0b00111000); // function set
  lcd_cmd(0b00001100); // Display On
  lcd_cmd(0b00000001); // Clear Display
  delay(2);
}

void loop() {
  lcd_setCursor(0, 0);
  lcd_printStr("SWITCH");
  lcd_setCursor(1, 1);
  lcd_printStr("SCIENCE");
  delay(100);
}

void lcd_cmd(byte x) {
  Wire.beginTransmission(I2Cadr);
  Wire.write(0b00000000); // CO = 0,RS = 0
  Wire.write(x);
  Wire.endTransmission();
}

void lcd_contdata(byte x) {
  Wire.write(0b11000000); // CO = 1, RS = 1
  Wire.write(x);
}

void lcd_lastdata(byte x) {
  Wire.write(0b01000000); // CO = 0, RS = 1
  Wire.write(x);
}

// 文字の表示
void lcd_printStr(const char *s) {
  Wire.beginTransmission(I2Cadr);
  while (*s) {
    if (*(s + 1)) {
      lcd_contdata(*s);
    } else {
      lcd_lastdata(*s);
    }
    s++;
  }
  Wire.endTransmission();
}

// 表示位置の指定
void lcd_setCursor(byte x, byte y) {
  lcd_cmd(0x80 | (y * 0x40 + x));
}

それでは実行してみましょう。
画面に「SWITCH SCIENCE」と表示されましたか?

次はコントラストを変えてみましょう。
setup()の上に下記を挿入して下さい。

boolean contrastFlag = false;

delay(100);の上に下記を挿入して下さい。

  if (contrastFlag == false) {
    if (++contrast >= 63) {
      contrastFlag = true;
    }
  } else {
    if (--contrast <= 0) {
      contrastFlag = false;
    }
  }
  lcd_setContrast(contrast);

スケッチの一番後ろに下記を付け加えて下さい。

// コントラストの変更
void lcd_setContrast(byte c) {
  lcd_cmd(0x39);
  lcd_cmd(0b01110000 | (c & 0x0f)); // contrast Low
  lcd_cmd(0b01011100 | ((c >> 4) & 0x03)); // contast High/icon/power
  lcd_cmd(0x38);
}

#念のため、この記事の最後にスケッチを貼っておきます
それでは実行してみましょう。

「白画面から文字が現れ黒画面へと消えていく、黒画面から文字が現れ白画面へと消えていく」この動作が繰り返させるようになりましたか?

上記サンプルにより「初期化(setup)」や「文字の表示(lcd_printStr)」「文字位置の指定(lcd_setCursor)」「コントラストの変更(lcd_setContrast)」が出来るようになったのではないでしょうか?

今回はライブラリ化していないので使い勝手が悪かったですかね?
#どなたかライブラリ化していただけると嬉しい限りです!

私はちょっとしたデバックの表示とかに使っています。

#以下、コントラストを変える変更済みのスケッチです

#include <Wire.h>

#define vddPin 16    // ArduinoA2
#define gndPin 17    // ArduinoA3
#define sdaPin 18    // ArduinoA4
#define sclPin 19    // ArduinoA5
#define I2Cadr 0x3e  // 固定
byte contrast = 35;  // コントラスト(0~63)
boolean contrastFlag = false;

void setup() {
  pinMode(gndPin, OUTPUT);
  digitalWrite(gndPin, LOW);
  pinMode(vddPin, OUTPUT);
  digitalWrite(vddPin, HIGH);
  delay(500);
  Wire.begin();
  lcd_cmd(0b00111000); // function set
  lcd_cmd(0b00111001); // function set
  lcd_cmd(0b00000100); // EntryModeSet
  lcd_cmd(0b00010100); // interval osc
  lcd_cmd(0b01110000 | (contrast & 0xF)); // contrast Low
  lcd_cmd(0b01011100 | ((contrast >> 4) & 0x3)); // contast High/icon/power
  lcd_cmd(0b01101100); // follower control
  delay(200);
  lcd_cmd(0b00111000); // function set
  lcd_cmd(0b00001100); // Display On
  lcd_cmd(0b00000001); // Clear Display
  delay(2);
}

void loop() {
  lcd_setCursor(0, 0);
  lcd_printStr("SWITCH");
  lcd_setCursor(1, 1);
  lcd_printStr("SCIENCE");
  if (contrastFlag == false) {
    if (++contrast >= 63) {
      contrastFlag = true;
    }
  } else {
    if (--contrast <= 0) {
      contrastFlag = false;
    }
  }
  lcd_setContrast(contrast);
  delay(100);
}

void lcd_cmd(byte x) {
  Wire.beginTransmission(I2Cadr);
  Wire.write(0b00000000); // CO = 0,RS = 0
  Wire.write(x);
  Wire.endTransmission();
}

void lcd_contdata(byte x) {
  Wire.write(0b11000000); // CO = 1, RS = 1
  Wire.write(x);
}

void lcd_lastdata(byte x) {
  Wire.write(0b01000000); // CO = 0, RS = 1
  Wire.write(x);
}

// 文字の表示
void lcd_printStr(const char *s) {
  Wire.beginTransmission(I2Cadr);
  while (*s) {
    if (*(s + 1)) {
      lcd_contdata(*s);
    } else {
      lcd_lastdata(*s);
    }
    s++;
  }
  Wire.endTransmission();
}

// 表示位置の指定
void lcd_setCursor(byte x, byte y) {
  lcd_cmd(0x80 | (y * 0x40 + x));
}
void lcd_setContrast(byte c) {
  lcd_cmd(0x39);
  lcd_cmd(0b01110000 | (c & 0x0f)); // contrast Low
  lcd_cmd(0b01011100 | ((c >> 4) & 0x03)); // contast High/icon/power
  lcd_cmd(0x38);
}