I'm making a Remote Control for my RC's and now i am programming the menu.
It works fine, except for it's speed. I have to hold the push button for a long time untill the ESP32 detect it. I don't know how to optimize the code. Should I use multithreading?
Code:
#include <Arduino.h>
#include <U8g2lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
#define LCDWidth u8g2.getDisplayWidth()
#define ALIGN_CENTER(t) ((LCDWidth - (u8g2.getUTF8Width(t))) / 2)
#define ALIGN_RIGHT(t) (LCDWidth - u8g2.getUTF8Width(t))
#define ALIGN_LEFT 0
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // All Boards without Reset of the Display
// 'Max', 20x10px
const unsigned char maxbat [] PROGMEM = {
0xfc, 0xff, 0x0f, 0x04, 0x00, 0x08, 0xf7, 0xde, 0x0b, 0xf1, 0xde, 0x0b, 0xf1, 0xde, 0x0b, 0xf1,
0xde, 0x0b, 0xf1, 0xde, 0x0b, 0xf7, 0xde, 0x0b, 0x04, 0x00, 0x08, 0xfc, 0xff, 0x0f
};
// 'Medium', 20x10px
const unsigned char medbat [] PROGMEM = {
0xfc, 0xff, 0x0f, 0x04, 0x00, 0x08, 0x07, 0xde, 0x0b, 0x01, 0xde, 0x0b, 0x01, 0xde, 0x0b, 0x01,
0xde, 0x0b, 0x01, 0xde, 0x0b, 0x07, 0xde, 0x0b, 0x04, 0x00, 0x08, 0xfc, 0xff, 0x0f
};
// 'Low', 20x10px
const unsigned char lowbat [] PROGMEM = {
0xfc, 0xff, 0x0f, 0x04, 0x00, 0x08, 0x07, 0xc0, 0x0b, 0x01, 0xc0, 0x0b, 0x01, 0xc0, 0x0b, 0x01,
0xc0, 0x0b, 0x01, 0xc0, 0x0b, 0x07, 0xc0, 0x0b, 0x04, 0x00, 0x08, 0xfc, 0xff, 0x0f
};
// 'ConfigIcon', 13x13px
const unsigned char configIcon [] PROGMEM = {
0x00, 0x00, 0x4e, 0x04, 0x4a, 0x04, 0x4e, 0x04, 0x44, 0x0e, 0x44, 0x0a, 0x44, 0x0e, 0x44, 0x04,
0xe4, 0x04, 0xa4, 0x04, 0xe4, 0x04, 0x44, 0x04, 0x00, 0x00
};
// 'JogosIcon', 10x10px
const unsigned char JogosIcon [] PROGMEM = {
0x02, 0x01, 0xfd, 0x02, 0x01, 0x02, 0xcd, 0x02, 0x45, 0x02, 0x01, 0x02, 0x79, 0x02, 0x85, 0x02,
0x85, 0x02, 0x02, 0x01
};
// 'VoltarIcon', 10x10px
const unsigned char VoltarIcon [] PROGMEM = {
0x30, 0x00, 0x18, 0x00, 0x0c, 0x00, 0xfe, 0x00, 0x0c, 0x01, 0x18, 0x02, 0x30, 0x02, 0x00, 0x01,
0xfc, 0x00, 0x00, 0x00
};
// 'JoysticksIcon', 10x10px
const unsigned char JoysticksIcon [] PROGMEM = {
0x30, 0x00, 0x78, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0x78, 0x00, 0x30, 0x00, 0x30, 0x00, 0x78, 0x00,
0xfe, 0x01, 0xff, 0x03
};
// 'PowerSavingIcon', 10x10px
const unsigned char PowerSavingIcon [] PROGMEM = {
0x30, 0x00, 0xfc, 0x00, 0x84, 0x00, 0x94, 0x00, 0xa4, 0x00, 0x94, 0x00, 0xa4, 0x00, 0x94, 0x00,
0x84, 0x00, 0xfc, 0x00
};
// 'ControlesIcon', 10x10px
const unsigned char ControlesIcon [] PROGMEM = {
0x78, 0x00, 0x86, 0x01, 0x32, 0x01, 0x49, 0x02, 0x49, 0x02, 0x79, 0x02, 0x49, 0x02, 0x4a, 0x01,
0x86, 0x01, 0x78, 0x00
};
const uint8_t* bitmaps[] = { VoltarIcon, ControlesIcon, PowerSavingIcon, JogosIcon, JoysticksIcon, VoltarIcon, VoltarIcon };
// ============================================================ //
const unsigned char *batLevel;
const unsigned char *RCbatLevel;
char * rcName = "IVECO HIGHWAY";
int canal = 123;
int start = 0;
int selected = 1; // Para os menus
unsigned long startMillis; //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 1000; //the value is a number of milliseconds
bool menuAtivo = false;
void setup(void) {
u8g2.begin();
startMillis = millis(); //initial start time
pinMode(14, INPUT_PULLUP);
pinMode(13, INPUT_PULLUP);
pinMode(12, INPUT_PULLUP);
Serial.begin(115200);
}
int x = 0;
void loop() {
if(menuAtivo) {
menu();
return;
}
currentMillis = millis(); //get the current "time" (actually the number of milliseconds since the program started)
if (currentMillis - startMillis >= period) //test whether the period has elapsed
{
u8g2.clearBuffer(); // clear the internal memory
bateria();
u8g2.setFont(u8g2_font_amstrad_cpc_extended_8u);
u8g2.setCursor(1, 13);
u8g2.print(F("CANAL: "));
u8g2.setCursor(55, 13);
u8g2.print(canal);
u8g2.setFont(u8g2_font_t0_11_mr);
u8g2.setCursor(ALIGN_CENTER(rcName), 30);
u8g2.print(rcName);
// Ăcones
u8g2.drawXBMP(107, 3, 20, 10, batLevel);
u8g2.drawXBMP(107, 52, 20, 10, RCbatLevel);
u8g2.drawXBMP(1, 50, 13, 13, configIcon);
u8g2.drawHLine(0, 15, 128);
u8g2.drawHLine(0, 47, 128);
u8g2.sendBuffer(); // transfer internal memory to the display
x += 1;
}
if (x == 5) {
menuAtivo = true;
}
}
void Controles() {}
void PowerSaving() {}
void Jogos() {}
void Debug() {}
// =========MENU========= //
typedef void (*FuncPtr)();
void menu() {
const char *options[5] = {
" Voltar",
" Controles",
" Power Saving",
" Jogos",
" Debug"
};
FuncPtr funcoesMenu[5] = {
loop,
Controles,
PowerSaving,
Jogos,
Debug
};
const int menuLength = sizeof(options) / sizeof(options[0]);
const unsigned long period = 20; // Intervalo em milissegundos
int start = 0;
selected = 0; // Começa no item "Voltar"
while (menuAtivo) {
if (digitalRead(14) == LOW) {
selected += 1;
if (selected >= menuLength) {
selected = 0; // Volta para o primeiro item
start = 0;
}
if (selected >= start + 3) {
start += 1; // Ajuste o inĂcio para rolar para baixo
}
}
if (digitalRead(12) == LOW) {
if (selected == 0) {
selected = menuLength - 1; // Volta para o Ășltimo item
start = menuLength - 3; // Ajuste o inĂcio para mostrar os Ășltimos itens
} else {
selected -= 1;
}
if (selected < start) {
start -= 1; // Ajuste o inĂcio para rolar para cima
}
}
if (digitalRead(13) == LOW) {
//rodando = false;
if (selected == 0) {
menuAtivo = false;
return;
}
funcoesMenu[selected](); // Chame a função correspondente ao item selecionado
}
currentMillis = millis();
if (currentMillis - startMillis >= period) {
startMillis = currentMillis; // Reset do timer
u8g2.clearBuffer();
u8g2.setCursor(ALIGN_CENTER("MENU"), 13);
u8g2.print(F("MENU"));
u8g2.drawHLine(0, 15, 128);
for (int i = start; i < start + 5 && i < menuLength; i++) {
int yPos = 15 + (i - start) * 12;
if (i == selected) {
u8g2.setDrawColor(1);
u8g2.drawBox(0, yPos + 6, 128, 10);
u8g2.setDrawColor(0);
} else {
u8g2.setDrawColor(1);
}
u8g2.drawXBMP(0, yPos + 6, 10, 10, bitmaps[i]);
u8g2.setCursor(14, yPos + 15);
u8g2.print(options[i]);
}
u8g2.sendBuffer();
}
}
}
void bateria() {
// LĂȘ a V. bateria
int x = 60; // V. Ficticia (Controle)
int y = 99; // V. Ficticia (Carrinho)
if (x > 66) {
batLevel = maxbat;
} else if (x > 33) {
batLevel = medbat;
} else {
batLevel = lowbat;
}
if (y > 66) {
RCbatLevel = maxbat;
} else if (y > 33) {
RCbatLevel = medbat;
} else {
RCbatLevel = lowbat;
}
}
The "Issue" is happening on the 'if (digitalRead(13))', 'if (digitalRead(12))', 'if (digitalRead(14))'.
As I said, I have to hold the button for a long time for the esp32 to read the click
