ESP32 - 3.5" lcd touch - MCUFRIEND_kbv - Adafruit_GFX_Button

buongiorno a tutti,

ho un esp32 wemos col formfactory di un arduino uno così da poter installare direttamente l'lcd coi piedini originali e la modifica hardware consigliata da Bodmer, con diverse difficoltà sono riuscito a far funzionare tutto ciò che mi serve, sia lcd che touch e libreria Adafruit_GFX_Button, purtroppo però ho la necessità di avere più "pagine/schermate" con diversi pulsanti, quindi ho utilizzato come consigliato, degli array di oggetti contenenti i pulsanti per ogni schermata, il problema è che quando vado a caricare il software con questi array dichiarati e/o richiamati dalle funzioni che verificano la pressione del tasto, l'esp32 impazzisce andando in loop di riavvio, in pratica parte, schermo bianco e si riavvia. Se commento le funzioni incriminate tutto torna a funzionare, dalle mie prove sembra che il problema sia dato dall'* di Adafruit_GFX_Button necessario per richiamare l'array che mi interessa... ad esempio se dichiaro l'array:

Adafruit_GFX_Button *interfaccia1 = { &calcozButton_btn, &tempozButton_btn, NULL };

l'esp32 impazzisce e si riavvia di continuo, se lo dichiaro come:

Adafruit_GFX_Button* interfaccia1 = { &calcozButton_btn, &tempozButton_btn, NULL };

si avvia tranquillamente...

invece con la funzione:

bool update_button_list(Adafruit_GFX_Button **pb){ }

non riesco a far funzionare niente, l'esp32 si riavvia di continuo...

suggerimenti?

Riporta (mettendo nei tag code, altrimenti vedi che schifo di simboli vengono fuori) esattamente la dichiarazione di quel array, così non si legge/capisce nulla.
Per una variabile/oggetto singola avere * vicino al nome classe o al nome variabile non cambia, a meno di un compilatore impazzito.

Ho inserito un array per intero, ne avevo estromesso il contenuto inizialmente.

p.s. sono già dentro i tag <code></code>

Nella versione che impazzisce manca lo = di assegnazione

no è stato un mio errore di battitura, l' "=" c'è in entrambe, l'unica differenza è la posizione dell'asterisco, ma il problema maggiore lo ho sul richiamo dell'array nella funzione:

bool update_button_list(Adafruit_GFX_Button **pb){ }

Prova a mettere l'intero sorgente

allora il codice intero non lo posso pubblicare, però ne ho estratto una parte semplificata.

Adafruit_GFX_Button		btn1, btn2, btn3, btn11, btn12, btn13, btn21, btn22, btn23;

Adafruit_GFX_Button* interfaccia0[] = { &btn1, &btn2, &btn3, NULL };
Adafruit_GFX_Button* interfaccia1[] = { &btn11, &btn12, &btn13, NULL };
Adafruit_GFX_Button* interfaccia2[] = { &btn21, &btn22, &btn23, NULL };

#define PRESSURE 200

#define NERO      	0x0000
#define BLU       		0x421F
#define ROSSO     	0xF800
#define VERDE     	0x0681
#define CIANO     	0x07FF
#define MAGENTA   0xF81F
#define GIALLO      	0xFFE0
#define BIANCO      0xFFFF
#define AZZURRO   	0x633F
#define ARANCIO 	0xFCE1

void setup() {
    btn1.initButtonUL(&tft, 238,	20,	67,	43,  BLU, BLU, BIANCO, "1", 1);      //      8
    btn2.initButtonUL(&tft, 314, 20, 67, 43,  BLU, BLU, BIANCO, "2", 1);      //      9
    btn3.initButtonUL(&tft, 391, 20, 67, 43,  BLU, BLU, BIANCO, "3", 1);      //      10
    btn11.initButtonUL(&tft, 238, 69, 67, 43,  BLU, BLU, BIANCO, "4", 1);      //      11
    btn12.initButtonUL(&tft, 314, 69, 67, 43, BLU, BLU, BIANCO, "5", 1);      //      12
    btn13.initButtonUL(&tft, 391,	69,	67,	43, BLU, BLU, BIANCO, "6", 1);      //      13
    btn21.initButtonUL(&tft, 238, 119, 67, 43, BLU, BLU, BIANCO, "7", 1);      //      14
    btn22.initButtonUL(&tft, 314, 119, 67, 43, BLU, BLU, BIANCO, "8", 1);      //      15
    btn23.initButtonUL(&tft, 391,	119,	67,	43, BLU, BLU, BIANCO, "9", 1);      //      16
	
	update_button_list(interfaccia0);
	draw_button_list(interfaccia0);
}

