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

お父にゃんの電子工作

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

前回まで2インチのSPI接続のカラーLCDを使ってWebラジオを作ってみた。

これはこれで、良い感じなのである。

 

でも、暇なおじさんはAli-Expressで もうちょっと大きめの2.4インチカラーLCDを見つけてしまった。しかも、なぜか2インチよりも安かったのでポチッとしてしまったのである。

 

 

キャンペーンで他の部品も買ったので送料無料で480円で入手できた。

 

ちょっと大きさを比較したくて、2インチ版と2.4インチ版の両方を表示させてみる。

どちらもST7789を使っているので、全く同じに動作させることが出来る。

 

CPUボードは去年Ali-Expressで買っておいたRP-2040-ZERO(もどき)↓

 

とても安くてRaspberry Pi Picoの小型版として動作させることが出来る。

Arduino(C/C++)や、MicroPythonでも書くことが出来る。

 

テスト用の回路図↓

SPIのCS端子のみ別配線とすることで、1つのSPIポートから複数の機器を接続することが出来る。

今回、LCDのリセット端子は使わず3.3Vに繋いだ。

最初は、リセット端子も共有して同じポートにつないでいたのだが、2台目のLCDを初期化する時に初期化済みの1台目のLCDも再度リセットしてしまうので1台目が動作しなくなってしまう。

リセット端子を使う場合は、こちらもポートを別にする必要がある。

 

テスト用のスケッチはこちら

#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_CS1   2
#define TFT_CS2   8
#define TFT_RST   -1  //未使用
#define TFT_DC    3
#define TFT_MOSI  7
#define TFT_SCK   6
 
Adafruit_ST7789 tft1 = Adafruit_ST7789(TFT_CS1, TFT_DC, TFT_RST);
Adafruit_ST7789 tft2 = Adafruit_ST7789(TFT_CS2, 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.setSCK(TFT_SCK);
  SPI.setTX(TFT_MOSI);
  SPI.begin();
 
  // 1台目初期化
  tft1.init(240, 320); //
  tft1.setRotation(3);
 
  // 2台目初期化
  tft2.init(240, 320);
  tft2.setRotation(3);
}
 
