LCD(ST7789)付きRP2040とESP32C3を搭載したT-PicoC3を試す

コンピュータ、組み込み

LILYGOのT-PicoC3を入手しました。
1つの基板にESP32-C3とRaspberryPiのRP2040の2つのCPUを搭載し、小型のLCD(ST7789v)まで付いています。
技適はありませんが、面白そうな基板なので試してみます。

紹介するもの

LILYGO T-PicoC3

特徴

小型のLCD ST7789V 搭載。
一枚の基板にESP32-C3とRP2040が搭載されています。
電源を投入すると同時に動作を開始します。
技適はありません。

RP2040側ESP32-C3側
電源LED
CPURP2040 133MHzRISC-V 160MHz
メモリSRAM 264KB
Flash Memory 4MB
SRAM 400KB
ROM 384KB
Flash 4MB
GPIO153
ADC3 (10bit 0 ~ 1023)1 (12bit 0 ~ 4095)
PWM15 (8bit 0 ~ 255)3 (8bit 0 ~ 255)
UART2
(UART1 は ESP32-C3通信用)
1(RP2040通信用)
I2C21
SPI20
ボタン2
右側 GPIO6
左側 GPIO7
そのほかLED赤 GPIO25
LCD ST7789V 1.14inch(240 x 135)
JST GH 1.25mm バッテリーコネクタ

LILYGO T-Pico3ページ(外部サイト)

T-PicoC3 紹介(github)

ピン配置

CPUにRP2040とESP32-C3が搭載されています。
使用できるピンはCPUにより決まっています。
青枠はRP2040から制御を行うGPIO、緑枠はESP32-C3から制御を行うGPIO
ユーザボタン2個、LED、LCDはRP2040から制御します。
RP2040とESP32-C3は直接シリアルで接続されて、内部で通信することができます。

外観

RP2040を搭載しているためSWDありますが、LCDモニタと干渉するので使い勝手はイマイチです。

LCDを斜めにズラすことでピンヘッダを装着できますが、それでも干渉は避けられません。
SWDを使わなければ問題になりません。

T-Displayシリーズは専用のケースも販売されていて、収納することで小型のゲーム機のようになります。
収納後の使い勝手はT-Display RP2040で紹介しています。

USB TypeCコネクタを接続し、電源を供給します。
搭載されるRP2040とESP32-C3はどちらも動作を開始します。

USBコネクタの挿し面により接続されるCPUが変わります。
LEDの点灯が青の時はRP2040に接続、緑の時はESP32-C3に接続されている状態です。

スケッチの書き込みやUARTのデバッグ出力などで区別する必要があります。

RP2040とESP32-C3は基板内でUART接続されています。
CPU間の通信をすることができます。
こちらは記事の後半でサンプルを掲載して動作確認をします。

使ってみて

一枚の開発基板に2種類のCPUが搭載されています。
それぞれに別々のスケッチを書いて動かすことができます。

内部ではCPU同士がUARTで接続されているので、データの送受信やタイミング合わせをして連動させることができます。

スケッチの書き込みはTYPE C USBコネクタの表と裏で接続するCPUを選択するユニークな機構です。
TYPE C自体どちらが表か裏かがわかりにくいので、この基板を使用するときはコネクタに目印をつけておくと良いです。

スケッチの作りこみや書き込みには作業の慣れが必要です。
作っているスケッチと使おうと思っているCPUが違うことがあります。
開いているプロジェクトがどちらのCPUの物か混乱することがあります。
現在どちらのCPUに接続しているかを意識する必要があります。
書き込み作業は後述しますが、ESP32-C3側は書き込み時にGPIO9とGNDをショートさせた状態で電源を投入する必要があり手間がかかります。

1つの成果物に複数のCPUやプログラムを使用することはありますが、この規模の基板場合は手間の方が大きいです。
とはいえ、趣味の世界では楽しいと思えればOKです。

扱いが難しければ両方のCPUを使うことを考えず、まずはRP2040側だけ使えばいいと思います。

