TFT_eSPIとAudioI2SでmediaPlayerを作る(2)

Arduino IDE 2.xxのInstallとモジュールのチェック

Arduino IDE 2.xxの存在は認識していたのですが、今までArduino IDE 1.819離れずにいました。今回思い切ってArduino IDE 2.xxに移ろうと思います。 よってまずは、Arduino IDE 2.xxをInstall、その後 簡単なスケッチを使って前回の回路のモジュールが正常に動くか確認して行きたいと思います。

Arduino IDE 2.xxのInstall

Arduino IDE 2.xxのInstallは非常に簡単です。Installは”Arduino 2.xxをInstall”を参照して下さい。今回InstallしたIDEのVersionは”2.3.6 ”でした。Install後ESP32が使える状態にして下さい。

前準備

下記は今回モジュールの確認用に使うスケッチです。

check.ino

#include "FS.h"
#include <Arduino.h>
#include <Wire.h>
#include <DS3231.h>
#include <SPI.h>
#include <TFT_eSPI.h>             
#include <WiFi.h>
#include <SD_MMC.h>
#include "Audio.h"
#include <LittleFS.h>

//------------- DS3231 (RTC) ---------------------------------
#define i2c_sda         15  
#define i2c_scl         04   
#define alarm1          1
#define alarm2          2
#define int_pin         16

DS3231 Clock;
bool  flg_time;

//------------ SD_MMC 1-wire SD mode ----------------------------
#define mmc_CMD         21 
#define mmc_CLK         48  
#define mmc_D0          47  
#define SDMMC_FREQ      30000
#define MAX_FILE        3

//-------------  PAM8403 -----------------------------------------
#define PAM8403         17

//-------------  PCM5102 (I2S) ---------------------------------
#define   BCK           7   
#define   LCK           5   
#define   DIN           6   
Audio audio;

//------------- DHT20 (temp hume) ---------------------------------
#define DHT_ADR         0x38

//------------- TFT_eSPI ----------------------------------------
#define REPEAT_CAL      false
#define CALIBRATION_FILE "/TouchCalData1"
TFT_eSPI tft = TFT_eSPI();       
#define GFXFF           1

//------------- Timer ----------------------------------------
uint8_t timer_flg = 0;

void time_int()
{
		flg_time = true;
}

void setup()
{
	uint8_t tm_data[10];           //Year,Month,Date,DoW,Hour,Minute,Secon
	
		// Initialise PAM8403
		pinMode(PAM8403, OUTPUT);
		digitalWrite(PAM8403, 0);   // PAM8403 OFF

		Serial.begin(115200);
		Serial.println("");

		// Initialise FS
		if (!LittleFS.begin()) {
			Serial.println("LittleFS initialisation failed!");
			while(1) yield(); 
		}
		else Serial.println("LittleFS OK");

		// Initialise TFT_eSPI 
		Serial.println("Init TFT");
		tft.init();
		touch_calibrate();
		tft.setRotation(1);
		tft.fillScreen(TFT_BROWN);
		tft.setTextColor(TFT_BLUE, TFT_BLUE);
		tft.setTextDatum(TL_DATUM);
		tft.drawString("LCD OK",10, 10, GFXFF); 
		
		// Initialise I2C
		tft.drawString("Init RTC",10, 20, GFXFF); 
		Wire.begin(i2c_sda, i2c_scl, 100000);
		
		// Set RTC 24h mode  
		Clock.setClockMode(0);      
		Clock.turnOffAlarm(alarm1);  

		Clock.setYear(25);          //Set the year (Last two digits of the year)
		Clock.setMonth(6);
		Clock.setDate(1);
		Clock.setDoW(1);           //Set the day of the week  SUN=1 / SAT=7
		Clock.setHour(0);
		Clock.setMinute(0);
		Clock.setSecond(0);

		tft.drawString("RTC OK",10, 30, GFXFF); 

		// Initialise PCM5102 (I2S)
		tft.drawString("Init I2S",10, 40, GFXFF); 
		audio.setPinout(BCK, LCK, DIN);
		audio.setVolume(5);
		tft.drawString("I2S OK",10, 50, GFXFF); 

		// Initialise the SD_MMC
		tft.drawString("Init SD_MMC",10, 60, GFXFF); 
		pinMode(mmc_D0, INPUT_PULLUP);
		SD_MMC.setPins(mmc_CLK, mmc_CMD, mmc_D0);
		if(!SD_MMC.begin("/sdmmc", true, false, SDMMC_FREQ, MAX_FILE)){
			 Serial.println("Card Mount Failed");
			 while(1) yield();
		}
		else Serial.println("SD_MMC initialisation OK");
		tft.drawString("SD_MMC OK",10, 70, GFXFF); 

		tft.drawString("Load J_FONT",10, 80, GFXFF); 
		tft.loadFont("/genshin-regular-20pt", SD_MMC); // Use font stored on SD
		tft.drawString("J_FONT OK",10, 90, GFXFF); 
	
		digitalWrite(PAM8403, 1);   // PAM8403 ON

		pinMode(int_pin, INPUT_PULLUP);
		attachInterrupt(int_pin, time_int, FALLING);

}

