Modificare sequenza messaggi su display

Buongiorno a tutti,
utilizzo questo sketch qui sotto per visualizzare i messaggi su 2 display led MAX7219 8x64 attaccati ad una ESP32, funziona tutto bene, ma... vorrei apportare una modifica e per questo sono qui a chiedervi aiuto. La modifica che vorrei fare è far si che la sequenza dei messaggi appaia sullo schermo in maniera non randomica, ossia che il display rispetti sempre la stessa sequenza, diciamo dal primo messaggio in alto fino all'ultimo in continuo. Ora il display legge magari tre volte lo stesso messaggio di fila, poi il primo messaggio poi il terzo, tutto a caso insomma. Ho letto diverse discussioni e provato da me a cambiare alcuni parametri ma purtroppo non ho capito come fare. (sono riuscito cmq a togliere i decimali dal prezzo, il che mi ha dato grande soddisfazione), sono assolutamente inesperto, ma questo immagino che lo avrete capito, spero che l'indentazione sia corretta.
Se qualcuno provasse ad utilizzare lo sketch a ma non funzionava bene in principio, i led non funzionavano in cascata ma ogniuno per conto suo. Poi provando e riprovando ho visto che bastava riscrivere i messaggi e uscivano perfetti sul display, strana cosa...
Grazie mille se qualcuno vorrà dare un'occhiata

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>

#include <ArduinoJson.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>

//Wifi details
char wifiSSID[] = "YOURWIFI";
char wifiPASS[] = "YOURPASS";
String on_currency = "BTCGBP";
String on_sub_currency = on_currency.substring(3);
char conversion[20];

const uint16_t WAIT_TIME = 1000;


#define HARDWARE_TYPE MD_MAX72XX::ICSTATION_HW //If your LEDs look odd try replacing ICSTATION_HW with one of these GENERIC_HW, FC16_HW, PAROLA_HW .

#define MAX_DEVICES 4
#define CLK_PIN   18
#define DATA_PIN  23
#define CS_PIN    5


MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

// Scrolling parameters
uint8_t scrollSpeed = 25;    // default frame delay value
textEffect_t scrollEffect = PA_SCROLL_LEFT;
textPosition_t scrollAlign = PA_LEFT;
uint16_t scrollPause = 2000; // in milliseconds

// Global message buffers shared by Serial and Scrolling functions
#define  BUF_SIZE  75
char curMessage[BUF_SIZE] = { "" };
char newMessage[BUF_SIZE] = { "Hello! Enter new message?" };
bool newMessageAvailable = true;


void setup(void)
{
  Serial.begin(115200);

  //connect to local wifi
  WiFi.begin(wifiSSID, wifiPASS);
  while (WiFi.status() != WL_CONNECTED) {}

  P.begin();
  P.setIntensity(0);
  P.displayText(curMessage, scrollAlign, scrollSpeed, scrollPause, scrollEffect, scrollEffect);
}
int counta = 0;
void loop(void)
{

  if (P.displayAnimate())
  { if (newMessageAvailable) {
      strcpy(curMessage, "The computer can be used as a tool to liberate and protect people, rather than to control them.");
    } P.displayReset();
  }

  if (P.displayAnimate())
  { if (newMessageAvailable) {
      on_rates();
      strcpy(curMessage, conversion);
    } P.displayReset();
  }

  if (P.displayAnimate())
  { if (newMessageAvailable) {
      strcpy(curMessage, "Bitcoin seems to be a very promising idea.");
    } P.displayReset();
  }

  if (P.displayAnimate())
  { if (newMessageAvailable) {
      strcpy(curMessage, "Easy come, easy go.");
    } P.displayReset();
  }

  if (P.displayAnimate())
  { if (newMessageAvailable) {
      strcpy(curMessage, "Since we're all rich with bitcoins ... we ought to put some of this unearned wealth to good use.");
    } P.displayReset();
  }

  if (P.displayAnimate())
  { if (newMessageAvailable) {
      strcpy(curMessage, "It is pretty strange that bitcoins will hit a dollar in the relatively near future.");
    } P.displayReset();
  }

  if (P.displayAnimate())
  { if (newMessageAvailable) {
      strcpy(curMessage, "For Bitcoin to succeed and become secure, bitcoins must become vastly more expensive.");
    } P.displayReset();
  }

}


