Forum >DFR0669 + DFR0654: trouble with "createbutton" function

DFR0669 + DFR0654: trouble with "createbutton" function

userHead Staldy 2025-06-29 23:16:57 416 Views2 Replies

Hello everyone,

 

I’m a beginner in C programming and I’m using a 3.5″ DFR0669 screen with a FireBeetle ESP32, coding on the Arduino platform.

 

My project is to build an alarm clock by adding a DFPlayer Pro module, a speaker, and a large physical button for stop/snooze. Eventually, it will support up to four alarms with recurrence and allow me to choose a custom song for each.

 

The first screen connects the FireBeetle ESP32 to the network and lets you select the language, using credentials stored in a text file on an SD card attached to the display. After that, I plan to turn off Wi-Fi and synchronize with an NTP server once a day.

 

I’ve created my first screen and I’m now trying to add buttons to switch to the “Help” screen and to the next screen (Clock/Settings). I’m struggling with the createButton() function: I tested the example and it works fine, but I can’t implement it in my own code.

 

Actually, the font changes and a blue/gray area appears on the left as soon as I add the button, and my icon disappears, it doesn’t look right. Can someone help me fix this? Thanks!

 

I'm sharing the working/not working codes with pictures :-)

 

Working code and the result:

 

#include "WiFi.h"

#include "SD.h"

#include "SPI.h"

#include "DFRobot_UI.h"

#include "DFRobot_GDL.h"

#include "DFRobot_Touch.h"

#include "time.h"

#include "icon.h"


 

#define TFT_DC   D2

#define TFT_CS   D6

#define TFT_RST  D3

#define TFT_SD   D7

#define TFT_BL   D13


 

DFRobot_ILI9488_320x480_HW_SPI screen(TFT_DC, TFT_CS, TFT_RST, TFT_BL);

DFRobot_Touch_GT911 touch;

DFRobot_UI ui(&screen, &touch);


 

// Placeholder color (light gray)

#define CLR_PLACEHOLDER COLOR_RGB565_LGRAY


 

// Wi-Fi and language configuration

char ssid[64]     = "";

char password[64] = "";

char lang[4]      = "en";


 

// Day names in French and English

const char* dayNames_fr[] = {

  "DIMANCHE","LUNDI","MARDI","MERCREDI","JEUDI","VENDREDI","SAMEDI"

};

const char* dayNames_en[] = {

  "SUNDAY","MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"

};


 

// Layout constants

const int padH        = 15;

const int padV        = 13;

const int iconSize    = 48;

const int iconSpacing = 6;

const int box1Size    = 60;

const int box2Size    = 138;

const int boxSpacing  = 18;

const int radius      = 12;


 

// Draw a small icon with a rounded border

void drawIconBox(int x, int y, const unsigned char* icon, uint16_t color) {

  screen.drawRoundRect(x, y, box1Size, box1Size, radius, color);

  screen.drawBitmap(x + iconSpacing, y + iconSpacing,

                    icon, iconSize, iconSize, color);

}


 

// Draw a larger “language” box with label

void drawLangBox(int x, int y, const unsigned char* icon,

                 const char* label, uint16_t color) {

  screen.drawRoundRect(x, y, box2Size, box1Size, radius, color);

  screen.drawBitmap(x + iconSpacing, y + iconSpacing,

                    icon, iconSize, iconSize, color);

  screen.setTextColor(color);

  screen.setTextSize(3);

  screen.setCursor(x + box1Size + iconSpacing, y + 18);

  screen.print(label);

}


 