void loop()
{
	bool temp,temp1; 
	String str; 
	float ht_data[2];
	char buf[100];

		//Alarm once per second
		Clock.setA1Time(0, 0, 0, 0, 0x0f, 0, 0, 0);
		Clock.turnOnAlarm(alarm1);
		audio.connecttoFS(SD_MMC, "/ピアノ演奏.mp3");
		tft.drawString("Start ピアノ演奏", 10, 115, GFXFF); 
		
		while(1){
			if(audio.isRunning()) 
				audio.loop();
			else{
				audio.stopSong();
				delay(500);
				audio.connecttoFS(SD_MMC, "/ピアノ演奏.mp3");
			}

			if(flg_time){
				str = 
					String(2000 + Clock.getYear()) + "年" + 
					String(Clock.getMonth(temp)) + "月" + 
					String(Clock.getDate()) + "日" +
					String(Clock.getHour(temp,temp1)) + "時"  +
					String(Clock.getMinute()) + "分" + 
					String(Clock.getSecond()) + "秒" ; 
					 
				tft.fillRect(0, 140, 300, 60, TFT_BROWN);
				Serial.println(str);
				tft.drawString(str, 10, 140, GFXFF);

				if(get_t_h(ht_data))
					sprintf(buf,"%.1f'c    %.1f%%", ht_data[1], ht_data[0]);
				Serial.println(buf);
				tft.drawString(buf, 10, 165, GFXFF);

				Clock.checkIfAlarm(alarm1);
				flg_time = false;   
			}
		}

}

bool get_t_h(float* ht_buf){
	uint8_t buf[8];
	long a;
	int flg;
	bool flg_ok;

		flg = 1;
		while (flg)
		{
				Wire.beginTransmission(DHT_ADR);
				Wire.write(0xac);
				Wire.write(0x33);
				Wire.write(0x00);
				Wire.endTransmission();
				delay(100);

				Wire.requestFrom(DHT_ADR, 6);
				for (uint8_t i = 0; i < 6; i++)  buf[i] = Wire.read();

				if (buf[0] & 0x80){
					delay(100);
					flg ++;
					if(flg > 10) break;
				}
				else flg = 0;
		}

		flg_ok = true;
		if(flg){
			Serial.println("Measurement not Comp");
			flg_ok = false;
		}
		else{
			a = buf[1] << 8;
			a |= buf[2];
			a <<= 4;
			a |= ((buf[3] >> 4) & 0x0f);
			ht_buf[0] = a / 10485.76;            //hum

			a = (buf[3] & 0xf);
			a <<= 8;
			a |= buf[4];
			a <<= 8;
			a |= buf[5];
			ht_buf[1] = a / 5242.88 - 50;        // temp

		}
		
		return(flg_ok);
}

