WeMosを使ってみる

1602LCD+PCF8574


1602のLCDを使うときは定番のPCF8574(IOエクスパンダー)を使ってみます。
ESP8266でi2cを使う場合、Arduino CoreライブラリではSDA=GPIO4 SCL=GPIO5として定義されていますが、
他のGPIOもI2Cで使うことができ ます。

ESP8266では以下のコードは同じ結果になります。
Wire.begin()
Wire.begin(SDA, SCL)
Wire.begin(4, 5)

ESP8266のI2Cで使えるピンについてはこ ちらで詳しく紹介されています。(力作です)
GPIO15、GPIO16に関する記載が有りませんが、実際に確認したところ、GPIO15、GPIO16はi2cとして使えませんでした。

1602LCD+PCF8574を使う場合は、LiquidCrystal_I2Cライブラリと決まっているのですが、これがなかなか厄介です。
「LiquidCrystal_I2C arduino」のキーワードでGitHubを検索したらC++のライブラリだけで27のrepositoryが見つかりました。
SDAとSCLに好きなピンを指定できるライブラリかどうかは、ライブラリヘッダーを見ればわかります。

SDA=GPIO4 SCL=GPIO5に固定されるライブラリ
void LiquidCrystal_I2C::begin() {
    Wire.begin();

SDA SCLに任意のピンを使えるライブラリ
void LiquidCrystal_I2C::begin(uint8_t sda, uint8_t scl) {
    Wire.begin(sda,scl);


色々探した結果、この ライブラリが該当することが分かりました。

LiquidCrystal_I2Cライブラリを使った時の、PCF8574とLCDの結線には、以下の2パターンあることが分かっています。

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

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

ヘッダーファイル(LiquidCrystal_I2C.h)を確認しないと、どちらのパターンなのか分かりません。

#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

このライブラリはパターン2であることが分かりました。
ここまで調べて、ようやく結線は以下のようになります。
i2cのPullUp抵抗はなくても動くようです。

このライブラリはバックライトの制御を行うことができます。
PCF8574から供給できるのは25mA程度です。
PCF8574のP3からバックライトのアノード側に直接給電しても制御できますが、
トランジスタを使ってバックライトのカソード側をSWした方が安定して動きます。

PCF8574は5V駆動していますので、i2cは5Vでの制御となりますが、
ESP8266の全てのピンは5V TOLERANTです
i2cのレベルコンバータは必要ありません。
嘘だと思うなら「esp8266 5v tolerant」でググってみて下さい。



PCF8574 シリーズには PCF8574/PC8574P/PCF8574AP があります。
いずれも非常によく似たチップですが、i2cアドレスの範囲が違います。
Model address map
PCF8574 0x20-0x27
PCF8574P 0x20-0x27
PCF8574AP 0x38-0x3F

こちら
のスケッチでi2cアドレスを調べることができます。

WeMosのスケッチは以下の通りです。
今回使用したのはPCF8574Pなので、i2cアドレスは0x20となります。
SDAはGPIO_0(=D3)、SCLはGPIO_2(=D4)を使いました。
これらのピンはブートモードの決定に使われますが、i2cのSDA SCLとしても使うことができます。
/*
 * 1602 LCD Sample with LiquidCrystal_I2
 * https://github.com/agnunez/ESP8266-I2C-LCD1602
 *
 * PCF8574-----1602LCD-----WeMos
 * A0                 -----GND
 * A1                 -----GND
 * A2                 -----GND
 * VSS                -----GND
 * P0     ----- RS
 * P1     ----- RW
 * P2     ----- EN
 * P3     ----- B/L
 * P4     ----- D4
 * P5     ----- D5
 * P6     ----- D6
 * P7     ----- D7
 * VDD                -----5V
 *
 * SDA                -----D3(GPIO_0)
 * SCL                -----D4(GPIO_2)
 *
 */
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

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

void setup()
{
  lcd.begin(D3, D4);  // sda=GPIO_0, scl=GPIO_2
  // Print a message to the LCD.
  lcd.print("hello, world!");
}

void loop()
{
  // 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() / 1000);
}





MQTTと組み合わせれば、色々なマシンからWeMosに表示できるようになります。

続く...