void setup() {

  Serial.begin(115200);

  delay(500);

  ui.begin();


 

  // 1) Initialize display

  screen.setRotation(1);

  screen.fillScreen(COLOR_RGB565_BLACK);


 

  // 2) Initialize SPI for SD card and then Wi-Fi and NTP

  SPI.begin(18, 19, 23, TFT_SD);


 

  // Placeholder: draw all status icons in gray

  int x0 = padH;

  int y0 = padV + box1Size + boxSpacing;

  drawIconBox(x0 + 0*(box1Size+boxSpacing), y0, icon_sd_nok, CLR_PLACEHOLDER);

  drawIconBox(x0 + 1*(box1Size+boxSpacing), y0, icon_file_nok, CLR_PLACEHOLDER);

  drawLangBox(x0 + 2*(box1Size+boxSpacing), y0, icon_lang, "  ", CLR_PLACEHOLDER);

  drawIconBox(x0 + 4*(box1Size+boxSpacing), y0, icon_wifi_off, CLR_PLACEHOLDER);


 

  // 3) Check SD card

    delay(500);

  bool sdOk = SD.begin(TFT_SD);

  uint16_t sdColor = sdOk ? COLOR_RGB565_GREEN : COLOR_RGB565_RED;

  // Clear area before redrawing

  screen.fillRect(x0 + 0*(box1Size+boxSpacing),

                  y0,

                  box1Size,

                  box1Size,

                  COLOR_RGB565_BLACK);

  drawIconBox(x0 + 0*(box1Size+boxSpacing), y0,

              sdOk ? icon_sd_ok : icon_sd_nok,

              sdColor);


 

  // 4) Check setup.txt on SD

  bool fileOk = false;

  if (sdOk) {

    File f = SD.open("/setup.txt");

    if (f) {

      fileOk = true;

      while (f.available()) {

        String L = f.readStringUntil('\n');

        L.trim();

        if (L.startsWith("SSID="))  strncpy(ssid,     L.c_str()+5, sizeof(ssid)-1);

        if (L.startsWith("PASS="))  strncpy(password, L.c_str()+5, sizeof(password)-1);

        if (L.startsWith("LANG="))  strncpy(lang,     L.c_str()+5, sizeof(lang)-1);

      }

      f.close();

    }

  }

  uint16_t fileColor = fileOk ? COLOR_RGB565_GREEN : COLOR_RGB565_RED;

  screen.fillRect(x0 + 1*(box1Size+boxSpacing),

                  y0,

                  box1Size,

                  box1Size,

                  COLOR_RGB565_BLACK);

  drawIconBox(x0 + 1*(box1Size+boxSpacing), y0,

              fileOk ? icon_file_ok : icon_file_nok,

              fileColor);


 

  // 5) Display language status

   delay(500);

  bool validLang = (strcmp(lang,"fr")==0)||(strcmp(lang,"en")==0);

  char langLabel[3] = {0};

  if (validLang) strcpy(langLabel, strcmp(lang,"fr")==0?"FR":"EN");

  else           strncpy(langLabel, lang, 2);

  uint16_t langColor;

  if (!fileOk)        langColor = COLOR_RGB565_ORANGE; // default if no file

  else if (validLang) langColor = COLOR_RGB565_GREEN;

  else                 langColor = COLOR_RGB565_RED;

  screen.fillRect(x0 + 2*(box1Size+boxSpacing),

                  y0,

                  box2Size,

                  box1Size,

                  COLOR_RGB565_BLACK);

  drawLangBox(x0 + 2*(box1Size+boxSpacing), y0,

              icon_lang, langLabel, langColor);


 

  // 6) Wi-Fi connection attempt

   delay(500);

  WiFi.begin(ssid, password);

  unsigned long t0 = millis();

  while (WiFi.status()!=WL_CONNECTED && millis()-t0<10000) {

    delay(200);

  }

  bool wifiOk = (WiFi.status()==WL_CONNECTED);

  uint16_t wifiColor = wifiOk ? COLOR_RGB565_GREEN : COLOR_RGB565_RED;

  screen.fillRect(x0 + 4*(box1Size+boxSpacing),

                  y0,

                  box1Size,

                  box1Size,

                  COLOR_RGB565_BLACK);

  drawIconBox(x0 + 4*(box1Size+boxSpacing), y0,

              wifiOk ? icon_wifi_on : icon_wifi_off,

              wifiColor);


 

  // 7) Configure NTP so getLocalTime() will work

  configTzTime("CET-1CEST,M3.5.0/2,M10.5.0/3", "pool.ntp.org");


 

  // 8) Draw Help / Refresh / Check icons (temporary buttons)

  drawIconBox(405,                padH, icon_help,    COLOR_RGB565_BLUE);

  drawIconBox(405 - (18 + 60),    247,  icon_refresh, COLOR_RGB565_ORANGE);

  drawIconBox(405,                247,  icon_check,   COLOR_RGB565_DGREEN);

}


 

