Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the google-analytics-for-wordpress domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home3/smania73/public_html/mcmajanwpr/wp-includes/functions.php on line 6121
Arduino UNO R4: problemi con la SoftwareSerial? | McMajan
Ago 182024
 

Oggi vi illustro un problema che mi ha fatto perdere tre giorni e che a quanto pare non è descritto nella documentazione di Arduino. L’arduino UNO R4 ha fra le caratteristiche che lo contraddistinguono, la presenza di una matrice led 12×8 che permette di fare piccole animazioni, scrivere informazioni in forma testuale / grafica, etc. Stavo completando un progetto che ho descritto diverse volte nel mio canale youtube, quando mi sono scontrato con un problema enorme. Il progetto prevedeva di collegare l’Arduino tramite due UART  a due  convertitori TTL / RS232 autocostruiti che a loro volta si collegano a due inverter fotovoltaici. Poi volevo sfruttare la ledmatrix per mostrare delle barre che indicano il consumo istantaneo di entrambi gli inverter. 

Purtroppo l’UNO R4 ha una sola UART libera, ne avrebbe una seconda ma è collegata all’ESP32 con cui comunica per dare connettività wifi. Perciò risulta d’obbligo utilizzare la SoftwareSerial per creare una porta software. Certo, non è la stessa cosa che una porta hardware, ma andrà più che bene, anche perchè i miei inverter comunicano a velocità molto bassa, per la precisione 2400 baud. Uno dei limiti è che si può usare qualunque pin per trasmettere e quindi per emulare il pin TX, ma solo alcuni possono ricevere e quindi essere usati come pin RX, ossia D0, D1, D2, D3, D8, D14, D15, A1, A2, A3, A4, A5. Ovviamente ha poco senso usare i pin D0 e D1 perchè sono i medesimi della porta hardware. 

#include <SoftwareSerial.h>
SoftwareSerial Inverter2_UART(2, 3); // RX=2 TX=3
setup()
{
    matrix.begin();  
    matrix.loadFrame(danger);
    Console_UART.begin(9600);
    while (!Console_UART);
    delay(500);
    Console_UART.println(“Seriale OK”);
    Inverter_UART.begin(2400); // L’inverter comunica a 2400 baud
    unsignedint code=Inverter2_UART.begin(2400);
    Console_UART.println(“codice errore ss: “);
    Console_UART.println(code);
Qui sopra vediamo una delle tante versioni della parte di inizializzazione delle porte seriali. Tutto semplice no? Certo, peccato che Arduino trasmetteva correttamente, l’inverter riceveva la richiesta, rispondeva ma poi Arduino non vedeva in nessun modo questa risposta. Eppure i segnali arrivavano, li ho visti con l’oscilloscopio, ma nulla, Arduino non li leggeva. Ho testato tutti i pin, ho cercato di capire se ci potesse essere un errore nella nomenclatura dei pin, ho fatto tantissime prove. Tre giorni di lavoro, alla fine mi sono detto: vabbè, è chiaramente un problema di gestione dei timers della SoftwareSerial, vediamo come e scritta e se riusciamo a modificarla. E nell’istruzione begin mi trovo un commento che recita: // NOTE: The IO port must be opened before calling any R_IOPORT_xxx functions A quel punto si illumina la classica lampadina e mi dico: “Ho capito, la SoftwareSerial deve essere la prima ad inizializzare i timers altrimenti non funzionerà”. Cos’altro potrebbe utilizzare i timers? Ma la LedMatrix ovvio !!!! E guarda caso nel codice avevo inizializzato prima la ledmatrix e dopo la softwareserial. Morale della favola è sufficiente modificare l’ordine di inizializzazione in questo modo: 
#include <SoftwareSerial.h>
SoftwareSerial Inverter2_UART(2, 3); // RX=2 TX=3
setup()
{
    Console_UART.begin(9600);
    while (!Console_UART);
    delay(500);
    Console_UART.println(“Seriale OK”);
    Inverter_UART.begin(2400); // L’inverter comunica a 2400 baud
    unsignedint code=Inverter2_UART.begin(2400);
    Console_UART.println(“codice errore ss: “);
    Console_UART.println(code);
    matrix.begin();  
    matrix.loadFrame(danger);
Alla fine è una cosa semplicissima, ma non è riportata nella documentazione di Arduino e se non lo sai ci puoi perdere le giornate. Se anche tu hai lo stesso problema controlla di aver inizializzato la SoftwareSerial prima di ogni altra risorsa. 
Spero che questo articolo ti sia stato d’aiuto. 

Notice: ob_end_flush(): Failed to send buffer of zlib output compression (0) in /home3/smania73/public_html/mcmajanwpr/wp-includes/functions.php on line 5471