この基板のように複数のCPUがある場合、それぞれの特徴を活かしたタスクの分配をしたいところです。
RP2040側の方が使用できるGPIOが多く、LCDやボタンなどの機能も所有しているのでメインの処理はRP2040側になるのでしょうか。
ESP32-C3の優位を活かしたタスクを与えて動作させたいですが、この基板のESP32C3の技適が無いため無線が使用できないことは残念です。

他にもバッテリーコネクタがを使用する付いているなどのユーティリティも充実していて、電源の無いところでも動作させることができます。

RP2040を搭載したT-Display RP2040 も紹介しています。

ESP32-WROOM(技適付き)のT-Display

準備

ライブラリ

ボードライブラリ

Arduino IDEのボードマネージャからRP2040用ライブラリとESP32用ライブラリのインストールをします。
選択するライブラリは書き込みを行うCPUのライブラリを選択します。

RP2040側

追加のボードマネージャのURLhttps://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
検索RP2040
ボードライブラリRaspberry Pi RP2040 Boards(x.x.x)※
選択するボードRaspberry Pi RP2040 Boards(x.x.x) > Raspberry Pi Pico H
※動作確認はバージョン 3.1.0です

ESP32-C3側

ボードマネージャのURLhttps://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
検索ESP
ボードライブラリesp32 by Espressif Systems バージョン x.x.x※
選択するボードツール > ボード > esp32 > ESP32 Dev Module
※ x.x.x Sep/2022 動作確認は2.0.5を使用しています

モジュールライブラリ

機能/モジュールライブラリ名検索確認時のバージョン
ST7735Adafruit ST7735 and ST7789
Library by Adafruit
ST77351.9.3
関連
SSD1306
ST7789
Adafruit GFX Library by AdafruitGFX1.11.3

UF2ファイルの作成とシリアル認識

RP2040側に接続されている状態で行う作業です。
(基板の電源LEDが青)

Arduino環境で空のuf2ファイルを作成し、RP2040搭載基板に書き込みます。
この作業を行うことでArduino環境のシリアルからスケッチの書き込みができるようになります。

<<この作業はArduino環境にRP2040ボードライブラリがインストールされている必要があります>>

1.ArduinoIDEを起動し「新規スケッチ」を開き、そのまま「名前を付けて保存」します。

2. ボードには Raspberry Pi Pico/RP2040 > Raspberry Pi Pico を選択します。

3.「コンパイル済みバイナリをエクスポート」を実行します。
コンパイルが終わると、保存したフォルダの下位階層に [blank.ino.uf2]が作成されます。

4. T-PicoC3のBOOT SELボタンを押しながら、USBケーブルをパソコンに接続します。

5.パソコンの画面では、T-PicoC3(RP2040側) をストレージとして認識します。

6.先に作成した[blank.ino.uf2]をT-PicoC3にドラッグ&ドロップします。

以上の作業でCOM認識されます。

今回作成したuf2ファイルは、保存しておいてください。
T-PicoC3を初期化したいとき(今何のファームウエアが書かれているかわからなくなったとき)には、このuf2ファイルを書き込むことで初期化することができます。

書き込み

RP2040側
電源LEDが青に点灯する方向でUSBケーブルを接続します。
ArduinoIDEの書き込みボタンから書き込みを行います。

ESP32-C3側
GPIO9とGNDをショートさせた状態で、電源LEDが緑に点灯する方向でUSBケーブルを接続します。

ArduinoIDEの書き込みボタンから書き込みを行います。

基本スケッチ

RP2040側 ボタン、LED

説明

RP2040側でユーザボタンGPIO7(左側)が押されたらされたらLEDを点灯させます。
ユーザボタンGPIO6(右側)が押下されたらLEDを消灯させます。

書き込みは「書き込み」RP2040側を参照します。

スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
T-PicoC3

【スケッチの説明】
ユーザボタンGPIO7(Left Sideとします)が押下されたらLEDを点灯
ユーザボタンGPIO6(RIght Sideとします)が押下されたらLEDを消灯

