Chi ha lavorato con Arduino UNO R3, Arduino MEGA, Arduino Leonardo, ecc. (tutte le classiche AVR) ber ricorda che la seriale, per ottimizzare i tempi era gestita ad interrupt così da NON bloccare il programma, ad esempio durante una tramissione di parecchi caratteri magari con un baud rate basso.
Per le prove che seguono, dato il il blocco di caratteri trasmessi è, volutamente, grande (180 caratteri) e che di base, il buffer di trasmissione per la seriale, sulle MCU classiche AVR è impostato al massimo a 64, occorre temporaneamente modificare UNA riga nel "core AVR" per rendere equiparabile il test che poi seguirà con Arduino UNO R4.
Quindi, trovato il core della scheda (io ho usato una Leonardo per avere sia la seriale USB nativa che la seconda seriale UART sui pin 0 e 1, come si ha su Arduino UNO R4 MINIMA) occore modificare UNA riga nel file "HardwareSerial.h", riga 53 (non ho fatto prove con MCU che hanno meno di 1024 bytes di SRAM) in modo che si abbia:
#define SERIAL_TX_BUFFER_SIZE 256
che è sufficiente per la nostra prova con 180 caratteri.
Dopo le prove su AVR, salvo non vi serva veramente così grande, consiglio di riportare il valore a quello originale, ovvero 64 per non sprecare preziosa memoria.
Passiamo al semplice programma di test che utilizzeremo sia per la Leonardo che per la R4 MINIMA (ed una prova anche sulla WiFi) ...
void setup() {
char msg[] = "The quick brown fox jump over the lazy dogs\r\n"
"The quick brown fox jump over the lazy dogs\r\n"
"The quick brown fox jump over the lazy dogs\r\n"
"The quick brown fox jump over the lazy dogs\r\n";
unsigned long t_start, t_start_1, t_start_g;
unsigned long t_end, t_end_1, t_end_g;
//
delay ( 500 );
pinMode ( LED_BUILTIN, OUTPUT );
//
Serial.begin ( 4800 );
while ( !Serial ) delay ( 50 );
Serial1.begin ( 4800 );
//
t_start_1 = micros();
t_start_g = t_start_1;
Serial1.println ( msg );
t_end_1 = micros();
t_start = micros();
Serial.println ( msg );
t_end = micros();
t_end_g = t_end;
//
Serial.print ( "Number of printed chars: " );
Serial.println ( strlen ( msg ) );
Serial.print ( "Time to print to Serial microseconds: " );
Serial.println ( t_end - t_start );
Serial.print ( "Time to print to Serial1 microseconds: " );
Serial.println ( t_end_1 - t_start_1 );
Serial.print ( "Time to print total microseconds: " );
Serial.println ( t_end_g - t_start_g );
//
Serial.println ();
}
void loop() {
static byte ledStatus = LOW;
//
delay ( 750 );
ledStatus = ~ledStatus;
digitalWrite ( LED_BUILTIN, ledStatus );
}
Programmino molto semplice che crea una stringa classica del C di 180 caratteri e la invia in trasmissione sia su Serial1 che su Serial, misurando i microsecondi che passano prima che il controllo torni all'applicazione dopo aver chiamato la Serial.println().
Ho scelto di lavorare a 4800 bps proprio per evidenziare bene il problema ...
Guglielmo