//---------------------------------------------------
//              LCD
//---------------------------------------------------
void touch_calibrate(){
	uint16_t calData[5];
	uint8_t calDataOK = 0;

	// check if calibration file exists and size is correct
	if (LittleFS.exists(CALIBRATION_FILE)) {
		if (REPEAT_CAL){
			// Delete if we want to re-calibrate
			LittleFS.remove(CALIBRATION_FILE);
		}
		else {
			File f = LittleFS.open(CALIBRATION_FILE, "r");
			if (f) {
				if (f.readBytes((char *)calData, 14) == 14)
					calDataOK = 1;
				f.close();
			}
		}
	}

	if (calDataOK && !REPEAT_CAL) {
		// calibration data valid
		tft.setTouch(calData);
	} 
	else {
		// data not valid so recalibrate
		tft.fillScreen(TFT_BLACK);
		tft.setCursor(20, 0);
		tft.setTextFont(2);
		tft.setTextSize(1);
		tft.setTextColor(TFT_WHITE, TFT_BLACK);

		tft.println("Touch corners as indicated");

		tft.setTextFont(1);
		tft.println();

		if (REPEAT_CAL) {
			tft.setTextColor(TFT_RED, TFT_BLACK);
			tft.println("Set REPEAT_CAL to false to stop this running again!");
		}

		tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15);

		tft.setTextColor(TFT_GREEN, TFT_BLACK);
		tft.println("Calibration complete!");

		// store data
		File f = LittleFS.open(CALIBRATION_FILE, "w");
		if (f) {
			f.write((const unsigned char *)calData, 14);
			f.close();
		}
	}
}

簡単に説明すると、

  • void setup()
    • 60,61行:  PAM8403のMuteをオン。ポップアップオン対策
    • 66~71行:  LittleFSの初期化。TFTのcalibration Fileを保存するため
    • 73~81行:  TFTの初期化(タッチセンサのcalibrationを含む)と画面の設定。
    • 83~85行:  I2Cの初期化
    • 87~99行:  RTCの初期化と時間を 2025年6月1日0時0分0秒に設定
    • 101~105行: I2Sの初期化
    • 107~116行: SD_MMCの初期化
    • 118~120行: 日本語フォントの読み込み
    • 122行:   PAM8403のMuteをオフ。これ以降スピーカから音が出る。
    • 124,125行: 割り込み設定
  • void loop()
    • 141,142行: RTCの割り込み信号(1秒に一回発生)
    • 143行:   演奏曲の指定
    • 146以降:  演奏しながら、1秒間隔で時間、温湿度を表示

このスケッチをコンパイルする為にライブラリを追加する必要が有ります。

ライブラリの追加

追加するライブラリは下記の3つです。

  • DS3231.h:RTC用ライブラリ      検索ワード → DS3231
  • TFT_eSPI.h:TFT用ライブラリ     検索ワード → TFT_eSPI
  • Audio.h:オーディオ再生用ライブラリ 検索ワード → esp32-audioi2s-master

ライブラリの追加は以下の手順で行います。

  • Arduino IDEの画面左のメニューからライブラリアイコンを選ぶ
  • ライブラリマネージャーの検索欄に上記の検索ワードを入力
  • その下に表示されたライブラリをインストール。

追加したライブラリはLibraryDIrectoryに保存されます。今回IDEを新規にInstallしている為、LibraryDIrectoryには今Installしたライブラリのみです。

TFT_eSPIの”User_Setup.h”を編集

通常モジュールの設定(ピンアサイン等)はスケッチに書く事が多いですが、TFT_eSPIの場合”User_Setup.h”というパラメタを設定する特別なファイルを使用してTFT_eSPIの設定を行います。このファイルを正しく設定しないとLCDが動いてくれません。”User_Setup.h”はTFT_eSPIフォルダの下に有ります。

エディタで”User_Setup.h”を開いて下記の項目に編集を行います。

  • Driverの指定
User_Setup.h


// Display type -  only define if RPi display
//#define RPI_DISPLAY_TYPE // 20MHz maximum SPI

