ATtiny+PCF8574でLCDを使う(LiquidCrystal_I2C library for the ATtiny)


ATtinyでのi2c通信を調べていたら、ATtiny+PCF8574(IOエクスパンダー)で
1602のLCDを使えることが分かりましたので紹介します。

PCF8574の DIPパッケージには PCF8574P と PCF8574AP があります。
どちらも非常によく似たチップですが、i2cアドレスが違います。
PCF8574P   address map 0x20-0x27
PCF8574AP address map 0x38-0x3f

こちらに 日本語のカタログが公開されています。
PCF8574 と PCF8574A はi2cアドレス以外にどこが違うのか、見ても分かりませんでした。

i2cアドレスを調べる方法はこ ちらで紹介されています。

<PCF8574P>


<PCF8574AP>


PCF8574で1602のLCDを使うためのライブラリは沢山あります。
しかもほとんどが LiquidCrystal_I2C.h と LiquidCrystal_I2C.cpp という名前のライブラリで
とっても紛らわしいです。

以下のキーワードでGitHubを検索したら16のrepositoryが見つかりました。
LiquidCrystal_I2C arduino
おそらくみんな、少しずつ違うのでしょう.....

ATtinyで使えるライブラリも以下の3つがあります。(探せばもっとあるかもしれません)

@modified LiquidCrystal_I2C library for the ATtiny(LiquidCrystal_I2C.h と LiquidCrystal_I2C.cpp)

ADigisparkArduinoIntegration/libraries/DigisparkLCD(LiquidCrystal_I2C.h と LiquidCrystal_I2C.cpp)

Bplatisd/ATtiny85-LCD-library(LiquidCrystal_attiny.h と LiquidCrystal_attiny.cpp)

これらの違いはPCF8574とLCDの結線の違いです。
ライブラリが対応しているPCF8574とLCDの結線には、以下の2パターンがあります。

パターン1(@)
LCD D4 D5 D6 D7 EN RW RS B/L
PCF8574 P0 P1 P2 P3 P4 P5 P6 P7

パターン2(AとB)
LCD RS RW EN B/L D4 D5 D6 D7
PCF8574 P0 P1 P2 P3 P4 P5 P6 P7

B/L=バックライト

厄介なことに、この違いはヘッダーファイルのdefineを見ないとわかりません。

@modified LiquidCrystal_I2C library for the ATtiny
#define LCD_BACKLIGHT 0x00
#define LCD_NOBACKLIGHT 0x80
#define En B00010000  // Enable bit
#define Rw B00100000  // Read/Write bit
#define Rs B01000000  // Register select bit


ADigisparkArduinoIntegration/libraries/DigisparkLCD
#define LCD_BACKLIGHT 0x08
#define LCD_NOBACKLIGHT 0x00
#define En B00000100  // Enable bit
#define Rw B00000010  // Read/Write bit
#define Rs B00000001  // Register select bit


BATtiny85-LCD-library
#define LCD_BACKLIGHT 0x08
#define LCD_NOBACKLIGHT 0x00
#define En B00000100  // Enable bit
#define Rw B00000010  // Read/Write bit
#define Rs B00000001  // Register select bit


AとBはファイル名だけの違いで内容は実質同じ(Aは一部のATtinyとATmegaをサポート、BはATtiny専用)です。
そこで、今回はこちらのペー ジで紹介されている「modified LiquidCrystal_I2C library for the ATtiny」を紹介します。

こ ちらから「LiquidCrystal_I2C_85V1.zip」をダウンロードし、
展開したらフォルダーごとライブラリーフォルダーに移動します。
ライブラリソースを確認しましたが、ATtiny85 と ATtiny2313 しか対応していないので、
LiquidCrystal_I2C.h と LiquidCrystal_I2C.cpp を一部変更します。

修正前(抜粋)
#if defined(__AVR_ATtiny85__) || (__AVR_ATtiny2313__)

修正後(抜粋)
//#if defined(__AVR_ATtiny85__) || (__AVR_ATtiny2313__)
#if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny861__) || (__AVR_ATtiny4313__)

同じコードが何箇所かありますので、使用するマイコンに合わせて全て修正してください。
これで以下のスケッチが動くようになります。
なお、i2cアドレスは「PCF8574P」の場合は0x20、「PCF8574AP」の場合は0x38を指定してください。

/*
 * 1602 LCD Sample with LiquidCrystal_I2C_85V1.zip
 * http://playground.arduino.cc/uploads/Code/LiquidCrystal_I2C_85V1.zip
 *
 * PCF8574-----1602LCD-----TINY
 * A0                 -----GRD
 * A1                 -----GRD
 * A2                 -----GRD
 * P0     ----- D4
 * P1     ----- D5
 * P2     ----- D6
 * P3     ----- D7
 * VSS                -----GRD
 * P4     ----- EN
 * P5     ----- RW
 * P6     ----- RS
 * P7     ----- N/C
 * VDD                -----5V
 *
 * PCF8574-----1602LCD-----ATTiny85
 * SDA                -----PB0
 * SCL                -----PB2
 *
 * PCF8574-----1602LCD-----ATTiny84
 * SDA                -----PA6
 * SCL                -----PA4
 *
 * PCF8574-----1602LCD-----ATTiny861
 * SDA                -----PB0
 * SCL                -----PB2
 *
 * PCF8574-----1602LCD-----ATTiny4313
 * SDA                -----PB5
 * SCL                -----PB7
 */

#include <TinyWireM.h>
#include <LiquidCrystal_I2C.h>

#define i2cAddress 0x20

LiquidCrystal_I2C lcd(i2cAddress,16,2); // set the LCD address to 0x20 for a 16 chars and 2 line display

void setup()
{
    lcd.init(); // initialize the lcd
}

void loop()
{
  static int number=0;
  char buf[21];

  if (number < 100) {
    lcd.setCursor(0, 0);
  // Print a message to the LCD.
    sprintf(buf,"Hello, World %03d!",number++);
    lcd.print(buf);

  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
    lcd.setCursor(0, 1);
  // print the number of seconds since reset:
    lcd.print(millis());
  }
}


【ATtiny84@1MHz】
以下の結線で上記のスケッチが動きます。
FemtoCowのAddOnを使ってコンパイルしています。



【ATtiny85@1MHz】
以下の結線で上記のスケッチが動きます。



【ATtiny861@1Mhz】
以下の結線で上記のスケッチが動きます。



【ATtiny4313@1MHz】
以下の結線で上記のスケッチが動きます。



モデルごとのパフォーマンスは以下の様に全てのモデルで同じ結果となりました。

モデル 処理時間(ミリ秒) ShiftLCD_SPIの処理時間
ATtiny84 12869 13129
ATtiny85 12869 12492
ATtiny861 12869 12492
ATtiny4313 12869 12492

こちらで紹介しているSPI-USIといい勝負だ と いうことが分かりました。

続く....