Memoria dinamica Arduino con Nextion

Buongiorno a tutti sto riscontrando un problema con un consumo eccessivo di memoria dinamica da parte dei tasti del Nextion circa il 40%. Uso un Arduino mega e un Nextion nx8048t070_011

Richiamo i tasti nel seguente modo:

NexButton b003 = NexButton(0, 3, "b003");

NexTouch *nex_listen_list[] = {
  &b003, 
  NULL
};

void b003PopCallback(void *ptr) {
//comando
}

void setup() {

nexInit();

b003.attachPop(b003PopCallback);
}

Qualcuno ha trovato un modo per risparmiare memoria dinamica quando si usano tanti bottoni?

Immagino tu stia usando la libreria ITEAD?

Non mi è mai piaciuta granché perché essenzialmente l'onere della comunicazione è tutto a carico della MCU che "interroga" il display di volta in volta, quando quest'ultimo da parte sua ha tutte le risorse per fare il grosso del lavoro.

Sarà perché sono abituato ad HMI di tipo industriale, ma di solito uso l'approccio inverso: quando l'utente esegue qualche azione sul display invio un comando alla MCU che "reagisce di conseguenza".
L'unica cosa che il microcontrollore deve fare a questo punto è fare il parsing dei comandi che arrivano sulla seriale (e solo se e quando ci sono). Per questione di compatibilità con altri miei progetti, io formatto i messaggi sempre nel formato JSON, ma ovviamente ognuno può usare il protocollo che preferisce.

Se invece devo aggiornare qualche proprietà del display (testi, background etc etc), prendendo spunto dall'ottima libreria de @ilguargua, mi sono fatto una piccola classe con soltanto i metodi che mi sono realmente necessari (ed il parser JSON come dicevo più su) riducendo al minimo la quantità di risorse impegnate.

#include "Arduino.h"
#include <ArduinoJson.h>

#ifndef NEXTION_HMI
#define NEXTION_HMI

#define NXT_BUF_SIZE              256
#define NXT_MSG_END               0xFF,0xFF,0xFF


class NextionHMI {
    public:

        // Default constructor
        NextionHMI(HardwareSerial* serial) {
            hmiSerial = serial;
        };

        char sendBuf[NXT_BUF_SIZE];

        StaticJsonDocument<NXT_BUF_SIZE*2> doc;

        int available() {
            return hmiSerial->available();
        }

        uint8_t setButtonClick(const char* field){
            snprintf( sendBuf, NXT_BUF_SIZE, "click %s,1%c%c%c", field, NXT_MSG_END);
            return hmiSerial->print(sendBuf);
        }

        uint8_t setNumeric(const char* field,long value){
            snprintf( sendBuf, NXT_BUF_SIZE, "%s.val=%ld%c%c%c", field, value, NXT_MSG_END);
            return hmiSerial->print(sendBuf);
        }

        uint8_t setValue(const char* field,long value){
            snprintf( sendBuf, NXT_BUF_SIZE, "%s.val=%ld%c%c%c", field, value, NXT_MSG_END);
            return hmiSerial->print(sendBuf);
        }

        uint8_t setString(const char* field, const char* value){
            snprintf( sendBuf, NXT_BUF_SIZE, "%s.txt=\"%s\"%c%c%c", field, value, NXT_MSG_END);
            return  hmiSerial->print(sendBuf);
        }


        uint8_t setString(const char* field, const String & value){
            return  setString(field, value.c_str());
        }

        uint8_t appendString(const char* field, const char* value){
            snprintf( sendBuf, NXT_BUF_SIZE, "%s.txt+=\"%s\\r\"%c%c%c", field, value, NXT_MSG_END);
            return  hmiSerial->print(sendBuf);
        }

        uint8_t setFloat(const char* field, float value, uint8_t intSize = 0, uint8_t frctSize = 0){
            long valLong = value * (frctSize *10.0F);
            snprintf( sendBuf, NXT_BUF_SIZE, "%s.val=%ld%c%c%c", field, valLong, NXT_MSG_END);
            return  hmiSerial->print(sendBuf);
        }

        uint8_t setButtonPushed(const char* field){
            snprintf( sendBuf, NXT_BUF_SIZE, "click %s,1%c%c%c", field, NXT_MSG_END);
            return  hmiSerial->print(sendBuf);
        }

        uint8_t setButtonReleased(const char* field){
            snprintf( sendBuf, NXT_BUF_SIZE, "click %s,0%c%c%c", field, NXT_MSG_END);
            return  hmiSerial->print(sendBuf);
        }

        uint8_t setProperty(const char* prop, const char* value){
            snprintf(sendBuf, NXT_BUF_SIZE, "%s=%s%c%c%c", prop, value, NXT_MSG_END);
            return  hmiSerial->print(sendBuf);
        }

        uint8_t setProperty(const char* prop, long value){
            snprintf(sendBuf, NXT_BUF_SIZE, "%s=%ld%c%c%c", prop, value, NXT_MSG_END);
            return  hmiSerial->print(sendBuf);
        }

        uint8_t setVariable(const char* var, long value){
            snprintf(sendBuf, NXT_BUF_SIZE, "%s=%ld%c%c%c", var, value, NXT_MSG_END);
            return  hmiSerial->print(sendBuf);
        }

        uint8_t addWavePoint(uint8_t waveId,uint8_t ch, uint8_t value){
            snprintf(sendBuf, NXT_BUF_SIZE, "add %u,%u,%u%c%c%c", waveId, ch, value, NXT_MSG_END);
            return  hmiSerial->print(sendBuf);
        }

        bool readSerialHMI( const char* filter ) {
            // Alreay in the buffer?
            if (doc.containsKey(filter))
                return true;

            String rxBuffer;
            if (hmiSerial->available()) {
                rxBuffer = hmiSerial->readStringUntil('\n');
                DeserializationError error = deserializeJson(doc, rxBuffer);
                if (error) {
                    //Serial.print(F("deserializeJson() failed: "));
                    //Serial.println(error.c_str());
                    // Flush Serial input buffer
                    while (hmiSerial->available())  hmiSerial->read();
                }

            }
            return doc.containsKey(filter);
        }

        // Empty RX buffer after message parsed
        void clearBuffer() {
            doc.clear();
        }

    private:
        HardwareSerial* hmiSerial;
};


#endif

Grazie per la soluzione, vorrei tanto non dover modificare l'intero codice.

Se vuoi mantenere l'uso di quella libreria, non vedo altre soluzioni che snellire altrove.

Se ad esempio usi molte "string literal", fai già uso della macro F() per risparmiare un po' di SRAM?

si purtroppo ho già ridotto tutto all'osso, sai se esiste un modo per modificare l'id e la pagina dentro il loop? oppure se posso dare lo stesso indirizzo al un tasto e modificarle il funzionamento nelle diverse pagine?

NexButton b0 = NexButton(0, 1, "b0");

No purtroppo come ti dicevo non conosco quella libreria.