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

お父にゃんの電子工作

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

前回購入したCYDが XH-32Sという謎のモジュールが載った怪しい物。しかも技適マークの無い「ハズレ」だった。

でも、もったいないので無線機能無しで何か動かして遊んでみる。

正規のCYDの場合、2つのUSBコネクタのついた新しい2.8インチCYDではLCDコントローラはST7789が使われていると、複数の記事で書かれていた。

 

しかし、最初にインストールされているデモプログラムではシリアルモニタで以下のようにILI9341が載っているかのよう。

 

21:42:06.962 -> disp_spi->Adding SPI device
21:42:06.962 -> disp_spi->Clock speed: 40000000Hz, mode: 0, CS pin: 15
21:42:07.146 -> ILI9341->ili9341 Initialization....
21:42:07.346 -> I (940) ILI9341: Enabling backlight.
21:42:07.346 -> ILI9341->Display orientation: LANDSCAPE_INVERTED
21:42:07.346 -> ILI9341->0x36 command value: 0xE8
21:42:07.384 -> lvgl_helpers->Initializing SPI master for touch
21:42:07.384 -> I (950) gpio: GPIO[36]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
21:42:07.384 -> I (960) gpio: GPIO[39]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
21:42:07.384 -> I (960) XPT2046: XPT2046 Initialization

 

おいおい・・・ どっちなんだい?

 

まず、記事を信じてChatGPTにST7789でコードを書いてもらう。

何度もやり取りして、動き始めた。やはりST7789だったのか・・と思ったのだが

なんじゃこりゃ? 文字が左右に鏡写しになっている。

ChatGPTに直せないのか訊いて、いろいろ試してみたのだが効果なし。

 

仕方が無いのでILI9341前提で、動作確認のコードを書いてもらった。

気のせいかもしれないが、最近のChatGPTのコード出力の精度が悪いような気がする。間違いを指摘しても、まるで指示したおじさんが悪いかのような文面で修正してくるのだ。

コードを書く前によく考えて欲しいもんである。(お前が言うか?)

めげずに何度かやり取りして動くようになった。

 

今度はLCDの表示に TFT_eSPI.h を使う。TFT_eSPI.hでタッチパネルも扱えるのだが、CYDでは何故かタッチパネルのSPIは完全独立しているので、扱う事が出来ない。

独自に XPT2046_Touchscreen.h を使って動かす必要がある。

SPIを共通にしておけば使えるGPIOも増えるのに・・・

 

最初に、Arduino/libraries/TFT_eSPI/User_Setup.h を編集して以下に変更:

 

#define ILI9341_DRIVER
#define TFT_MISO 12
#define TFT_MOSI 13
#define TFT_SCLK 14
#define TFT_CS   15
#define TFT_DC    2
#define TFT_RST  -1
#define LOAD_GLCD
#define LOAD_GFXFF
#define LOAD_FONT2
#define SMOOTH_FONT

 

Arduino IDEのコード

#include <TFT_eSPI.h>
#include <XPT2046_Touchscreen.h>
#include <SPI.h>
 
#define TOUCH_CS   33
#define TOUCH_IRQ  36
 
// タッチ用 SPI(HSPI)
SPIClass touchSPI(HSPI);
 
#define TOUCH_CLK  25
#define TOUCH_MISO 39
#define TOUCH_MOSI 32
 
XPT2046_Touchscreen ts(TOUCH_CS, TOUCH_IRQ);
TFT_eSPI tft = TFT_eSPI();
 
#define TFT_BL 21
 
// ===== プロトタイプ宣言 =====
struct Button;
void drawButton(struct Button &btn);
bool inButton(struct Button &btn, int x, int y);
 
// ===== Button 構造体 =====
struct Button {
  int x, y, w, h;
  bool state;
  const char* label;
};
 
// ===== ボタン定義 =====
Button btnA = { 30,  80, 120, 80, false, "Button A" };
Button btnB = { 170, 80, 120, 80, false, "Button B" };
 
// ===== タッチ座標変換 =====
int mapX(int x) { return map(x, 300, 3800, 0, 320); }
int mapY(int y) { return map(y, 300, 3800, 0, 240); }
 
// ===== ボタン描画 =====
void drawButton(Button &btn) {
  uint16_t color = btn.state ? TFT_GREEN : TFT_RED;
  tft.fillRect(btn.x, btn.y, btn.w, btn.h, color);
  tft.drawRect(btn.x, btn.y, btn.w, btn.h, TFT_WHITE);
 
  tft.setTextColor(TFT_WHITE, color);
  tft.setTextSize(2);
  tft.setCursor(btn.x + 10, btn.y + 30);
  tft.print(btn.label);
}
 
// ===== ボタン判定 =====
bool inButton(Button &btn, int x, int y) {
  return (x > btn.x && x < btn.x + btn.w &&
          y > btn.y && y < btn.y + btn.h);
}
 
// ===== setup =====
void setup() {
  Serial.begin(115200);
 
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH);
 
  tft.init();
  tft.setRotation(1);
  tft.invertDisplay(false);
  tft.fillScreen(TFT_BLACK);
 
  touchSPI.begin(TOUCH_CLK, TOUCH_MISO, TOUCH_MOSI, TOUCH_CS);
  ts.begin(touchSPI);
  ts.setRotation(1);
 
  drawButton(btnA);
  drawButton(btnB);
}
 
// ===== loop =====
void loop() {
  if (ts.touched()) {
    TS_Point p = ts.getPoint();
 
    int tx = mapX(p.x);
    int ty = mapY(p.y);
 
    Serial.printf("Touch: x=%d y=%d\n", tx, ty);
 
    if (inButton(btnA, tx, ty)) {
      btnA.state = !btnA.state;
      drawButton(btnA);
      delay(200);
    }
 
    if (inButton(btnB, tx, ty)) {
      btnB.state = !btnB.state;
      drawButton(btnB);
      delay(200);
    }
  }
}

 

今度は、ちゃんと動いた。

やはりLCDコントローラーは ILI9341が使われているようだ。

むむむむ・・・ 偽物を掴まされると苦労するのである。

 

次に、CN1コネクタから出ているGPIO 22と27を使ってI2C通信出来るか試してみる。

前回描いてみたCYD内部回路図の右下部分

接続するのは以前に秋月電子で買った温湿度センサDHT20

過去に何度か使ったことが有るので、特に迷うことは無い。

 
おじさんにしては珍しく一発で動いた。
これで、CN1から電源とI2Cを取り出すことが出来ることは分かった。
このコードは以下に置いてあるので、気になる方はどうぞ
 
温湿度表示更新の際に表示がちらつくのが気になるが、そこの対策はまた追い追いで考えることにする。
 
ああ、しかし、WiFiが使えれば時刻情報を取って時計表示するとか、webから気象情報を取って天気予報を表示するとか、いろいろ考えられるのだが・・・
 
さて、これからどうしたものか?
 
 
「何をするか決まるまで、寝て待つことにするニャ」
いつも寝てるでしょ