Hello everybody
my problem might be very common and I researched on this forum but only found topics related to AtMega processors.
My project works with a ESP32-C6 super mini and a 1.8" TFT ST7735 display. The project is a wakeup clock shows the time and other info on the screen and can be setup to a wakeup hour playing a track using a DFP-player. So far so good, I got all parts together developped a sketch and on the first version I loaded it on a ESP32 -C3 super mini and it worked fantastic. Now I built a second one and just changed the processor to a ESP32**-C6 **super mini. This required to change some GPIO´s and the library for the TFT display. On the first version I used Bodmer´s TFT_eSPI library but on the ESP32-C6 this does not work at all. So I use the Adafruit_ST7735 library and basicly it works fine but the refresh of the display is now very very slow. I wanted to attach a video so that you can see what I am talking about but I have no permission. It takes about one second to refresh a quarter of the screen. I tried to raise the SPI clock frequency up to 32Mhz but very few progress.
My code is quite long but I will post it:
// Digital MP3 Clock Galactico
// for ESP32C3 Supermini DY-Player
// January 2024
// Bernardo Gullasch
// VERSION 4 ESP32-C6 and 1,8" ST7735 TFT display
// V4.0 using Adafruit_ST7735 TFT library
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <SPI.h>
#include <WiFi.h>
#include <ESP32Time.h>
#include <DFRobotDFPlayerMini.h>
#include <Fonts\FreeMonoBoldOblique9pt7b.h>
#include <Fonts\FreeSerifBoldItalic24pt7b.h>
#include <Fonts\FreeSerifBoldItalic12pt7b.h>
#include <Fonts\FreeMonoBold9pt7b.h>
#include <Fonts\FreeSerifBold9pt7b.h>
#include <Fonts\FreeSerifBold18pt7b.h>
#define TFT_BLACK 0x0000
#define TFT_WHITE 0xFFFF
#define TFT_LIGHTGREY 0xBDF7
#define TFT_DARKGREY 0x7BEF
#define TFT_RED 0xF800
#define TFT_DRED 0xA800
#define TFT_YELLOW 0xFFE0
#define TFT_ORANGE 0xFBE0
#define TFT_BROWN 0x79E0
#define TFT_GREEN 0x7E0
#define TFT_DGREEN 0x580
#define TFT_CYAN 0x7FF
#define TFT_DCYAN 0x3594
#define TFT_CALIPSO 0xE0F
#define TFT_MAGENTA 0xB993
#define TFT_DMAGENTA 0x80D5
#define TFT_BLUE 0x1F
#define TFT_DBLUE 0x2013
#define TFT_LBLUE 0x537F
#define TFT_PINK 0xFCD3
#define TFT_CS 0
#define TFT_RST 1
#define TFT_DC 2
#define TFT_MOSI 3
#define TFT_SCLK 4
DFRobotDFPlayerMini Music;
#define MY_TZ "<-04>4<-03>,M9.1.6/24,M4.1.6/24" // for time() ctime()
#define MY_NTP_SERVER "cl.pool.ntp.org"
// Create the TFT display ST7735 SPI
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
ESP32Time rtc;
// WiFi setup data
//const char* ssid = "GalacticoVTR"; // Name of the Wi-Fi box
//const char* password = "19Galactico"; // MDP of the Wi-Fi box
const char* ssid = "Galactico_Salon"; // Name of the Wi-Fi box
const char* password = "saturno002"; // MDP of the Wi-Fi box
/* Globals */
time_t now; // this are the seconds since Epoch (1970) - UTC
tm timeinfo; // the structure tm holds time information in a more convenient way *
int TFTLED = 5;
int UpBtn = 6;
int DwnBtn = 7;
int SetBtn = 15;
int Idle = 9;
int AlarmBtn = 14;
int TFTbright = 1024;
const char *mainMen[] = {"> Set Alarm", "> Alarm Mode", "> Set Track", "> Exit Menu"};
const char *trackTxt[] = {"Hey Brother ", "Say Captain say.. ", "Hardest Part ", "Hokima ", "Infinity ",
"On The Loose ", "The one I Love ", "California Blue ", "Never see you agai", "Dreams ",
"Stupid Girl ", "The one I love ", "Loosing my religio", "Prayer in C ", "please release me ",
"A Sky full of ", "You're a woman ", "AhA Analogue ", "want todo is dance", "The more you live ",
"Around the world ", "DJ Don Bishop ", "Modern Talking ", "Girls Girls Girls ", " ", " ", " ", " ", " ", " "
};
int selTrack[5];
int selIndex = 0;
int scrollList = 0;
int repTimes;
int reploop = 0;
int xref;
int yref;
int yOffset = 20;
int xOffset = 5;
int lastVal;
int Mitem = 0;
int AlarmH = 0;
int AlarmM = 0;
int AlarmHBuf;
int AlarmMBuf;
bool AlarmAct = false;
int modeItem = 0;
int repWait = 5;
int repNum = 1;
int playNum = 0;
int vol = 20;
int mark;
const char *WeekDay[] = {"Domingo ", "Lunes ", "Martes ", "Miercoles ", "Jueves ", "Viernes ", "Sabado "};
bool END;
int Block[7];
int setVal = 0;
int dispPos = 0;
int newHour;
int newMinute;
int newSecond;
int prevSecond;
int actSecond;
int actMinute;
int prevMinute;
int actHour;
int count;
int i;
int x;
int y;
int v;
unsigned long lastMillis;
int ShowTime = 1000;
// --------- SETUP ---------
void setup()
{
pinMode(SetBtn, INPUT_PULLUP);
pinMode(UpBtn, INPUT_PULLUP);
pinMode(DwnBtn, INPUT_PULLUP);
pinMode(AlarmBtn, INPUT_PULLUP);
pinMode(Idle, INPUT);
pinMode(TFTLED, OUTPUT);
analogWrite(TFTLED, TFTbright);
tft.initR(INITR_BLACKTAB);
tft.setSPISpeed(320000000);
tft.setRotation(3);
tft.invertDisplay(0);
tft.fillScreen(TFT_BLACK);
tft.setTextSize(1);
tft.setTextColor(TFT_LIGHTGREY, TFT_BLACK);
tft.fillScreen(TFT_BLACK);
delay(100);
Serial.begin(9600, SERIAL_8N1, RX, TX);
delay(200);
// Serial.println(" ***** Start Setup *****");
WiFi.persistent(false);
WiFi.mode(WIFI_STA); // Optional
WiFi.begin(ssid, password);
tft.setCursor(0, 0);
tft.println(" Time init");
tft.println(" Connecting");
while (WiFi.status() != WL_CONNECTED)
{
tft.print(".");
count++;
if (count > 100) {
tft.fillScreen(TFT_BLACK);
tft.setCursor(0, 0);
tft.println("connection failed");
delay(2000);
break;
}
delay(100);
}
if (WiFi.status() == WL_CONNECTED)
{
tft.fillScreen(TFT_BLACK);
tft.setCursor(0, 0);
tft.println("Connected to ");
tft.println();
tft.println(ssid);
tft.println();
tft.println("Local ESP32 IP: ");
tft.println();
tft.println(WiFi.localIP());
delay(2000);
tft.fillScreen(TFT_BLACK);
tft.setCursor(0, 0);
tft.println("get Time from NTP...");
configTime(0, 0, MY_NTP_SERVER);
setenv("TZ", MY_TZ, 1);
tzset();
if (!getLocalTime(&timeinfo))
{
tft.setCursor(0, 0);
tft.println("Failed to obtain time");
tft.println("adjust time manually");
delay(2000);
tft.fillScreen(TFT_BLACK);
InputTime();
}
else
{
rtc.setTimeStruct(timeinfo);
tft.fillScreen(TFT_BLACK);
tft.setCursor(0, 0);
tft.println("Time set OK");
}
}
else
{
tft.fillScreen(TFT_BLACK);
InputTime();
}
Block[0] = rtc.getYear();
Block[1] = rtc.getMonth();
Block[2] = rtc.getDay();
Block[3] = rtc.getDayofWeek();
Block[4] = rtc.getHour(true);
Block[5] = rtc.getMinute();
Block[6] = rtc.getSecond();
tft.fillScreen(TFT_BLACK);
tft.setCursor(4, 5);
tft.print("RTC actual time is");
tft.setCursor(4, 12);
tft.print("-------------------");
tft.setCursor(4, 19);
if (Block[2] < 10) {
tft.print("0");
}
tft.print(Block[2]);
tft.print(".");
if (Block[1] < 9) {
tft.print("0");
}
tft.print(Block[1] + 1);
tft.print(". ");
tft.print(Block[0]);
tft.print(" ");
if (Block[4] < 10) {
tft.print("0");
} tft.print(Block[4]);
tft.print(":");
if (Block[5] < 10) {
tft.print("0");
} tft.print(Block[5]);
tft.print(":");
if (Block[6] < 10) {
tft.print("0");
} tft.println(Block[6]);
delay(1000);
tft.setCursor(20, 50);
tft.print("* Time Set ready *");
delay(1000);
tft.fillScreen(TFT_BLACK);
Music.begin(Serial);
Music.volume(25);
Music.play(26);
//Music.stop();
delay(1000);
Music.volume(vol);
showField_1();
showField_2();
showField_3();
showField_4();
// LET´S GO
} // --------------------- finish Setup ------------------------
void loop()
{
if (!digitalRead(AlarmBtn) && AlarmAct == true)
{
AlarmAct = false;
Music.stop();
showField_3();
delay(500);
}
if (!digitalRead(AlarmBtn) && AlarmAct == false)
{
AlarmAct = true;
showField_3();
delay(500);
}
actSecond = rtc.getSecond();
actMinute = rtc.getMinute();
if ((rtc.getHour(true) == AlarmH && rtc.getMinute() == AlarmM && actSecond == 0 && AlarmAct == true))
{
Alarm();
delay(300);
}
if (rtc.getHour(true) == 0 && rtc.getSecond() == 0) {
showField_1();
delay(1000);
}
if (actSecond != prevSecond) {
prevSecond = actSecond;
showField_2();
}
if (!digitalRead(SetBtn)) {
mainMenu();
}
}// ------------------------------------- End Loop ------------------------------
void Alarm()
{
showField_4vol();
if (digitalRead(Idle))
{
Music.play(selTrack[reploop] + 1);
delay(1000);
}
while (digitalRead(AlarmBtn) && !digitalRead(Idle))
{
actSecond = rtc.getSecond();
actHour = rtc.getHour(true);
if (actSecond != prevSecond)
{
prevSecond = actSecond;
showField_2();
}
if (actHour == 0 && actSecond == 0) {
showField_1();
delay(1000);
}
if (!digitalRead(UpBtn) && vol < 28)
{
vol++;
showField_4vol();
Music.volume(vol);
delay(200);
}
if (!digitalRead(DwnBtn) && vol > 10)
{
vol--;
showField_4vol();
Music.volume(vol);
delay(200);
}
}
if (!digitalRead(AlarmBtn)) {
Music.stop();
}
showField_4();
reploop++;
if (reploop < repNum)
{
AlarmM += repWait;
if (AlarmM > 59) {
AlarmM -= 60;
AlarmH++;
}
if (AlarmH > 23) {
AlarmH = 0;
}
}
else
{
AlarmM = AlarmMBuf;
AlarmH = AlarmHBuf;
reploop = 0;
}
showField_3();
}
void InputTime()
{
delay(200);
while (i < 7) // input date/time values
{
if (!digitalRead(UpBtn)) // ajust actual value
{
Block[i]++ ;
if (Block[0] > 32) {
Block[0] = 22;
}
if (Block[1] > 12) {
Block[1] = 1;
}
if (Block[2] > 31) {
Block[2] = 1;
}
if (Block[3] > 7 ) {
Block[3] = 1;
}
if (Block[4] > 23) {
Block[4] = 0;
}
if (Block[5] > 59) {
Block[5] = 0;
}
if (Block[6] > 59) {
Block[6] = 0;
}
delay(300);
}
if (!digitalRead(DwnBtn)) // ajust actual value
{
Block[i]-- ;
if (Block[0] < 25) {
Block[0] = 25;
}
if (Block[1] < 0 ) {
Block[1] = 12;
}
if (Block[2] < 0 ) {
Block[2] = 31;
}
if (Block[3] < 1 ) {
Block[3] = 7;
}
if (Block[4] < 0 ) {
Block[4] = 23;
}
if (Block[5] < 0 ) {
Block[5] = 59;
}
if (Block[6] < 0 ) {
Block[6] = 59;
}
delay(300);
}
showInput();
if (!digitalRead(SetBtn)) {
i++;
delay(500);
}
} // ready input date/time values 0 to 5
delay(100);
tft.fillScreen(TFT_BLACK);
tft.setTextSize(1);
tft.setTextColor(TFT_WHITE);
tft.setCursor(0, 12);
tft.print("Ready for adjust time");
while (digitalRead(SetBtn)) {
;
}
SetClock();
}
void showInput()
{
//tft.setFont();
int fontbase = 9;
//tft.fillScreen(TFT_BLACK);
tft.setTextSize(1);
tft.setTextColor(TFT_CYAN, TFT_BLACK);
tft.setCursor(0, 0 + fontbase);
tft.println("Now input Date/time");
tft.println("---------------------");
tft.setTextColor(TFT_YELLOW, TFT_BLACK);
tft.setCursor(0, 15 + fontbase);
tft.print("Year Month Day DoW");
for (y = 0; y < 4; y++)
{
tft.setCursor((y * 30 + 10), 25 + fontbase);
if (y == i) {
tft.setTextColor(TFT_RED, TFT_BLACK);
} else {
tft.setTextColor(TFT_YELLOW, TFT_BLACK);
}
if (Block[y] < 10) {
tft.print("0");
}
tft.print(Block[y]);
}
tft.setTextColor(TFT_YELLOW, TFT_BLACK);
tft.setCursor(0, 35 + fontbase);
tft.print("Hour Minute Second");
for (y = 4; y < 7; y++)
{
tft.setCursor(((y - 4) * 30 + 10), 45 + fontbase);
if (y == i) {
tft.setTextColor(TFT_RED, TFT_BLACK);
} else {
tft.setTextColor(TFT_YELLOW, TFT_BLACK);
}
if (Block[y] < 10) {
tft.print("0");
}
tft.print(Block[y]);
}
}
void SetClock()
{
//rtc.setTime(10,15,20,11,12,2024);
rtc.setTime(Block[6], Block[5], Block[4], Block[2], (Block[1]), Block[0] + 2000);
tft.setCursor(30, 24);
tft.print("* READY *");
delay(1000);
}
void showField_1()
{
tft.fillRoundRect(2, 2, 156, 20, 8, TFT_BLACK);
tft.setTextColor(TFT_ORANGE);
tft.setFont(&FreeMonoBoldOblique9pt7b);
tft.setCursor(3, 16);
tft.print(WeekDay[rtc.getDayofWeek()]);
//tft.print(" ");
if (rtc.getDay() < 10) {
tft.print("0");
}
tft.print(rtc.getDay());
tft.print(".");
if (rtc.getMonth() < 10) {
tft.print("0");
}
tft.print(rtc.getMonth() + 1);
}
void showField_2()
{
tft.fillRect(5, 25, 150, 39, TFT_BLACK);
tft.drawRoundRect(2, 22, 156, 45, 6, TFT_LBLUE);
tft.drawRoundRect(3, 23, 154, 43, 6, TFT_LBLUE);
tft.drawRoundRect(4, 24, 152, 41, 6, TFT_LBLUE);
tft.setTextColor(TFT_YELLOW);
tft.setFont(&FreeSerifBoldItalic24pt7b);
tft.setCursor(13, 60);
if (rtc.getHour(true) < 10) {
tft.print("0");
}
tft.print(rtc.getHour(true));
tft.print(":");
if (rtc.getMinute() < 10) {
tft.print("0");
}
tft.print(rtc.getMinute());
tft.setFont(&FreeSerifBoldItalic12pt7b);
tft.print(":");
if ((rtc.getSecond()) < 10) {
tft.print("0");
}
tft.print(rtc.getSecond());
}
void showField_3()
{
tft.fillRect(2, 67, 156, 30, TFT_BLACK);
tft.setFont(&FreeMonoBoldOblique9pt7b);
tft.setCursor(3, 87);
if (AlarmAct)
{
tft.setTextColor(TFT_RED);
tft.print("Alarm at ");
if (AlarmH < 10) {
tft.print("0");
}
tft.print(AlarmH);
tft.print(":");
if (AlarmM < 10) {
tft.print("0");
}
tft.print(AlarmM);
}
else
{
tft.setTextColor(TFT_GREEN);
tft.print("Alarm OFF");
}
}
void showField_4()
{
tft.fillRoundRect(2, 97, 156, 29, 8, TFT_DBLUE);
tft.setTextColor(TFT_YELLOW);
tft.setFont(&FreeMonoBold9pt7b);
tft.setCursor(3, 115);
tft.print("Cube Galactico");
}
void showField_4vol()
{
tft.fillRoundRect(2, 97, 156, 29, 8, TFT_DBLUE);
tft.setTextColor(TFT_YELLOW);
tft.setFont(&FreeMonoBold9pt7b);
tft.setCursor(3, 115);
tft.print("Volume ");
y = 97;
x = 70;
tft.fillRoundRect(x, y, 89, 29, 8, TFT_DBLUE);
for (v = 0; v < vol; v++)
{
tft.fillRect(72 + v * 3, y + 5, 2, 18, TFT_YELLOW);
}
}
void mainMenu()
{
showMainMenu();
delay(300);
while (digitalRead(SetBtn))
{
if (!digitalRead(UpBtn) && Mitem < 3) {
Mitem ++;
}
if (!digitalRead(DwnBtn) && Mitem > 0) {
Mitem --;
}
if (Mitem != lastVal ) {
showMainMenu();
lastVal = Mitem;
}
delay(200);
}
delay(300);
switch (Mitem)
{
case 0:
SubAlarmTime();
break;
case 1:
SubAlarmMode();
break;
case 2:
SubSetTrack();
break;
case 3:
tft.fillScreen(TFT_BLACK);
showField_1();
showField_2();
showField_3();
showField_4();
break;
}
}
void showMainMenu()
{
tft.setFont(&FreeSerifBold9pt7b);
tft.fillScreen(TFT_BLACK);
tft.setTextSize(1);
xref = 5;
yref = 20;
tft.setCursor(xref, yref);
tft.print("Alarm Main Menu");
tft.drawLine(0, 25, 160, 25, TFT_YELLOW);
yref += 30;
for (int y = 0; y < 4; y++)
{
tft.setCursor(xref + 10, yref + y * 15);
if (Mitem == y) {
tft.setTextColor(TFT_RED);
}
else {
tft.setTextColor(TFT_DGREEN);
}
tft.print(mainMen[y]);
tft.setTextColor(TFT_WHITE);
}
}
void SubAlarmTime()
{
tft.fillScreen(TFT_BLACK);
xref = 20;
yref = 20;
tft.setCursor(xref, yref);
tft.print("Set Alarm Time");
tft.drawLine(0, 25, 160, 25, TFT_ORANGE);
xref = 10;
yref = 40;
lastVal = 30;
tft.drawRoundRect(35, 40, 100, 40, 6, TFT_RED);
tft.setFont(&FreeSerifBold18pt7b);
while (digitalRead(SetBtn))
{
if (!digitalRead(UpBtn)) {
AlarmH ++;
delay(200);
}
if (!digitalRead(DwnBtn)) {
AlarmH --;
delay(200);
}
if (AlarmH > 23) {
AlarmH = 0;
}
if (AlarmH < 0) {
AlarmH = 23;
}
if (AlarmH != lastVal)
{
tft.fillRoundRect(37, 42, 96, 36, 6, TFT_YELLOW);
tft.setCursor(45, 70);
tft.setTextColor(TFT_DRED);
if (AlarmH < 10) {
tft.print("0");
}
tft.print(AlarmH);
tft.setTextColor(TFT_DGREEN);
tft.print(":");
if (AlarmM < 10) {
tft.print("0");
}
tft.print(AlarmM);
lastVal = AlarmH;
}
delay(200);
}
delay(500);
while (digitalRead(SetBtn))
{
if (!digitalRead(UpBtn)) {
AlarmM ++;
delay(200);
}
if (!digitalRead(DwnBtn)) {
AlarmM --;
delay(200);
}
if (AlarmM > 59) {
AlarmM = 0;
}
if (AlarmM < 0) {
AlarmM = 59;
}
if (AlarmM != lastVal)
{
tft.fillRoundRect(37, 42, 96, 36, 6, TFT_YELLOW);
tft.setCursor(45, 70);
tft.setTextColor(TFT_DGREEN);
if (AlarmH < 10) {
tft.print("0");
}
tft.print(AlarmH); tft.print(":");
tft.setTextColor(TFT_DRED);
if (AlarmM < 10) {
tft.print("0");
}
tft.print(AlarmM);
tft.setTextColor(TFT_YELLOW);
lastVal = AlarmM;
}
delay(200);
}
AlarmHBuf = AlarmH;
AlarmMBuf = AlarmM;
delay(100);
mainMenu();
}
void SubAlarmMode()
{
tft.fillScreen(TFT_BLACK);
tft.setFont(&FreeSerifBold9pt7b);
xref = 10;
yref = 20;
tft.setCursor(xref, yref);
tft.print("Set Alarm Mode");
tft.drawLine(0, 25, 160, 25, TFT_ORANGE);
tft.setCursor(10, 60);
tft.setTextColor(TFT_DRED);
tft.print("repeat times -> "); tft.print(repNum);
tft.setTextColor(TFT_DGREEN);
tft.setCursor(10, 85);
tft.print("waiting time -> "); tft.print(repWait);
lastVal = 99;
while (digitalRead(SetBtn))
{
if (!digitalRead(UpBtn) && repNum < 3) {
repNum++;
}
if (!digitalRead(DwnBtn) && repNum > 1) {
repNum--;
}
if (lastVal != repNum)
{
tft.fillRect(0, 40, 160, 20, TFT_BLACK);
tft.setCursor(10, 60);
tft.setTextColor(TFT_DRED);
tft.print("repeat times -> "); tft.print(repNum);
lastVal = repNum;
}
delay(300);
}
tft.setCursor(10, 60);
tft.setTextColor(TFT_DGREEN);
tft.print("repeat times -> "); tft.print(repNum);
delay(300);
while (digitalRead(SetBtn))
{
if (!digitalRead(UpBtn) && repWait < 15) {
repWait++;
}
if (!digitalRead(DwnBtn) && repWait > 5) {
repWait--;
}
if (lastVal != repWait)
{
tft.fillRect(0, 65, 160, 20, TFT_BLACK);
tft.setCursor(10, 85);
tft.setTextColor(TFT_RED);
tft.print("waiting time -> "); tft.print(repWait);
lastVal = repWait;
}
delay(300);
}
//delay(100);
mainMenu();
}
void SubSetTrack()
{
tft.fillScreen(TFT_BLACK);
tft.setFont(&FreeSerifBold9pt7b);
tft.setCursor(10, 20);
tft.print("Select Tracks");
tft.drawLine(0, 25, 160, 25, TFT_ORANGE);
lastVal = 99;
xref = 0;
yref = 40;
tft.setFont();
tft.setTextSize(1);
while (digitalRead(SetBtn))
{
if (!digitalRead(UpBtn) && scrollList < 24) {
scrollList++;
}
if (!digitalRead(DwnBtn) && scrollList > 0) {
scrollList--;
}
if (!digitalRead(AlarmBtn))
{
if (selIndex == repNum) {
selIndex = 0;
}
selTrack[selIndex] = scrollList;
mark = selIndex;
lastVal = 99;
selIndex++;
}
if (lastVal != scrollList)
{
tft.fillRect(0, yref, 160, 80, TFT_BLACK);
for (int i = 0; i < 6; i++)
{
if (i == 0) {
tft.fillRect(5, 26, 160, 12, TFT_BLACK);
tft.setTextColor(TFT_GREEN);
}
else {
tft.setTextColor(TFT_ORANGE);
}
tft.setCursor(xref, yref + i * 12);
tft.print(trackTxt[scrollList + i]); tft.print(" > ");
for (mark = 0; mark < repNum; mark++)
{
if (selTrack[mark] == scrollList + i) {
tft.print(mark + 1);
tft.print(" ");
}
}
}
lastVal = scrollList;
}
tft.setTextColor(TFT_YELLOW);
delay(200);
}
//while(digitalRead(AlarmBtn)) {;}
delay(300);
mainMenu();
}
Any ideas why TFT_eSPI works great on a ESP32-C3 but Adafruit_ST7735 on a ESP32-C6 works very slow ?
Thanks guys