void loop(){
  tft1.fillScreen(ST77XX_BLACK); //背景の塗りつぶし
  tft2.fillScreen(ST77XX_BLACK);
 
  //テキスト表示
  tft1.setTextSize(3);           //サイズ
 
  tft1.setCursor(0, 0);          //カーソル位置                      
  tft1.setTextColor(ST77XX_WHITE);   //白
  tft1.println("ST7789 240 x 320");
  tft1.println("2inch LCD");
  tft1.setTextColor(ST77XX_RED);     //赤
  tft1.println("ABCDEFGHIJKLMNOPQ");
  tft1.setTextColor(ST77XX_GREEN);   //緑
  tft1.println("ABCDEFGHIJKLMNOPQ");
  tft1.setTextColor(ST77XX_BLUE);    //青
  tft1.println("ABCDEFGHIJKLMNOPQ");
  tft1.setTextColor(ST77XX_CYAN);    //シアン
  tft1.println("ABCDEFGHIJKLMNOPQ");
  tft1.setTextColor(ST77XX_MAGENTA); //マゼンタ
  tft1.println("ABCDEFGHIJKLMNOPQ");
  tft1.setTextColor(ST77XX_YELLOW);  //黄色
  tft1.println("ABCDEFGHIJKLMNOPQ");
  tft1.setTextColor(ST77XX_ORANGE);  //オレンジ
  tft1.println("ABCDEFGHIJKLMNOPQ");
  tft1.setTextColor(ST77XX_WHITE);   //白
  tft1.println("ABCDEFGHIJKLMNOPQ");
 
  tft2.setTextSize(3);           //サイズ
 
  tft2.setCursor(0, 0);          //カーソル位置                      
  tft2.setTextColor(ST77XX_WHITE);   //白
  tft2.println("ST7789 240 x 320");
  tft2.println("2inch LCD");
  tft2.setTextColor(ST77XX_RED);     //赤
  tft2.println("ABCDEFGHIJKLMNOPQ");
  tft2.setTextColor(ST77XX_GREEN);   //緑
  tft2.println("ABCDEFGHIJKLMNOPQ");
  tft2.setTextColor(ST77XX_BLUE);    //青
  tft2.println("ABCDEFGHIJKLMNOPQ");
  tft2.setTextColor(ST77XX_CYAN);    //シアン
  tft2.println("ABCDEFGHIJKLMNOPQ");
  tft2.setTextColor(ST77XX_MAGENTA); //マゼンタ
  tft2.println("ABCDEFGHIJKLMNOPQ");
  tft2.setTextColor(ST77XX_YELLOW);  //黄色
  tft2.println("ABCDEFGHIJKLMNOPQ");
  tft2.setTextColor(ST77XX_ORANGE);  //オレンジ
  tft2.println("ABCDEFGHIJKLMNOPQ");
  tft2.setTextColor(ST77XX_WHITE);   //白
  tft2.println("ABCDEFGHIJKLMNOPQ");
 
  delay(7000);
 
  tft1.fillScreen(ST77XX_BLACK);         //背景の塗りつぶし
  tft2.fillScreen(ST77XX_BLACK);         //背景の塗りつぶし
  const char* str2 = neko_full.c_str(); //吾輩は猫 long
  printEfont(0,0,1,ST77XX_WHITE,str2);  //efont標準サイズ
  printEfont2(0,0,1,ST77XX_WHITE,str2);  //efont標準サイズ
 
  delay(7000);
 
  tft1.fillScreen(ST77XX_BLACK);         //背景の塗りつぶし
  tft2.fillScreen(ST77XX_BLACK);         //背景の塗りつぶし
  const char* str = neko.c_str();       //吾輩は猫 short
  printEfont(0,0,2,ST77XX_WHITE,str);   //efont倍角
  printEfont2(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 ){
            tft1.drawPixel(drawX, drawY, textcolor);
          } else {
            tft1.fillRect(drawX, drawY, textsize, textsize, textcolor);
          }
        }
      }
    }
    // 描画カーソルを進める
    posX += width;
  }
  // カーソルを更新
  tft1.setCursor(posX, posY);
}
//
//
void printEfont2(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 ){
            tft2.drawPixel(drawX, drawY, textcolor);
          } else {
            tft2.fillRect(drawX, drawY, textsize, textsize, textcolor);
          }
        }
      }
    }
    // 描画カーソルを進める
    posX += width;
  }
  // カーソルを更新
  tft2.setCursor(posX, posY);
}

 

 

ブレッドボードでこんな感じ

 

 

写真だと分かりにくいが、2.4インチの方が暗い

2インチ版の方が明るくて、発色も良い感じがする

 

白文字で表示しているが、2.4インチ版の方がやや暗くて青い

2インチ版は、はっきりした白で表示してくれる。

しかし、16×16フォントだと、2インチ版では、おじさん的にはつらいが、2.4インチ版だと読みやすい。明るさも文字を読む分には、このくらいの方がまぶしくなくて読みやすい。

 

32×32だと、どちらも見やすい。

 

2.4インチ版の電流値

電流値を測ってみる

 

LCD接続無しで23mA

 

2インチ版だと79mA 差は56mA

 

2.4インチ版で76mA 差は53mA

 

なんと、2インチ版の方が小型なのに電流値が多い。明るいはずなのである。

 

全体的な感想でいうと、2.4インチ版の方がやや暗いのだが、単独で動かしていると気にならない。当然ながら小さな文字も大きい方が読みやすい。

やはり大きいということは良いのである。

 

また2.4インチ版にはBL(Back Light)端子が出ていて、輝度調整が出来る。

次はこの2.4インチ版でWebラジオに仕立ててみたい。

 

 

「何度も言うけど、大きいのは良いことなんだニャ」

大きいのと、デブなのはちょっと違うからね