【ライブラリ】
Raspberry Pi Pico/RP2040 > Generic RP2040

【バージョン情報】
2023/12/13 : 新規
**********************************************************************/

#define LED 25       //基板実装LED 赤(基板裏面)

//USBコネクタを上側にしたときにLeftSide と RightSideとします。
#define BUTTON_L 7      //基板実装スイッチ LeftSide
#define BUTTON_R 6      //基板実装スイッチ RightSide

void setup()
{
  pinMode(LED, OUTPUT);                 //ピン出力設定

  pinMode(BUTTON_L, INPUT_PULLUP);      //プルアップで入力
  pinMode(BUTTON_R, INPUT_PULLUP);      //T-DisplayのユーザボタンはPULLDOWN設定にしてもPULLUPになるので、PULLUPとした。

  Serial.begin(115200);
}

void loop()
{
  //PULLUP設定のためボタン押下状態がLOW

  if(digitalRead(BUTTON_L) == LOW)
  {
    digitalWrite(LED, HIGH);            //ボタンLeftSideが押下されていた場合は、LEDを点灯
  }
  else if(digitalRead(BUTTON_R) == LOW)
  {
    digitalWrite(LED, LOW);             //ボタンRightSideが押下されていた場合は、LEDを消灯
  }
}
結果

ユーザボタンGPIO7(Left Sideとします)を押下するとLEDが点灯しました。
ユーザボタンGPIO6(RIght Sideとします)を押下するとLEDが消灯しました。

GPIO25(LED赤)は基板の背面側に実装されています。
画像上ではGPIO7(Left Side)のボタンを押したため、点灯状態で床が赤っぽくなっています。
画像下ではGPIO6(Right Side)のボタンを押したため、消灯状態です。
床が青っぽいのはUSBケーブルの向きがRP2040側に接続されているインジケータです。

ケーブルの面を反転させてESP32C3側に接続しても同じ動作をします。
次のESP32-C3側PWMでも確認をすることができます。

ESP32-C3側PWM

説明

PWMを使ってLEDのフェード点灯(ゆっくり点灯させる)を行います。

書き込みは「書き込み」ESP32-C3側を参照します。

スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
T-PicoC3

【スケッチの説明】
PWM出力でのフェード点灯(ゆっくり点灯)とフェード消灯(ゆっくり消灯)を行います。

【ライブラリ】
esp32 > ESP32C3 Dev Module

【準備】
GPIO9 - LEDModule - GND
保護抵抗付きLEDModuleを使用した回路です。
抵抗の無いLEDを使用する場合は、適切な保護抵抗(200Ω程度)を使用します。

【バージョン情報】
2023/12/13 : 新規
**********************************************************************/

#define PWM (8)        //PWM 出力

void setup()
{
  pinMode(PWM , OUTPUT);
}

void loop()
{
  for(int i = 0; i < 256; i ++)
  {
    analogWrite(PWM, i);
    delay(2);
  }

  for(int i = 0; i < 256; i ++)
  {
    analogWrite(PWM, 255 - i);
    delay(2);
  }
}
結果

実装LEDがゆっくり点灯、ゆっくり消灯しました。
結果は静止画で行っていますが、PWMによる光量の変化がみられます。

サンプルスケッチ「RP2040側ボタン、LED」を書き込んでいた場合、RP2040側も動作しています。
ボタンを押すことでLEDの点灯と消灯をします。

ADC(RP2040, ESP32-C3)

説明

T-PicoC3のADCはRP2040では3ch、ESP32-C3では1ch使用できます。
それぞれに同じ電圧を入力して、結果をUART出力します。

入力する電圧はLOLIN32 Liteを使っています。

サンプルはRP2040とESP32C3の同地らも掲載していますが、片方ずつ作業します。
このサンプルはどちらか一方だけで動作します。

配線

RP2040側の配線