void loop() {

  ui.refresh();  // handle UI touch callbacks (if any)


 

  // Update date/time once per minute

  static char lastDate[32] = "";

  static char lastTime[6]  = "";

  static unsigned long lastCheck = 0;


 

  if (millis() - lastCheck < 1000) return;

  lastCheck = millis();


 

  struct tm ti;

  if (!getLocalTime(&ti)) return;


 

  // Format date string and time string

  char d[32], t[6];

  const char** dn = (strcmp(lang,"fr")==0) ? dayNames_fr : dayNames_en;

  snprintf(d, sizeof(d),

           "%s %02d.%02d.%04d",

           dn[ti.tm_wday],

           ti.tm_mday,

           ti.tm_mon + 1,

           ti.tm_year + 1900);

  snprintf(t, sizeof(t),

           "%02d:%02d",

           ti.tm_hour,

           ti.tm_min);


 

  // Redraw if changed

  if (strcmp(d, lastDate) || strcmp(t, lastTime)) {

    strcpy(lastDate, d);

    strcpy(lastTime, t);

    screen.fillRect(15, 180, 300, 70, COLOR_RGB565_BLACK);

    screen.setTextColor(COLOR_RGB565_WHITE);

    screen.setTextSize(3);

    screen.setCursor(15, 180);

    screen.print(d);

    screen.setCursor(15, 210);

    screen.print(t);

  }

}


 

 

 

I add the first button: 

 

#include "WiFi.h"

#include "SD.h"

#include "SPI.h"

#include "DFRobot_UI.h"

#include "DFRobot_GDL.h"

#include "DFRobot_Touch.h"

#include "time.h"

#include "icon.h"


 

#define TFT_DC   D2

#define TFT_CS   D6

#define TFT_RST  D3

#define TFT_SD   D7

#define TFT_BL   D13


 

DFRobot_ILI9488_320x480_HW_SPI screen(TFT_DC, TFT_CS, TFT_RST, TFT_BL);

DFRobot_Touch_GT911 touch;

DFRobot_UI ui(&screen, &touch);


 

// Placeholder color (light gray)

#define CLR_PLACEHOLDER COLOR_RGB565_LGRAY


 

// Wi-Fi and language configuration

char ssid[64]     = "";

char password[64] = "";

char lang[4]      = "en";


 

// Day names in French and English

const char* dayNames_fr[] = {

  "DIMANCHE","LUNDI","MARDI","MERCREDI","JEUDI","VENDREDI","SAMEDI"

};

const char* dayNames_en[] = {

  "SUNDAY","MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"

};


 

// Layout constants

const int padH        = 15;

const int padV        = 13;

const int iconSize    = 48;

const int iconSpacing = 6;

const int box1Size    = 60;

const int box2Size    = 138;

const int boxSpacing  = 18;

const int radius      = 12;


 

// Draw a small icon with a rounded border

void drawIconBox(int x, int y, const unsigned char* icon, uint16_t color) {

  screen.drawRoundRect(x, y, box1Size, box1Size, radius, color);

  screen.drawBitmap(x + iconSpacing, y + iconSpacing,

                    icon, iconSize, iconSize, color);

}


 

// Draw a larger “language” box with label

void drawLangBox(int x, int y, const unsigned char* icon,

                 const char* label, uint16_t color) {

  screen.drawRoundRect(x, y, box2Size, box1Size, radius, color);

  screen.drawBitmap(x + iconSpacing, y + iconSpacing,

                    icon, iconSize, iconSize, color);

  screen.setTextColor(color);

  screen.setTextSize(3);

  screen.setCursor(x + box1Size + iconSpacing, y + 18);

  screen.print(label);

}




 