void on_rates() {

  // Use WiFiClientSecure class to create TLS connection
  WiFiClientSecure client;

  if (!client.connect("api.opennode.co", 443)) {

    return;
  }

  String url = "/v1/rates";


  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + "api.opennode.co" + "\r\n" +
               "User-Agent: ESP32\r\n" +
               "Connection: close\r\n\r\n");

  while (client.connected()) {


    String line = client.readStringUntil('\n');
    if (line == "\r") {

      break;
    }
  }
  String line = client.readStringUntil('\n');


  const size_t capacity = 169 * JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(168) + 3800;
  DynamicJsonDocument doc(capacity);

  deserializeJson(doc, line);

  String conversionn = doc["data"][on_currency][on_currency.substring(3)];
  conversionn.toCharArray(conversion, conversionn.length());
  Serial.println(conversion);
}

Ma ti sei accorto che le variabili che usi come buffer dei messaggi le hai dimensionate a 75 (quindi massimo 74 caratteri) e tu ci copi dentro messaggi ben più lunghi, fino a ben 96 caratteri?

Inizia a dimensionare i buffer sempre almeno pari alla stringa più grande più uno, ti direi di mettere 100 in questo caso. Inoltre non essendo dei vettori ma semplici stringhe (array di char) non servono le graffe:

#define  BUF_SIZE  100
char curMessage[BUF_SIZE] = "";
char newMessage[BUF_SIZE] = "Hello! Enter new message?" };

Poi se vuoi risparmiare RAM quelle "stringone" costanti mettile in Flash usando la funzione F():

      strcpy(curMessage, F("The computer can be used as a tool to liberate and protect people, rather than to control them."));

Per finire, se hai vari messaggi da mostrare ti converrebbe creare una unica funzione che mostra i messaggi, e con una variabile indichi quale sia il messaggio da mostrare. Ma di questo ne parleremo dopo, inizia a fare le modifiche che ti ho suggerito e vedi se funziona, per le ottimizzazioni c'è tempo...

2 display led MAX7219 8x64 attaccati ad una ESP32

Poi se vuoi risparmiare RAM quelle "stringone" costanti mettile in Flash usando la funzione F()

Funziona anche con l'ESP32? Mi sembrava che la cosa funzionasse solo per gli AVR, forse sbaglio.

Ciao, Ale.

ilguargua:
Funziona anche con l'ESP32? Mi sembrava che la cosa funzionasse solo per gli AVR, forse sbaglio. ...

Dai un occhiata QUI per come è stata implementata la cosa su ESP8266 ... magari avranno fatto qualche cosa di simile su ESP32 ... bisognerebbe verificare ... ::slight_smile:

Guglielmo

... ho trovato anche QUESTA dicussione in cui si dice che:

In the ESP32, anything declared as const will end up in the rodata segment, which then will go into flash and is read directly from that. So for your example, you would declare test_array as e.g.

const uint16_t test_array[1024]={10, 9, 8, 3, 4, 5, 6, ...,};

... non so se può servire ... ::slight_smile:

Guglielmo

gpb01:
Dai un occhiata QUI per come è stata implementata la cosa su ESP8266 ... magari avranno fatto qualche cosa di simile su ESP32 ... bisognerebbe verificare ... ::slight_smile:

Guglielmo

gpb01:
... ho trovato anche QUESTA dicussione in cui si dice che:
... non so se può servire ... ::slight_smile:

Guglielmo

Grazie mille per i suggerimenti : )
Ora me li studio e faccio qualche prova
Alex

gpb01:
... non so se può servire ... ::slight_smile:

Ah ottimo, non lo sapevo neanche io, buono a sapersi (tra l'altro ha anche un senso, dovrebbe esere sempre così! :wink: ).

docdoc:
Ma ti sei accorto che le variabili che usi come buffer dei messaggi le hai dimensionate a 75 (quindi massimo 74 caratteri) e tu ci copi dentro messaggi ben più lunghi, fino a ben 96 caratteri?

Inizia a dimensionare i buffer sempre almeno pari alla stringa più grande più uno, ti direi di mettere 100 in questo caso. Inoltre non essendo dei vettori ma semplici stringhe (array di char) non servono le graffe:

#define  BUF_SIZE  100

char curMessage[BUF_SIZE] = "";
char newMessage[BUF_SIZE] = "Hello! Enter new message?" };
Poi se vuoi risparmiare RAM quelle "stringone" costanti mettile in Flash usando la funzione F():

[code]      strcpy(curMessage, F("The computer can be used as a tool to liberate and protect people, rather than to control them."));




Per finire, se hai vari messaggi da mostrare ti converrebbe creare una unica funzione che mostra i messaggi, e con una variabile indichi quale sia il messaggio da mostrare. Ma di questo ne parleremo dopo, inizia a fare le modifiche che ti ho suggerito e vedi se funziona, per le ottimizzazioni c'è tempo...