// Only define one driver, the other ones must be commented out
#define ILI9341_DRIVER       // Generic driver for common displays
//#define ILI9341_2_DRIVER     // Alternative ILI9341 driver, see https://github.com/Bodmer/TFT_eSPI/issues/1172
//#define ST7735_DRIVER      // Define additional parameters below for this display
//#define ILI9163_DRIVER     // Define additional parameters below for this display
//#define S6D02A1_DRIVER
  • 解像度の指定
User_Setup.h

// For ST7789, ST7735, ILI9163 and GC9A01 ONLY, define the pixel width and height in portrait orientation
// #define TFT_WIDTH  80
// #define TFT_WIDTH  128
// #define TFT_WIDTH  172 // ST7789 172 x 320
// #define TFT_WIDTH  170 // ST7789 170 x 320
#define TFT_WIDTH  240 // ST7789 240 x 240 and 240 x 320
//#define TFT_HEIGHT 160
// #define TFT_HEIGHT 128
// #define TFT_HEIGHT 240 // ST7789 240 x 240
#define TFT_HEIGHT 320 // ST7789 240 x 320
// #define TFT_HEIGHT 240 // GC9A01 240 x 240

// For ST7735 ONLY, define the type of display, originally this was based on the
// colour of the tab on the screen protector film but this is not always true, so try
// 
  • LEDライトに指定(使用する)
User_Setup.h

// If a backlight control signal is available then define the TFT_BL pin in Section 2
// below. The backlight will be turned ON when tft.begin() is called, but the library
// needs to know if the LEDs are ON with the pin HIGH or LOW. If the LEDs are to be
// driven with a PWM signal or turned OFF/ON then this must be handled by the user
// sketch. e.g. with digitalWrite(TFT_BL, LOW);

#define TFT_BL   40            // LED back-light control pin
#define TFT_BACKLIGHT_ON HIGH  // Level to turn ON back-light (HIGH or LOW)



// We must use hardware SPI, a minimum of 3 GPIO pins is needed.
// Typical setup for ESP8266 NodeMCU ESP-12 is :
//
// Display SDO/MISO  t
  • 信号線の指定
User_Setup.h

// For ESP32 Dev board (only tested with ILI9341 display)
// The hardware SPI can be mapped to any pins

#define TFT_MISO    45
#define TFT_MOSI    42
#define TFT_SCLK    41
#define TFT_CS      01  // Chip select control pin
#define TFT_DC      02  // Data Command control pin
//#define TFT_RST   4  // Reset pin (could connect to RST pin)
#define TFT_RST     -1  // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST

#define TOUCH_CS    38     // Chip select pin (T_CS) of touch screen

// For ESP32 Dev board (only tested with GC9A01 display)
// The hardware SPI can be mapped to any pins

  • 使用SPI(今回はHSPI)の指定
User_Setup.h

// The ESP32 has 2 free SPI ports i.e. VSPI and HSPI, the VSPI is the default.
// If the VSPI port is in use and pins are not accessible (e.g. TTGO T-Beam)
// then uncomment the following line:
#define USE_HSPI_PORT

// Comment out the following #define if "SPI Transactions" do not need to be
// supported. When commented out the code size will be smaller and sketches will
/

データの保存

音楽ファイルと日本語フォント(下記2つ)をダウンロードして予めSDカードのRootDirectryに保存して下さい。

コンパイルと実行