//Callback function for three buttons

void btnCallback(DFRobot_UI::sButton_t &btn,DFRobot_UI::sTextBox_t &obj) {

 /* String text((char *)btn.text);

   if(text == "ON"){

    obj.setText("you have touch button on");

    }

   else if(text == "OFF"){

    obj.setText("you have touch button off");

    }

   else if(text == "clr"){

    obj.deleteChar();

    }*/

   

}


 

void setup() {

  Serial.begin(115200);

  delay(500);

  ui.begin();

//ui.setTheme(DFRobot_UI::MODERN);

  // 1) Initialize display

  screen.setRotation(1);

  screen.fillScreen(COLOR_RGB565_BLACK);


 

  // 2) Initialize SPI for SD card and then Wi-Fi and NTP

  SPI.begin(18, 19, 23, TFT_SD);


 

  // Placeholder: draw all status icons in gray

  int x0 = padH;

  int y0 = padV + box1Size + boxSpacing;

  drawIconBox(x0 + 0*(box1Size+boxSpacing), y0, icon_sd_nok, CLR_PLACEHOLDER);

  drawIconBox(x0 + 1*(box1Size+boxSpacing), y0, icon_file_nok, CLR_PLACEHOLDER);

  drawLangBox(x0 + 2*(box1Size+boxSpacing), y0, icon_lang, "  ", CLR_PLACEHOLDER);

  drawIconBox(x0 + 4*(box1Size+boxSpacing), y0, icon_wifi_off, CLR_PLACEHOLDER);


 

  // 3) Check SD card

    delay(500);

  bool sdOk = SD.begin(TFT_SD);

  uint16_t sdColor = sdOk ? COLOR_RGB565_GREEN : COLOR_RGB565_RED;

  // Clear area before redrawing

  screen.fillRect(x0 + 0*(box1Size+boxSpacing),

                  y0,

                  box1Size,

                  box1Size,

                  COLOR_RGB565_BLACK);

  drawIconBox(x0 + 0*(box1Size+boxSpacing), y0,

              sdOk ? icon_sd_ok : icon_sd_nok,

              sdColor);


 

  // 4) Check setup.txt on SD

  bool fileOk = false;

  if (sdOk) {

    File f = SD.open("/setup.txt");

    if (f) {

      fileOk = true;

      while (f.available()) {

        String L = f.readStringUntil('\n');

        L.trim();

        if (L.startsWith("SSID="))  strncpy(ssid,     L.c_str()+5, sizeof(ssid)-1);

        if (L.startsWith("PASS="))  strncpy(password, L.c_str()+5, sizeof(password)-1);

        if (L.startsWith("LANG="))  strncpy(lang,     L.c_str()+5, sizeof(lang)-1);

      }

      f.close();

    }

  }

  uint16_t fileColor = fileOk ? COLOR_RGB565_GREEN : COLOR_RGB565_RED;

  screen.fillRect(x0 + 1*(box1Size+boxSpacing),

                  y0,

                  box1Size,

                  box1Size,

                  COLOR_RGB565_BLACK);

  drawIconBox(x0 + 1*(box1Size+boxSpacing), y0,

              fileOk ? icon_file_ok : icon_file_nok,

              fileColor);


 

  // 5) Display language status

   delay(500);

  bool validLang = (strcmp(lang,"fr")==0)||(strcmp(lang,"en")==0);

  char langLabel[3] = {0};

  if (validLang) strcpy(langLabel, strcmp(lang,"fr")==0?"FR":"EN");

  else           strncpy(langLabel, lang, 2);

  uint16_t langColor;

  if (!fileOk)        langColor = COLOR_RGB565_ORANGE; // default if no file

  else if (validLang) langColor = COLOR_RGB565_GREEN;

  else                 langColor = COLOR_RGB565_RED;

  screen.fillRect(x0 + 2*(box1Size+boxSpacing),

                  y0,

                  box2Size,

                  box1Size,

                  COLOR_RGB565_BLACK);

  drawLangBox(x0 + 2*(box1Size+boxSpacing), y0,

              icon_lang, langLabel, langColor);


 

  // 6) Wi-Fi connection attempt

   delay(500);

  WiFi.begin(ssid, password);

  unsigned long t0 = millis();

  while (WiFi.status()!=WL_CONNECTED && millis()-t0<10000) {

    delay(200);

  }

  bool wifiOk = (WiFi.status()==WL_CONNECTED);

  uint16_t wifiColor = wifiOk ? COLOR_RGB565_GREEN : COLOR_RGB565_RED;

  screen.fillRect(x0 + 4*(box1Size+boxSpacing),

                  y0,

                  box1Size,

                  box1Size,

                  COLOR_RGB565_BLACK);

  drawIconBox(x0 + 4*(box1Size+boxSpacing), y0,

              wifiOk ? icon_wifi_on : icon_wifi_off,

              wifiColor);


 

  // 7) Configure NTP so getLocalTime() will work

  configTzTime("CET-1CEST,M3.5.0/2,M10.5.0/3", "pool.ntp.org");


 

  // 8) Draw Help / Refresh / Check icons (temporary buttons)



 

  //Create a button control on the screen

  DFRobot_UI::sButton_t & btn1 = ui.creatButton();

  //Set the name of the button

  btn1.setText("HELP");

  btn1.bgColor = COLOR_RGB565_BLUE;

  btn1.setCallback(btnCallback);

 

 // btn1.setOutput(&tb);

  ui.draw(&btn1,405,padH,box1Size,box1Size);


 

  //drawIconBox(405,                padH, icon_help,    COLOR_RGB565_BLUE);

  drawIconBox(405 - (18 + 60),    247,  icon_refresh, COLOR_RGB565_ORANGE);

  drawIconBox(405,                247,  icon_check,   COLOR_RGB565_DGREEN);

}


 