void loop() {

	if (interfaccia == 0) {
		update_button_list(interfaccia0);                                                               //process all buttons
		if ( btn1.justPressed() ) { Serial.println("1"); }
		if ( btn2.justPressed() ) { Serial.println("2"); }
		if ( btn3.justPressed() ) { Serial.println("3"); }
	}
	if (interfaccia == 1) {
		update_button_list(interfaccia1);                                                               //process all buttons
		if ( btn11.justPressed() ) { Serial.println("11"); }
		if ( btn12.justPressed() ) { Serial.println("12"); }
		if ( btn13.justPressed() ) { Serial.println("13"); }
	}
	if (interfaccia == 2) {
		update_button_list(interfaccia2);                                                               //process all buttons
		if ( btn21.justPressed() ) { Serial.println("21"); }
		if ( btn22.justPressed() ) { Serial.println("22"); }
		if ( btn23.justPressed() ) { Serial.println("23"); }
	}
	
}


void readResistiveTouch(void){
    tp = ts.getPoint();
    pinMode(YP, OUTPUT);      //restore shared pins
    pinMode(XM, OUTPUT);
    //digitalWrite(YP, HIGH);  //because TFT control pins
    //digitalWrite(XM, HIGH);
    //    Serial.println("tp.x=" + String(tp.x) + ", tp.y=" + String(tp.y) + ", tp.z =" + String(tp.z));
}

bool ISPRESSED(void){
    // .kbv this was too sensitive !!
    // now touch has to be stable for 50ms
    int count = 0;
    bool state, oldstate;
    while (count < 10) {
        readResistiveTouch();
        state = tp.z != 0;     //ADJUST THIS VALUE TO SUIT YOUR SCREEN e.g. 20 ... 250
        if (state == oldstate) count++;
        else count = 0;
        oldstate = state;
        delay(5);
    }
	if(oldstate == true){
		xpos = map(tp.y, TS_MINY, TS_MAXY, 0, tft.width() );
		ypos = map(tp.x, TS_MAXX, TS_MINX, 0, tft.height() );
	}
    return oldstate;
}

bool update_button(Adafruit_GFX_Button* b, bool down){
  b->press(down && b->contains(xpos, ypos));
  if (b->justReleased())
    b->drawButton(false);
  if (b->justPressed())
    b->drawButton(true);
  return down;
}

bool update_button_list(Adafruit_GFX_Button* (&pb)){
  bool down = ISPRESSED();
  for (int i = 0 ; pb[i] != NULL; i++) {
    update_button(pb[i], down);
  }
  return down;
}

void draw_button_list(Adafruit_GFX_Button* (&pb)){
  tft.fillScreen(BIANCO);
  for (int i = 0 ; pb[i] != NULL; i++) {
    pb[i]->drawButton(false);
  }
}

tenendo conto del fatto che l'interfaccia è suddivisa in 3 schermate, ogni schermata ha i suoi pulsanti, devo necessariamente aggiornare la lista dei pulsanti attivi e verificarne la pressione, oltre ovviamente a disegnarli

E questo codice si incatasta?

Ovvero non compila?

Cosa succede?