T-PICOC3のGPIO28 と LOLIN32 LiteのGPIO26を直接配線します。

ESP32C3側の配線

T-PICOC3のGPIO2とLOLIN32 LiteのGPIO26を直接配線します。
ESP32C3には標準でUART出力するピンが無いので、GPIO8をTXに指定して使用します。
UART信号をFT232RLに入力します。

スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
T-PicoC3(RP2040 Side)

【スケッチの説明】
入力された電圧を読み取ります。

【ライブラリ】
 Raspberry Pi Pico/RP2040 > Generic RP2040

【準備】
マイコン基板 <-> LOLIN32 Lite
GPIO28(ADC)         <-> GPIO26(DAC)
GND                 <-> GND

【バージョン情報】
2023/12/15 : 新規
**********************************************************************/

#define ADC 28

void setup()
{
  Serial.begin(115200);
  pinMode(ADC, INPUT);
}

void loop()
{
  int iADC = 0;

  //外部から入力された電圧を読み取り、結果をCOMに出力します。
  iADC = analogRead(ADC);
  Serial.printf("(ADC) = %d\r\n", iADC);
  delay(2);
}
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
T-PicoC3(ESP32C3 Side)

【スケッチの説明】
入力された電圧を読み取ります。

【ライブラリ】
 esp32 > ESP32C3 Dev Module

【準備】
マイコン基板 <-> LOLIN32 Lite
GPIO2(ADC)          <-> GPIO26(DAC)
GND                 <-> GND

【バージョン情報】
2023/12/15 : 新規
**********************************************************************/

#define PIN_TX 8
#define PIN_RX 9
#define ADC 2

void setup()
{
  Serial1.begin(115200, SERIAL_8N1, PIN_RX, PIN_TX);      //Serial1 オブジェクトは ピン指定で使用します
  pinMode(ADC, INPUT);
}

void loop()
{
  int iADC = 0;

  //外部から入力された電圧を読み取り、結果をUARTに出力します。
  iADC = analogRead(ADC);
  Serial1.printf("(ADC) = %d\r\n", iADC);
  delay(2);
}

結果

結果を波形にしました。
横軸はデータ数(index)です。
縦軸左は設定したDA値、縦軸右が読み取ったAD値。

RP2040の波形はきれいに読み取りができていますが、ESP32C3側は何の波形を読み取っているのかわからないデータになりました。
固定の電圧を入力しても正しく読めないので、配線が悪いのか原因がわかっていません。



また、RP2040のADC読み取りと同時にESP32C3のADCにも同じ信号を入力するとRP2040側まで波形がおかしくなってしまいました。

原因はわかりませんが、現状ESP32C3のADCは使えていません。

UART(RP2040, ESP32C3)

説明

T-PicoC3のRP2040とESP32C3をUARTで通信します。

1.
パソコンとUSBケーブル経由でRP2040とUARTで送信します。
RP2040が読み取ったデータを基板内部で接続されているUART経由でESP32C3に送信します。
ESP32C3が読み取ったデータは、外部用のUARTからFT232RLに送信します。
FT232RLは読み取ったデータをパソコンに送信します。

2.
パソコンからFT232RLにデータを送信し、FT232RLはUARTでESP32C3に送信します。
ESP32C3が読み取ったデータは基板内部で接続されているUART経由でRP2040に送信します。
RP2040が読み取ったデータは、USB経由でパソコンに送信します。

配線

T-PicoC3のUSBケーブルはRP2040側と接続する面で接続します(基板の電源LEDが青)
FT232RLもUSBケーブルをパソコンと接続します。

T-PicoC3配線FT232RL
GPIO8 (UART TX)RX
GPIO9 (UART RX)TX
スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
T-PicoC3

【スケッチの説明】
ST7789V LCDの制御をします。

【ライブラリ】
Raspberry Pi Pico / RP2040 > Generic RP2040

