お父にゃんの電子工作 -35ページ目

お父にゃんの電子工作

暇なおじさんが、電子工作(主にラジオ製作)をして勝手な感想を書く

注文しておいた2インチカラーLCDが届いたので、早速試してみたい。

 

送料込みで882円だった。

 

動かすにあたっては、こちらのページ↓を参考にさせていただいた。

 

ドライバICはST7789Vというものが使われている。

こちらに対応したライブラリをArduino IDEにインストールする。

 

ライブラリマネージャーからST7789を検索して、Adafruit版をインストール。

依存関係もインストールするかと聞かれたので、全部インストール。

 

このように接続した。

 

テストプログラムはこちら

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>
#include <efontEnableJa.h>
//#include <efontEnableJaMini.h>
#include <efont.h>
 
#define SCREEN_WIDTH 320  //OLED 幅指定
String neko;
String neko_full;
String title;
 
#define TFT_CS    44
#define TFT_RST   6
#define TFT_DC    43
#define TFT_MOSI  9
#define TFT_SCK   7
 
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
//S/W SPIはこちら。遅いが任意のピンを使用できる。
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCK, TFT_RST);
 
void setup(void) {
 
  neko = "吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。";
  neko += "何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。";
 
  neko_full = neko;
  neko_full += "吾輩はここで始めて人間というものを見た。";
  neko_full += "しかもあとで聞くとそれは書生という人間中で一番獰悪な種族であったそうだ。";
  neko_full += "この書生というのは時々我々を捕えて煮て食うという話である。";
  neko_full += "しかしその当時は何という考もなかったから別段恐しいとも思わなかった。";
  neko_full += "ただ彼の掌に載せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。";
  neko_full += "掌の上で少し落ちついて書生の顔を見たのがいわゆる人間というものの見始であろう。";
 
  SPI.begin(TFT_SCK, -1, TFT_MOSI, TFT_CS);
  tft.init(240, 320);           // Init ST7789 320x240
  tft.setRotation(1);           //画面回転
 
}
 
void loop(){
  tft.fillScreen(ST77XX_BLACK); //背景の塗りつぶし
 
  //テキスト表示
  tft.setTextSize(3);           //サイズ
 
  tft.setCursor(0, 0);          //カーソル位置                      
  tft.setTextColor(ST77XX_WHITE);   //白
  tft.println("ST7789 240 x 320");
  tft.println("2inch LCD");
  tft.setTextColor(ST77XX_RED);     //赤
  tft.println("ABCDEFGHIJKLMNOPQ");
  tft.setTextColor(ST77XX_GREEN);   //緑
  tft.println("ABCDEFGHIJKLMNOPQ");
  tft.setTextColor(ST77XX_BLUE);    //青
  tft.println("ABCDEFGHIJKLMNOPQ");
  tft.setTextColor(ST77XX_CYAN);    //シアン
  tft.println("ABCDEFGHIJKLMNOPQ");
  tft.setTextColor(ST77XX_MAGENTA); //マゼンタ
  tft.println("ABCDEFGHIJKLMNOPQ");
  tft.setTextColor(ST77XX_YELLOW);  //黄色
  tft.println("ABCDEFGHIJKLMNOPQ");
  tft.setTextColor(ST77XX_ORANGE);  //オレンジ
  tft.println("ABCDEFGHIJKLMNOPQ");
  tft.setTextColor(ST77XX_WHITE);   //白
  tft.println("ABCDEFGHIJKLMNOPQ");
 
  delay(7000);
 
  tft.fillScreen(ST77XX_BLACK);         //背景の塗りつぶし
  const char* str2 = neko_full.c_str(); //吾輩は猫 long
  printEfont(0,0,1,ST77XX_WHITE,str2);  //efont標準サイズ
 
  delay(7000);
 
  tft.fillScreen(ST77XX_BLACK);         //背景の塗りつぶし
  const char* str = neko.c_str();       //吾輩は猫 short
  printEfont(0,0,2,ST77XX_WHITE,str);   //efont倍角
 
  delay(7000);
}
//
//efont 文字列を表示する
//
void printEfont(int16_t x, int16_t y, int16_t txtsize,uint16_t color,const char *str) {
  int posX = x;
  int posY = y;
  int16_t textsize = txtsize;
  uint16_t textcolor = color;
 
  uint8_t font[32];
  const char *p = str;  // 一時変数を用意
 
  while (*p != 0x00) {
    // 改行処理
    if (*p == '\n') {
      posY += 16;
      posX += 16;
      p++;
      continue;
    }
    // フォント取得
    uint16_t strUTF16;
    p = efontUFT8toUTF16(&strUTF16, const_cast<char*>(p)); // `p` を更新する
 
    getefontData(font, strUTF16);
   
    // 文字横幅
    int width = 16 * textsize;
    if( strUTF16 < 0x0100 ){
      // 半角
      width = 8 * textsize;
    }
    // 折返し処理
    if (posX >= SCREEN_WIDTH | (posX+width) > SCREEN_WIDTH) {
      posX = 0;
      posY += 16* textsize;
    }
    // 取得フォントの確認
    for (uint8_t row = 0; row < 16; row++) {
      word fontdata = font[row * 2] * 256 + font[row * 2 + 1];
      for (uint8_t col = 0; col < 16; col++) {
        if ((0x8000 >> col) & fontdata) {
          int drawX = posX + col * textsize;;
          int drawY = posY + row * textsize;;
          if( textsize == 1 ){
            tft.drawPixel(drawX, drawY, textcolor);
          } else {
            tft.fillRect(drawX, drawY, textsize, textsize, textcolor);
          }
        }
      }
    }
    // 描画カーソルを進める
    posX += width;
  }
  // カーソルを更新
  tft.setCursor(posX, posY);
}

 