Ciao, grazie dei suggerimenti, ho fatto un po di prove...
dunque il BUF l'ho portato a 100, funziona però sempre a random.
Ho provato a mettere le stringhe in flash con la funzione F, ma mi dà errore. Cmq io l'ESP la uso solo per quello, nel senso... non ho bisogno di rispamiare memoria per altre operazioni.
Vorrei allegare l'errore, con un file txt ma qui vedo che non ho la possibilità.
Forse in breve è questo

exit status 1
cannot convert 'const __FlashStringHelper*' to 'const char*' for argument '2' to 'char* strcpy(char*, const char*)'

amc81:
exit status 1
cannot convert 'const __FlashStringHelper*' to 'const char*' for argument '2' to 'char* strcpy(char*, const char*)'

... l'errore indica ch, da qualche parte, si sta cercando di usare la classica strcpy() invece della versione _P che si deve usare quando si usa la PROGMEM ... ma non so se questa cosa esiste su ESP32 ... ::slight_smile:

I files .txt li puoi allegare ma c'è il limite, per qualsiasi file, delle dimensioni di 2MB.

Guglielmo

amc81:
dunque il BUF l'ho portato a 100, funziona però sempre a random.

Ok, per la parte "C puro" diciamo che stiamo a posto. Non ho mai usato quella libreria, quindi non so esattamente come funzioni, però non capisco bene il meccanismo che hai nella loop().

Considera che loop() viene eseguito in continuazione, quindi a meno che tu non faccia delle pause o la funzione P.displayAnimate() non mantenga il controllo per tutto il tempo della riproduzione del messaggio (come detto, non la conosco), è possibile che faccia in qualche modo "impicciare" la libreria.

Poi la variabile "curMessage" che usi come buffer non mi è chiaro come vada alla libreria, suppongo (spero) che la funzione P.displayText() usi il puntatore alla stringa, e che la P.displayReset() vada a pescare la nuova stringa.

Poi vedo che hai una variabile booleana "newMessageAvailable" che vale sempre true, quindi il codice entra in tutte le if() (le quali sono di fatto inutili, messa così), dove tra l'altro immagino che dovresti reimpostare a "false" una volta cambiato il testo. Ma probabilmente è uno sketch ancora "grezzo" e non fai questi controlli.

Insomma, non conoscendo la libreria non so dirti molto se non di verificare come gira il codice mettendo delle Serial.print(curMessage) dopo ogni "strcpy(curMessage,..." per mostrare almeno sulla seriale quello che sta facendo: se vedi le tringhe tutte di seguito, c'è qualcosa da cambiare in termini di temporizzazioni.

Se non dovesse essere questo, lascio la parola a chi magari ha usato e conosce quella libreria. :wink:

Ho provato a mettere le stringhe in flash con la funzione F, ma mi dà errore. Cmq io l'ESP la uso solo per quello, nel senso... non ho bisogno di rispamiare memoria per altre operazioni.

Si, hai ragione, scusami, colpa mia, avevo trascurato il fatto che tu non stessi su Arduino ma su una ESP32 (l'abitudine... :wink: ).
Ignora questa cosa.

Ecco l'errore è questo qua,
Scusatemi io pensavo che bastasse cambiare una stringa e tutto risolto. Mi rendo conto che è molto più difficile di come sembrava...

sono uguali per errore l'ho aggiunto 2 volte

errorearduino.txt (84 KB)

errorearduino.txt (84 KB)

docdoc:
Ok, per la parte "C puro" diciamo che stiamo a posto. Non ho mai usato quella libreria, quindi non so esattamente come funzioni, però non capisco bene il meccanismo che hai nella loop(). ...

Va bene, grazie mille del tuo aiuto, ora comunque ho un pò di materiale e messaggi su cui fare tutte le prove del caso : )
Mi metto al lavoro
Alex

>amc81: Quando si quota un post, NON è necessario riportarlo (inutilmente) tutto; bastano poche righe per far capire di cosa si parla ed a cosa ci si riferisce, inoltre, se si risponde al post immediatamente precedente, normalmente NON è necessario alcun "quote" dato che è sottinteso. :slight_smile:

Gli utenti da device "mobile" (piccoli schermi) ringrazieranno per la cortesia :wink:

Guglielmo

P.S.: Ho troncato io il "quote" del tuo post qui sopra :wink:

Ok, grazie ! :wink:

Dai un occhiata QUI per come è stata implementata la cosa su ESP8266 .

Grazie! :slight_smile:

Ciao, Ale.