【準備】
マイコン基板 <-> ST7789V
SPI0
ビルトインLCDのため配線不要ですが仕様上のピン番号のみ記載します。
GPIO5(SPI0 CS)    <-> CS
GPIO0             <-> Reset
GPIO1             <-> AO
GPIO3(SPI0 MOSI)  <-> SDA
GPIO2(SPI0 SCK)   <-> SCK
GPIO4(BackLight)


【バージョン情報】
2023/12/16 : 新規
**********************************************************************/

#include <Adafruit_GFX.h> 
#include <Adafruit_ST7789.h>
#include <SPI.h>

//基板実装LCD SPI0
#define TFT0_CS          5   // CS
#define TFT0_RST         0   // Reset 
#define TFT0_DC          1   // DC
#define TFT0_MOSI        3   // MOSI
#define TFT0_SCK         2   // SCK
#define TFT0_BL          4   // BackLight 

//SPI0
Adafruit_ST7789 tft0 = Adafruit_ST7789(&SPI, TFT0_CS, TFT0_DC, TFT0_RST);

void setup(void) 
{
  //SPI0
  SPI.setTX(TFT0_MOSI);
  SPI.setSCK(TFT0_SCK);
  
  //基板上のLCD(SPI0)の表示

  pinMode(TFT0_BL, OUTPUT);
  digitalWrite(TFT0_BL, HIGH);                 //バックライトON

  tft0.init(135, 240);
  tft0.fillScreen(ST77XX_WHITE);               //背景の塗りつぶし

  //テキスト表示
  tft0.setRotation(1);                         //画面回転
  tft0.setTextSize(3);                         //サイズ

  tft0.setCursor(0, 20);                      //カーソル位置                      
  tft0.setTextColor(ST77XX_RED);               //赤
  tft0.printf("T-PicoC3\n");
  tft0.setCursor(0, 50);                      //カーソル位置                      
  tft0.setTextColor(ST77XX_BLUE);              //青
  tft0.printf("RP2040\n");
  tft0.setTextColor(ST77XX_GREEN);              //青
  tft0.printf("ESP32C3");

  digitalWrite(TFT0_BL, HIGH);                 //バックライトON
}

void loop()
{
}
結果

結果を確認するために、Teratermを2つ起動します。
1つはT-PicoC3のRP2040側と接続したCOM用(今回COM19と認識された)
もう一つはFT232RL用(今回COM13と認識された)

RP2040(COM19)側から “RP2040″と入力するとFT232RL(COM13)側にも”RP2040″と表示されました。
FT232RL(COM13)側から”ESP32C3″と入力するとRP2040(COM19)側にも”ESP32C3″と表示されました。

内部のUARTを経由してデータの送信と受信ができました。
今回UARTで使用していますが、GPIOのI/Oとしてタイミング調整やフラグにも使用できます。

SPI(ST7789V)

説明

SPIを使って実装ST7789V(LCD 1.14inch)の表示制御します。

以前紹介したT-Display RP2040とよく似ていますが、T-PicoC3では電源のOff/Onをすることなく使用できます。

図形の描画やそのほかの命令はArduinoサンプルスケッチを参照してください。
ファイル(F) > スケッチ例 > Adafruit ST7735 and ST7789 Library > graphicstest

配線

実装ST7789Vは配線不要。

スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
T-Display V1.1 で利用できます。

【スケッチの説明】
ST7735 LCDの制御をします。
VSPIは基板実装LCD ST7789V
HSPIはS/W SPIを使用し、ワイヤー接続でST7735の表示制御を行います。

基板実装LCDはバックライトにGPIO4, LCDの電源にGPIO14をHIGHにすることで動作表示されます。

【ライブラリ】
esp32 > ESP32 Dev Module

【準備】
VSPIは基板実装LCD ST7789Vを使用する。
配線は不要
マイコン基板 <-> ST7789V
GPIO5(CS)     <-> CS
GPIO23(Reset) <-> Reset
GPIO16(DC)    <-> AO
GPIO19(MOSI)  <-> SDA
GPIO18(SCK)   <-> SCK
GPIO4(BackLight)
GPIO14(PowerSupply)