最後にIDEの”ツール”でパラメタを設定してコンパイルです。設定するパラメタは下記の3つ。

  • ボード    : ”ESP32S3 Dev Module” 
    • 今回使用するCPU
  • Partition Scheme: ”Huge APP(3MB No OTA/1MB SPIFFS”
    • スケッチ自体は小さいのですがリンクしたライブラリが大きく、”Huge APP”が必要。
  • PSRAM    : ”OPI PSRAM” 
    • ESP32-audioI2SにPSRAMが必須です。今回はPSRAMのタイプは”OPI PSRAM”でした。

これでやっとコンパイル出来ます。コンパイルは

実行すると、以下の様に動作します。

  • まずLCDのCalibrationが始まります。指示通り四隅をタッチしてCalibrationを終了して下さい。
  • その後、LCD全体が茶色なります。
  • 小さい青い文字で各モジュールの初期状態がLCDに表示されます。
  • LCDに”"Load J_FONT"と表示されるとフォントの読み込みが始まります。これには若干時間がかかります。
  • フォント読み込みが終了すると演奏する曲名がLCDに表示されます。ここからフォントが日本語になっています。
  • 演奏開始。スピーカーから曲が流れます。曲は無限ループで再生されます。
  • 曲名の下に時間と温湿度が表示されます。これらは1秒間隔で更新されます。

これで各モジュールが動作している事が確認出来ました。

WiFi接続で問題発生

ところが次にWiFiに繋ごうとしたら繋がらないという問題が発生しました。使ったスケッチは以下の通り

check1.ino

#include <WiFi.h>

//-------------  WiFi setup ---------------------------------------
const char *SSID = "xxxxxxxx";
const char *PASSWORD = "yyyyyyyy";

void setup()
{
    Serial.begin(115200);
    Serial.println("");

    WiFi.disconnect();
    WiFi.softAPdisconnect(true);
    delay(500);

    WiFi.mode(WIFI_STA);
    WiFi.begin(SSID, PASSWORD);

    while (WiFi.status() != WL_CONNECTED)
    {
      Serial.println("...Connecting to WiFi");
      delay(1000);
    }
    Serial.println("Connected");
    Serial.println(SSID);
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
}

void loop()
{
}

実は最近よくこの現象に遭遇していて、WiFi 送信出力を調整するにて対応済みです。WiFi出力を調整するとつながると言う若干納得のいかない対応です。今回は、WIFI_POWER_13dBmを引数に WiFi.setTxPower(WIFI_POWER_13dBm); で出力を調整したらWiFiに接続出来ました。

最後に、Webラジオに接続してハードの検証を終わりたいと思います。

check2.ino

#include "FS.h"
#include <Arduino.h>
#include <Wire.h>
#include <DS3231.h>
#include <SPI.h>
#include <TFT_eSPI.h>             
#include <WiFi.h>
#include <SD_MMC.h>
#include "Audio.h"
#include <LittleFS.h>

//------------- DS3231 (RTC) ---------------------------------
#define i2c_sda         15  
#define i2c_scl         04   
#define alarm1          1
#define alarm2          2
#define int_pin         16

DS3231 Clock;
bool  flg_time;

//------------ SD_MMC 1-wire SD mode ----------------------------
#define mmc_CMD         21 
#define mmc_CLK         48  
#define mmc_D0          47  
#define SDMMC_FREQ      30000
#define MAX_FILE        3

//-------------  PAM8403 -----------------------------------------
#define PAM8403         17

//-------------  PCM5102 (I2S) ---------------------------------
#define   BCK           7   
#define   LCK           5   
#define   DIN           6   
Audio audio;

//------------- DHT20 (temp hume) ---------------------------------
#define DHT_ADR         0x38

//-------------  WiFi setup ---------------------------------------
const char *SSID = "xxxxxxxx";
const char *PASSWORD = "yyyyyyyy";

//------------- TFT_eSPI ----------------------------------------
#define REPEAT_CAL      false
#define CALIBRATION_FILE "/TouchCalData1"
TFT_eSPI tft = TFT_eSPI();       
#define GFXFF           1

//------------- Timer ----------------------------------------
uint8_t timer_flg = 0;

void time_int()
{
    flg_time = true;
}

void setup()
{
  uint8_t tm_data[10];           //Year,Month,Date,DoW,Hour,Minute,Secon
  
    // Initialise PAM8403
    pinMode(PAM8403, OUTPUT);
    digitalWrite(PAM8403, 0);   // PAM8403 OFF

    Serial.begin(115200);
    Serial.println("");

    // Initialise WiFi
    WiFi.disconnect();
    WiFi.softAPdisconnect(true);
    delay(500);

    WiFi.mode(WIFI_STA);
    WiFi.begin(SSID, PASSWORD);

    WiFi.setTxPower(WIFI_POWER_13dBm);
    while (WiFi.status() != WL_CONNECTED)
    {
      Serial.println("...Connecting to WiFi");
      delay(1000);
    }
    Serial.println("Connected");
    Serial.println(SSID);
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());

    // Initialise FS
    if (!LittleFS.begin()) {
      Serial.println("LittleFS initialisation failed!");
      while(1) yield(); 
    }
    else Serial.println("LittleFS OK");

    // Initialise TFT_eSPI 
    Serial.println("Init TFT");
    tft.init();
    tft.setRotation(1);
    touch_calibrate();
    tft.fillScreen(TFT_BROWN);

    tft.setTextColor(TFT_BLUE, TFT_BLUE);
    tft.setTextDatum(TL_DATUM);
    tft.drawString("LCD OK",10, 10, GFXFF); 
    
    // Initialise I2C
    tft.drawString("Init RTC",10, 20, GFXFF); 
    Wire.begin(i2c_sda, i2c_scl, 100000);
    
    // Set RTC 24h mode  
    Clock.setClockMode(0);      
    Clock.turnOffAlarm(alarm1);  

    Clock.setYear(25);          //Set the year (Last two digits of the year)
    Clock.setMonth(6);
    Clock.setDate(1);
    Clock.setDoW(1);           //Set the day of the week  SUN=1 / SAT=7
    Clock.setHour(0);
    Clock.setMinute(0);
    Clock.setSecond(0);

    tft.drawString("RTC OK",10, 30, GFXFF); 

    // Initialise PCM5102 (I2S)
    tft.drawString("Init I2S",10, 40, GFXFF); 
    audio.setPinout(BCK, LCK, DIN);
    audio.setVolume(5);
    tft.drawString("I2S OK",10, 50, GFXFF); 

    // Initialise the SD_MMC
    tft.drawString("Init SD_MMC",10, 60, GFXFF); 
    pinMode(mmc_D0, INPUT_PULLUP);
    SD_MMC.setPins(mmc_CLK, mmc_CMD, mmc_D0);
    if(!SD_MMC.begin("/sdmmc", true, false, SDMMC_FREQ, MAX_FILE)){
       Serial.println("Card Mount Failed");
       while(1) yield();
    }
    else Serial.println("SD_MMC initialisation OK");
    tft.drawString("SD_MMC OK",10, 70, GFXFF); 

    tft.drawString("Load J_FONT",10, 80, GFXFF); 
    tft.loadFont("/genshin-regular-20pt", SD_MMC); // Use font stored on SD
    tft.drawString("J_FONT OK",10, 90, GFXFF); 
  
    digitalWrite(PAM8403, 1);   // PAM8403 ON

    pinMode(int_pin, INPUT_PULLUP);
    attachInterrupt(int_pin, time_int, FALLING);

}