void loop() {

  ui.refresh();  // handle UI touch callbacks (if any)


 

  // Update date/time once per minute

  static char lastDate[32] = "";

  static char lastTime[6]  = "";

  static unsigned long lastCheck = 0;


 

  if (millis() - lastCheck < 1000) return;

  lastCheck = millis();


 

  struct tm ti;

  if (!getLocalTime(&ti)) return;


 

  // Format date string and time string

  char d[32], t[6];

  const char** dn = (strcmp(lang,"fr")==0) ? dayNames_fr : dayNames_en;

  snprintf(d, sizeof(d),

           "%s %02d.%02d.%04d",

           dn[ti.tm_wday],

           ti.tm_mday,

           ti.tm_mon + 1,

           ti.tm_year + 1900);

  snprintf(t, sizeof(t),

           "%02d:%02d",

           ti.tm_hour,

           ti.tm_min);


 

  // Redraw if changed

  if (strcmp(d, lastDate) || strcmp(t, lastTime)) {

    strcpy(lastDate, d);

    strcpy(lastTime, t);

    screen.fillRect(15, 180, 300, 70, COLOR_RGB565_BLACK);

    screen.setTextColor(COLOR_RGB565_WHITE);

    screen.setTextSize(3);

    screen.setCursor(15, 180);

    screen.print(d);

    screen.setCursor(15, 210);

    screen.print(t);

  }

}


 

 

 

2025-07-03 14:45:27

The UI button drawing might set a font/color internally and not reset it. Always set your desired font and color after you draw buttons:

// After drawing buttons
screen.setTextColor(COLOR_RGB565_WHITE);
screen.setTextSize(3);
screen.setFont(&FreeSans9pt7b);  // or whatever font you want
 

userHeadPic ahsrab.rifat
Staldy wrote:

Thank you !

For now, I’ve placed the touchscreen on the side and I’m using an RGB button and an AD keyboard, and that gets the job done.

2025-07-08 14:06:08
1 Replies