HSPIは使用できません。
SCK(GPIO14)が、VSPIの電源に使用されているためです。
今回ワイヤ接続でST7735をS/W SPIで制御する。
マイコン基板 <-> ST7735
3V3           <-> VCC
GND           <-> GND
GPIO15(CS)    <-> CS
GPIO27(Reset) <-> Reset
GPIO26(DC)    <-> AO
GPIO13(MOSI)  <-> SDA
GPIO2(SCK)    <-> SCK

【バージョン情報】
2022/12/03 : 新規
**********************************************************************/

#include <Adafruit_GFX.h> 
#include <Adafruit_ST7735.h>
#include <Adafruit_ST7789.h>
#include <SPI.h>

//基板実装LCD VSPI
#define TFT0_CS       5   // CS
#define TFT0_RST      23  // Reset 
#define TFT0_DC       16  // DC
#define TFT0_MOSI     19  // MOSI
#define TFT0_SCK      18  // Clock
#define TFT0_BL       4   // BackLight 
#define TFT0_PWR      14  // Powersupply

//  Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
 Adafruit_ST7789 tft0 = Adafruit_ST7789(&SPI, TFT0_CS, TFT0_DC, TFT0_RST);

//S/W SPIで使用するため、ピンはどれでもよい。
#define TFT1_CS          15  // CS
#define TFT1_RST         27  // Reset 
#define TFT1_DC          26  // DC
#define TFT1_MOSI        13  // MOSI
#define TFT1_SCK         2   // Clock

//S/W SPIはこちら。遅いが任意のピンを使用できる。
Adafruit_ST7735 tft1 = Adafruit_ST7735(TFT1_CS, TFT1_DC, TFT1_MOSI, TFT1_SCK, TFT1_RST);

void setup(void) 
{
  //SPI0 //ピンアサイン表にピン指定してあるが、定義はされていないようなのでbegin()でピン設定する。
  SPI.begin(TFT0_SCK, -1, TFT0_MOSI, TFT0_CS);       //FSPIピンを変更して使用する場合、この行のコメントを解除
  
  //基板上のLCD(SPI0)の表示
  pinMode(TFT0_PWR, OUTPUT);
  digitalWrite(TFT0_PWR, HIGH);                 //バックライトON

  pinMode(TFT0_BL, OUTPUT);
  digitalWrite(TFT0_BL, HIGH);                 //バックライトON

  tft0.init(135, 240);
  tft0.fillScreen(ST77XX_WHITE);               //背景の塗りつぶし

  //テキスト表示
  tft0.setRotation(1);                         //画面回転
  tft0.setTextSize(3);                         //サイズ

  tft0.setCursor(0, 20);                      //カーソル位置                      
  tft0.setTextColor(ST77XX_RED);              //赤
  tft0.printf("TTGO\n");
  tft0.setCursor(0, 50);                      //カーソル位置                      
  tft0.setTextColor(ST77XX_BLUE);             //青
  tft0.printf("T-Display\n");


  tft1.initR(INITR_BLACKTAB);                 //Init ST7735S初期化
  tft1.fillScreen(ST77XX_BLACK);              //背景の塗りつぶし

  //テキスト表示
  tft1.setRotation(3);                        //画面回転
  tft1.setTextSize(3);                        //サイズ

  tft1.setCursor(0, 20);                      //カーソル位置                      
  tft1.setTextColor(ST77XX_RED);              //赤
  tft1.printf("TAMANEGI\n");

  tft1.setTextColor(ST77XX_GREEN);            //緑
  tft1.printf("TAMANEGI\n");

  tft1.setTextColor(ST77XX_BLUE);             //青
  tft1.printf("TAMANEGI\n");

  tft1.setTextColor(ST77XX_YELLOW);           //黄
  tft1.printf("TAMANEGI\n");
}

void loop()
{
}
結果

ST7789Vのサンプルスケッチが動作しました。

コメント

タイトルとURLをコピーしました