void loop()
{
  bool temp,temp1; 
  String str; 
  float ht_data[2];
  char buf[100];

    //Alarm once per second
    Clock.setA1Time(0, 0, 0, 0, 0x0f, 0, 0, 0);
    Clock.turnOnAlarm(alarm1);

//		audio.connecttohost("http://www.wdr.de/wdrlive/media/einslive.m3u");
//    audio.connecttohost("http://somafm.com/wma128/missioncontrol.asx"); //  asx
//    audio.connecttohost("http://mp3.ffh.de/radioffh/hqlivestream.aac"); //  128k aac
    audio.connecttohost("http://mp3.ffh.de/radioffh/hqlivestream.mp3"); //  128k mp3

    tft.drawString("Web Radio Test", 10, 115, GFXFF); 
    
    while(1){
      audio.loop();

      if(flg_time){
        str = 
          String(2000 + Clock.getYear()) + "年" + 
          String(Clock.getMonth(temp)) + "月" + 
          String(Clock.getDate()) + "日" +
          String(Clock.getHour(temp,temp1)) + "時"  +
          String(Clock.getMinute()) + "分" + 
          String(Clock.getSecond()) + "秒" ; 
           
        tft.fillRect(0, 140, 300, 60, TFT_BROWN);
        Serial.println(str);
        tft.drawString(str, 10, 140, GFXFF);

        if(get_t_h(ht_data))
          sprintf(buf,"%.1f'c    %.1f%%", ht_data[1], ht_data[0]);
        Serial.println(buf);
        tft.drawString(buf, 10, 165, GFXFF);

        Clock.checkIfAlarm(alarm1);
        flg_time = false;   
      }
    }

}

