Arduino(10) aitendoの激安キャラクタ液晶をArduino Pro Mini(3.3V)に接続

Arduino Pro MiniへSPI TFT LCDが割とあっさり接続できたので、ついでに買い置きしてあったaitendoのキャラクタ液晶「SPLC792-I2C-M」も接続してみました。

この液晶モジュールは8×8ドットのキャラクタを16字×2行で表示できるものです。
インタフェースはI2Cで、バックライトはLEDです。
価格が50% OFFとなっており、375円(税別)と激安です。
3.3V専用なので、Arduino UNOからはちょっと使いにくいですが、3.3V動作のPro Miniなら問題ありません。

というわけでさっそくピンヘッダを取り付けます。
ジャンパピンが2つ(写真の青い部品)ありますが、これで表示の向きを指定できます。

arduino10-01.jpg

接続は以下のようになります。
電源ラインを除けば、Arduinoの信号線で使うのはI2CのためのA4、A5だけです。
なお電源は、Arduinoに接続したUSBシリアルアダプタが供給する想定です。
また、バックライト(BL+端子)は、100Ωの抵抗を入れて3.3Vに接続しました。
明るさ的にはこれで室内なら十分だと思います。

Arduino Pro MiniのA4、A5端子にはピンヘッダを付けてしまいましたので、接続にブレッドボード用のオス-オス型のジャンパケーブルは使えません。
ブレッドボード側にもピンヘッダを挿して、ピンヘッダ間を接続するメス型コネクタ(デュポンコネクタとかQIコネクタといいます)が両端に付いたワイヤを使います。

arduino10-04.png