ちゃんと動いた。

 

カラー表示

組み込み用のLCDなんて、どうせにじんだような画質だろうと思っていたが、結構くっきりはっきり表示してくれた。

 

efontで16×16サイズで日本語表示。

2インチ画面でこの文字数だと、肉眼では小さすぎて、おじさんの眼では厳しい。

 

efontを縦横倍角(32x32)にして表示。

大きくて、おじさんの眼でも読みやすいが、これでは文字数が少なくてOLEDの128×128で表示したのと大差ない。

 

試しに、Webラジオをイメージした画面を表示させてみる。

テストプログラムはこちら↓

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>
#include <efontEnableJa.h>
//#include <efontEnableJaMini.h>
#include <efont.h>
 
#define SCREEN_WIDTH 320  //OLED 幅指定
String neko;
String neko_full;
String title;
 
#define TFT_CS    44
#define TFT_RST   8
#define TFT_DC    43
#define TFT_MOSI  9
#define TFT_SCK   7
 
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
//S/W SPIはこちら。遅いが任意のピンを使用できる。
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCK, TFT_RST);
 
void setup(void) {
 
  title ="マンハッタンカフェ(CV.小倉唯)、エアシャカール(CV.津田美波)、ナイスネイチャ(CV.前田佳織里) - うまぴょい伝説";
 
  SPI.begin(TFT_SCK, -1, TFT_MOSI, TFT_CS);
  tft.init(240, 320);              // Init ST7789 320x240
  tft.setRotation(1);              //画面回転
 
  tft.fillScreen(ST77XX_BLACK);    //背景の塗りつぶし
 
  tft.setCursor(0, 0);              //カーソル位置
  tft.setTextColor(ST77XX_YELLOW);  //黄色
  tft.setTextSize(5);  
  tft.print("Ch:102");
 
  tft.setTextColor(ST77XX_WHITE);   //白
  tft.setTextSize(3);
  tft.setCursor(200, 0);
  tft.print("Vol:15");
 
  tft.setTextColor(ST77XX_WHITE);      //白
  tft.setCursor(200, 24);
  tft.setTextSize(2);
  tft.print("128 Kbps");
 
  tft.drawLine(0, 42, 320, 42, ST77XX_RED);
 
  const char* str2 = "Radio Paradise Mellow Mix 320k aac";
  printEfont(0,44,2,ST77XX_GREEN,str2);   //倍角
 
  tft.drawLine(0, 110, 320, 110, ST77XX_RED);
 
  const char* str3 = title.c_str();
  printEfont(0,112,2,ST77XX_WHITE,str3);   //倍角
 
}
 
void loop(){
}
 
//
//efont 文字列を表示する
//
void printEfont(int16_t x, int16_t y, int16_t txtsize,uint16_t color,const char *str) {
  int posX = x;
  int posY = y;
  int16_t textsize = txtsize;
  uint16_t textcolor = color;
 
  uint8_t font[32];
  const char *p = str;  // 一時変数を用意
 
  while (*p != 0x00) {
    // 改行処理
    if (*p == '\n') {
      posY += 16;
      posX += 16;
      p++;
      continue;
    }
    // フォント取得
    uint16_t strUTF16;
    p = efontUFT8toUTF16(&strUTF16, const_cast<char*>(p)); // `p` を更新する
 
    getefontData(font, strUTF16);
   
    // 文字横幅
    int width = 16 * textsize;
    if( strUTF16 < 0x0100 ){
      // 半角
      width = 8 * textsize;
    }
    // 折返し処理
    if (posX >= SCREEN_WIDTH | (posX+width) > SCREEN_WIDTH) {
      posX = 0;
      posY += 16* textsize;
    }
    // 取得フォントの確認
    for (uint8_t row = 0; row < 16; row++) {
      word fontdata = font[row * 2] * 256 + font[row * 2 + 1];
      for (uint8_t col = 0; col < 16; col++) {
        if ((0x8000 >> col) & fontdata) {
          int drawX = posX + col * textsize;;
          int drawY = posY + row * textsize;;
          if( textsize == 1 ){
            tft.drawPixel(drawX, drawY, textcolor);
          } else {
            tft.fillRect(drawX, drawY, textsize, textsize, textcolor);
          }
        }
      }
    }
    // 描画カーソルを進める
    posX += width;
  }
  // カーソルを更新
  tft.setCursor(posX, posY);
}

 

こんな感じ

 

画面拡大

まぁ、こんなもんだろうか? 画素数が増えたわりには、OLEDで組んだ時と情報量が変わらない。24×24のfontを使うとかすれば良いかもしれないが、データ量がかなり増えるのでそれはまた困る。一旦これで、Webラジオ2号機をつくってみることにする。

 

なお、この2インチLCDではバックライトLED端子が出ていないのでPWM制御などでバックライト調整は出来ない。ちょっと寂しい。

 

参考までに消費電流はLCD有りと無しで12mAくらいの差だった。5Vラインでの電流差なのだが、ESP32S3内部のレギュレーターはおそらくLDOなので、電流値は変わらずLCDの消費電流は12mAくらいとみていいと思う。液晶なのでほとんどがバックライトLEDの電流だろう。

(5/17修正:あとで測ると電流値は56mAでした・・・)

 

 

「まぁ、にゃんでも試してみるのニャ」