bool get_t_h(float* ht_buf){
  uint8_t buf[8];
  long a;
  int flg;
  bool flg_ok;

    flg = 1;
    while (flg)
    {
        Wire.beginTransmission(DHT_ADR);
        Wire.write(0xac);
        Wire.write(0x33);
        Wire.write(0x00);
        Wire.endTransmission();
        delay(100);

        Wire.requestFrom(DHT_ADR, 6);
        for (uint8_t i = 0; i < 6; i++)  buf[i] = Wire.read();

        if (buf[0] & 0x80){
          delay(100);
          flg ++;
          if(flg > 10) break;
        }
        else flg = 0;
    }

    flg_ok = true;
    if(flg){
      Serial.println("Measurement not Comp");
      flg_ok = false;
    }
    else{
      a = buf[1] << 8;
      a |= buf[2];
      a <<= 4;
      a |= ((buf[3] >> 4) & 0x0f);
      ht_buf[0] = a / 10485.76;            //hum

      a = (buf[3] & 0xf);
      a <<= 8;
      a |= buf[4];
      a <<= 8;
      a |= buf[5];
      ht_buf[1] = a / 5242.88 - 50;        // temp

    }
    
    return(flg_ok);
}

//---------------------------------------------------
//              LCD
//---------------------------------------------------
void touch_calibrate(){
  uint16_t calData[5];
  uint8_t calDataOK = 0;

  // check if calibration file exists and size is correct
  if (LittleFS.exists(CALIBRATION_FILE)) {
    if (REPEAT_CAL){
      // Delete if we want to re-calibrate
      LittleFS.remove(CALIBRATION_FILE);
    }
    else {
      File f = LittleFS.open(CALIBRATION_FILE, "r");
      if (f) {
        if (f.readBytes((char *)calData, 14) == 14)
          calDataOK = 1;
        f.close();
      }
    }
  }

  if (calDataOK && !REPEAT_CAL) {
    // calibration data valid
    tft.setTouch(calData);
  } 
  else {
    // data not valid so recalibrate
    tft.fillScreen(TFT_BLACK);
    tft.setCursor(20, 0);
    tft.setTextFont(2);
    tft.setTextSize(1);
    tft.setTextColor(TFT_WHITE, TFT_BLACK);

    tft.println("Touch corners as indicated");

    tft.setTextFont(1);
    tft.println();

    if (REPEAT_CAL) {
      tft.setTextColor(TFT_RED, TFT_BLACK);
      tft.println("Set REPEAT_CAL to false to stop this running again!");
    }

    tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15);

    tft.setTextColor(TFT_GREEN, TFT_BLACK);
    tft.println("Calibration complete!");

    // store data
    File f = LittleFS.open(CALIBRATION_FILE, "w");
    if (f) {
      f.write((const unsigned char *)calData, 14);
      f.close();
    }
  }
}
  • 42,43行:  WiFi用SSIDとPASSWORDの宣言
  • 70,87行:  WiFi接続
    • 78行: WiFi出力調整 WiFi.setTxPower(WIFI_POWER_13dBm);
  • 164~167行: WebRadioに接続。

164~167行に接続先が4つ有ります。この内1を有効にし他をコメントにして接続先を変更する事が出来ます。今回は全てに接続出来ました。

次回は

ハード全てが予定通り動作する事を検証出来ました。次回はLCDを使ったGUIに付いて説明します。