così come è ora, da errore e non compila perché in origine (ovvero quando non dava errore e compilava ma faceva comunque impazzire l'esp32) era:

bool update_button(Adafruit_GFX_Button *b, bool down)
bool update_button_list(Adafruit_GFX_Button **pb)

nella versione che ho incollato sopra non funziona e non compila perché stavo provando in ogni modo qualche alternativa

Secondo me questa:

void draw_button_list(Adafruit_GFX_Button* (&pb))

Puntatore passato come riferimento
Dovrebbe essere:

void draw_button_list(Adafruit_GFX_Button **pb)
Puntatore a puntatore, ovvero array di puntatori

esatto, è come dici, ma se la metto così, l'esp32 impazzisce, compila tutto senza errori, ma l'esp impazzisce proprio, per questo avevo modificato il puntatore, cercando di capire come "piace" all'esp32

Secondo me se impazzisce non è per una errata definizione

Dato che compila non ci sono errate definizioni, ma proprio per un valore errato o altre stranezze sostanziali

Quindi io guarderei il contenuto degli array, non la loro forma

Poi, io per primo sto imparando

Questa non esiste come sintassi. Quella giusta dovrebbe essere **
Qui il problema è che hai un array di cose. Ogni elemento di questo array è a sua volta un puntatore.
Per semplificare la sintassi prova per ora:
bool update_button_list(Adafruit_GFX_Button pb[ ] ){
e NON lavori con i puntatori ma con gli array, usando le quadre (cosa che poi già fai.

Un array, usi le quadre, ma dal C viene visto come un puntatore. Il nome stesso dell'array è un puntatore. Se lavori con le quadre è più semplice, altrimenti devi usare la sintassi puntatore,
*puntare e se hai un indice, per forza *(puntatore+i).

Un altro modo per semplificare la scrittura/lettura è usare typedef:
typedef Adafruit_GFX_Button* AGFXBpunt;
a inizio,
quindi puoi scrivere:
AGFXBpunt interfaccia0[ ] = { &btn1, &btn2, &btn3, NULL };
...
bool update_button_list(AGFXBpunt * pb){

ho provato anche così, tutto ok in compilazione ma esp32 impazzisce, questo il risultato da seriale:

PC: 0x400d4839: Adafruit_GFX::fillRoundRect(short, short, short, short, short, unsigned short) at C:\Users\HTPC\Documents\Arduino\libraries\Adafruit_GFX_Library\Adafruit_GFX.cpp line 580
EXCVADDR: 0x00004218

Decoding stack results
0x400d4839: Adafruit_GFX::fillRoundRect(short, short, short, short, short, unsigned short) at C:\Users\HTPC\Documents\Arduino\libraries\Adafruit_GFX_Library\Adafruit_GFX.cpp line 580
0x400d4da7: Adafruit_GFX_Button::drawButton(bool) at C:\Users\HTPC\Documents\Arduino\libraries\Adafruit_GFX_Library\Adafruit_GFX.cpp line 1687
0x400d1d66: update_button(Adafruit_GFX_Button*, bool) at C:\eclipse-workspace\lcd_8_bit/lcd_8_bit.ino line 1466
0x400d1d99: update_button_list(Adafruit_GFX_Button**) at C:\eclipse-workspace\lcd_8_bit/lcd_8_bit.ino line 1475
0x400d262a: GUI_SelectInterface() at C:\eclipse-workspace\lcd_8_bit/lcd_8_bit.ino line 679
0x400d354b: setup() at C:\eclipse-workspace\lcd_8_bit/lcd_8_bit.ino line 381
0x400d765a: loopTask(void*) at C:\Users\HTPC\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\cores\esp32\main.cpp line 18
0x4008616d: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

sembra quasi un problema con la funzione originale di Adafruit_GFX:

fillRoundRect

Riposta le 3 funzioni in rosso come le hai scritte ora.

scusami quali? non vedo funzioni in rosso! comunque le ho scritte come avevi suggerito, identiche, ora ho anche provato a convertire tutto da : MCUFRIEND_kbv a TFT_eSPI, per assurdo anche con questa libreria tutto viene compilato correttamente, ma l'esp32 ha lo stesso identico comportamento! premetto che lo sketch di esempio: TFT_graphicstest_one_lib, funziona correttamente

mi riferivo, ad esempio la "update_button_list" che nel tuo post #7 è in rosso
e quale suggerimento hai seguito? con il typedef o usando le quadre ?

Io la update_button_list proverei farla usando typedef e quadre:

bool update_button_list(AGFXBpunt pb[])
{ bool down = ISPRESSED();
  for (int i = 0 ; pb[i] != NULL; i++) 
  {  update_button(pb[i], down);
  }
  return down;
}

ok, le ho fatte così come mi hai suggerito ma stesso risultato, esp32 reboot loop:

bool update_button(AGFXBpunt b, bool down){
	b->press(down && b->contains(xpos, ypos));
	if (b->justReleased())
		b->drawButton(false);
	if (b->justPressed())
		b->drawButton(true);
	return down;
}

bool update_button_list(AGFXBpunt pb[]){
	bool down = Touch_getXY();
	for (int i = 0 ; pb[i] != NULL; i++) {
		update_button(pb[i], down);
	}
	return down;
}

void draw_button_list(AGFXBpunt pb[]){
	tft.fillScreen(BIANCO);
	for (int i = 0 ; pb[i] != NULL; i++) {
		pb[i]->drawButton(false);
	}
}

ora che sto provando anche con TFT_eSPI ho modificato anche le precedenti:

typedef TFT_eSPI_Button* AGFXBpunt;

AGFXBpunt		btn1, btn2, btn3, btn11, btn12, btn13, btn21, btn22, btn23;

AGFXBpunt interfaccia0[] = { &btn1, &btn2, &btn3, NULL };
AGFXBpunt interfaccia1[] = { &btn11, &btn12, &btn13, NULL };
AGFXBpunt interfaccia2[] = { &btn21, &btn22, &btn23, NULL };

Ma se dichiari le variabili btn e gli array dello stesso tipo non devi scrivere nell'array l'indirizzo...