(参考→aitendoのI2C低電圧キャラクタ液晶モジュールをArduino Pro Mini(3.3V)で駆動(配線編) – M.C.P.C. (Mamesibori Creation Plus Communication)

ライブラリは先人が作られたものをありがたく使わせていただきました。

I2C液晶のArduinoライブラリ – ST7032 | オレ工房

他のライブラリ同様、ZIPファイルをIDEに取り込めば、スケッチ例も自動的に追加されます。

無事動作確認ができたところで、一応何か作ってみようということで、ありがちですが手元にあったDHT11センサモジュールを使って、温度湿度計を作ってみました。

arduino10-02.jpg

aitendoの商品ページからリンクされているLCDコントローラ(SPLC792A)の仕様書を見ていたら、キャラクタROMにはカタカナも含まれていることが分かったので、カタカナ表示させてみました。
文字コード表を下に引用しておきます。

splc792a.png

使った温度湿度センサモジュールは、よく見かけるDHT11というセンサを使用した、中国Keyes社のKY-015という型番のものです。

arduino10-07.jpg

DHT11をArduinoから使用するためのソフトウェアは、例によってAdafruit製のライブラリがあります。

adafruit/DHT-sensor-library · GitHub

配線は以下の通りです。
(KY-015用の配線です。DHT11を直接接続する場合は配線が異なりますのでご注意ください。)

arduino10-05.png

スケッチファイルも一応アップロードしておきます。

#include <Wire.h>
#include <ST7032.h>
#include <DHT.h>

#define DHTTYPE DHT11
#define DHTPIN 2

ST7032 lcd;
DHT dht(DHTPIN, DHTTYPE);
char str1[14] = {' ',' ',' ',' ',' ',0xdf,'C',' ','/',' ',' ',' ','%',0};
char str2[10] = {' ',' ',0xcc,0xb6,0xb2,0xbc,0xbd,0xb3,0x3a,0};

void setup() {
 lcd.begin(16, 2);
 lcd.setContrast(40);
 lcd.setCursor(0, 0);
 lcd.print(str1);
 lcd.setCursor(0, 1);
 lcd.print(str2);
 
 dht.begin();
}

void loop() {
 delay(2000);
 float h = dht.readHumidity();
 float t = dht.readTemperature();
 if (isnan(h) || isnan(t)) {
   Serial.println("Failed to read from DHT sensor!");
   return;
 }
 float discomfort = 0.81 * t + 0.01 * h * (0.99 * t - 14.3) +46.3;

 lcd.setCursor(3, 0);
 lcd.print(t,0);
 lcd.setCursor(10, 0);
 lcd.print(h,0);
 lcd.setCursor(10, 1);
 lcd.print(discomfort,1);
}

余談ですが、今回使用したセンサモジュールは、中国の通販サイトaliexpressから、Keyes社のモジュール全部入りセットで入手しました。
購入価格は$17(送料無料)でしたので、1モジュール当たり50円強ということになります。

Keyes社のモジュールの一覧は以下のサイトなどで見ることができます。

Arduino 37 sensors – TkkrLab
Advanced Sensors Kit for Arduino – LinkSprite Playgound

届いたものはこんな感じで、全てのモジュールがジップロックの袋に無造作に袋詰めされていました。

arduino10-06.jpg

ホール素子モジュールなどは重複気味ですし、ただのLEDとか、磁気に反応するリードスイッチや傾くと接続する水銀スイッチなどの懐かしいデバイスが多く、ジャイロやI2Cデバイスのような最近のものは入っていませんので、お買い得かといえば迷うところではあります。
しかしロータリーエンコーダやリレー、レーザー、ジョイスティックなど、それなりに使えそうなものもあり、自分で情報を調べて使うことができる人には便利かもしれません。

Arduino(9) Adafruit_ST7735ライブラリの修正(aitendoの1.8型LCD用)

arduino08-03.jpg
Adafruit_ST7735ライブラリ+aitendo M-Z18SPI-2Pでgraphicstest。
画面右端と下端にゴミが出ています。Hの字の左端が切れています。

Adafruit_ST7735ライブラリでaitendo M-Z18SPI-2Pを制御すると、画面右端と下端にゴミが残り、画面左端が欠けてしまいます。
初期化時、initRのパラメータにINITR_GREENTABを指定するとこの現象は無くなりますが、その代わり色の配列がRGBではなくBGRになってしまいます。

ST7735ではMADCTLというコマンドが色表現のRGB/BGR指定を担っており、これをINITR_BLACKTABのときだけ違う値に設定しているのが関数initRの中の最後の部分です。

void Adafruit_ST7735::initR(uint8_t options) {
    commonInit(Rcmd1);
    if(options == INITR_GREENTAB) {
        commandList(Rcmd2green);
        colstart = 2;
        rowstart = 1;
    } else if(options == INITR_144GREENTAB) {
        _height = ST7735_TFTHEIGHT_144;
        commandList(Rcmd2green144);
        colstart = 2;
        rowstart = 3;
    } else {
        // colstart, rowstart left at default '0' values                        
        commandList(Rcmd2red);
    }
    commandList(Rcmd3);

      // if black, change MADCTL color filter      
         if (options == INITR_BLACKTAB) {
             writecommand(ST7735_MADCTL);
             writedata(0xC0);
         }

                tabcolor = options;
}

これをINITR_GREENTABでも実行するように変更すれば、色がRGBの並びになります。

ただし、本家のINITR_GREENTABが違う動作になるのも困るので、新しくINITR_BLUETABを定義しました。

まずAdafruit_ST7735.hに以下の定義を追加します。(赤字部分)

// some flags for initR() :(
#define INITR_GREENTAB 0x0
#define INITR_REDTAB   0x1
#define INITR_BLACKTAB   0x2
#define INITR_BLUETAB 0x3

#define INITR_18GREENTAB    INITR_GREENTAB
#define INITR_18REDTAB      INITR_REDTAB
#define INITR_18BLACKTAB    INITR_BLACKTAB
#define INITR_144GREENTAB   0x1

そして、Adafruit_ST7735.cppのinitR関数を修正し、BLUETABではGREENTABの初期化+BLACKTAB用追加コードを実行するようにします。

void Adafruit_ST7735::initR(uint8_t options) {
    commonInit(Rcmd1);
    if((options == INITR_GREENTAB) || (options == \
INITR_BLUETAB)) {
            commandList(Rcmd2green);
            colstart = 2;
            rowstart = 1;
        } else if(options == INITR_144GREENTAB) {
        _height = ST7735_TFTHEIGHT_144;
        commandList(Rcmd2green144);
        colstart = 2;
        rowstart = 3;
    } else {
        // colstart, rowstart left at default '0' values                        
        commandList(Rcmd2red);
    }
    commandList(Rcmd3);

    // if black, change MADCTL color filter                                     
    if ((options == INITR_BLACKTAB)|| (options == \
INITR_BLUETAB)) {
            writecommand(ST7735_MADCTL);
            writedata(0xC0);
        }

    tabcolor = options;
}

これで、ノイズなし、かつ正しい色での表示ができるようになります。
(もちろん、setup()の中でinitRの引数をINITR_BLUETABにする必要があります。)

なお、以下のページにST7735の仕様の解説があり、参考になります。

表示器 (ST7735B 1.8″ TFT SPI)

・修正後のライブラリ+aitendo M-Z18SPI-2Pでgraphicstest

arduino08-04.jpg
ゴミが消え、画面の左端が見えるようになりました。

Arduino(8) Arduino Pro Mini+aitendoの1.8型LCDでブロック崩し

aitendoの1.8インチSPI LCDがPro mini(3.3V/8MHz)で動作するようになったので、先日UNOで作成したブロック崩しを動かしてみました。

基本的には、画面解像度の違いへの対応と、LCD初期化の処理を若干変更するだけて対応できました。

解像度の違いへの対応は、拡大率の変更で行います。
以前使っていた液晶の解像度は240×320ピクセルでしたが、この液晶は解像度が128×160ピクセルです。
ブロック崩しは、論理的な解像度を30×40として作成していますので、座標値を4倍にすればこの液晶にフルスクリーンで表示できます。
(横方向は120ピクセルになるので、8ピクセル余ってしまいますが。)

LCD初期化処理は、Adafruit-TFTLibraryと今回使うAdafruit_ST7735でスケッチ例を見比べて、以下のように修正しました。

・includeするライブラリおよび信号線の定義
(当然ですね。)

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>

#define TFT_CS     10
#define TFT_RST    9
#define TFT_DC     8
#define TFT_SCLK 13   // set these to be whatever pins you like!
#define TFT_MOSI 11   // set these to be whatever pins you like!

・初期化シーケンス

void setup(void) {
tft.initR(INITR_GREENTAB);   // initialize a ST7735S chip, green tab
tft.fillScreen(BLACK);

gameStatus = GAME_RESTART;
BallInit(ball);
}

1行目のinitRの引数になっている「INITR_GREENTAB」は、液晶モジュールのバージョンによって、異なる値を与えなければならないようです。

Adafruit_ST7735の現状のヘッダファイルでは、この引数に使える値は「INITR_BLACKTAB」「INITR_GREENTAB」「INITR_REDTAB」の3種類が定義されています。
この値によって、液晶コントローラに送られる初期化コマンド列が変わります。

液晶モジュールの種類をどう見分けるかですが、この「BLACK」「GREEN」「RED」は液晶パネルの保護シールの引き剥がし用の耳(tab)の色なのだそうです。
少し昔のバージョンのAdafruit_ST7735を使ったスケッチ例を見ると、コメントでそのように記載されていました。
以下引用です。

  // Our supplier changed the 1.8" display slightly after Jan 10, 2012
// so that the alignment of the TFT had to be shifted by a few pixels
// this just means the init code is slightly different. Check the
// color of the tab to see which init code to try. If the display is
// cut off or has extra 'random' pixels on the top & left, try the
// other option!
// If you are seeing red and green color inversion, use Black Tab

// If your TFT's plastic wrap has a Black Tab, use the following:
tft.initR(INITR_BLACKTAB);   // initialize a ST7735S chip, black tab
// If your TFT's plastic wrap has a Red Tab, use the following:
//tft.initR(INITR_REDTAB);   // initialize a ST7735R chip, red tab
// If your TFT's plastic wrap has a Green Tab, use the following:
//tft.initR(INITR_GREENTAB); // initialize a ST7735R chip, green tab

今回使用した液晶はAdafruitの製品ではありませんが、青緑色のプルタブが付いていました。

arduino08-02.jpg

Adafruit製品のLCDモジュールと今回のaitendoのLCDモジュールが同一サプライヤの製品であるかどうかは定かではありません。
ネットの情報では、緑のタブの製品でもINITR_BLACKTABを指定すると正しく動いた、という例もあるようで、結局3種類を試して一番正常なものを選ぶのが良さそうです。

ちなみに私が試したところ、今回のaitendoの液晶モジュールは

・INITR_BLACKTAB・・・画面の下端と右端にランダムな色のノイズピクセルが出る。
上端と左端が2ピクセルほど切れる。
(aitendoの商品ページでもそうなっています)

・INITR_REDTAB・・・画面の下半分が表示されない。

・INITR_GREENTAB・・・ピクセルは表示されるが、色指定がRGBではなくBGRとなる。

となりました。

ピクセルが正常に表示されるのは、INITR_GREENTABですが、赤と青が入れ替わるので、まったく違う色調になってしまいます。

今回のブロック崩しは、もともとカラーを8色しか使っていないので、この問題へはスケッチファイル側で色の定義を変更することで対応しました。
スケッチファイル側を変更したくない場合は、ライブラリのソースコード(Adafruit_ST7735.cpp)を編集することで対応することもできます。
ライブラリの修正部分は別記事で載せておきます。

配線は、下図のようにしました。
コントローラ用の可変抵抗器はA1、圧電ブザーは3番の信号線を使用しています。
液晶への配線は前回と変わっていません。

arduino08-01.png

以上の変更を反映したスケッチファイルと、動作の様子は以下の通りです。