Come funziona il timestamp del Serial monitor? (strano comportamento)

Non mi sarei mai sognato di fare un una domanda così banale fino a che non ho notato questo strano comportamento:

Creando una funzione che stampasse al serial monitor ogni 10 ms una stringa (tramite millis) mi sono accorto che qualcosa non torna.

Posto il mio codice:

const unsigned int interval = 10;
unsigned long previousMillis; 
void setup() {
  Serial.begin(250000);
}

void loop() {
  if (millis() -  previousMillis > interval ){
    previousMillis = millis();
    Serial.println("hello: ");            
  }
}

Poi nel serial monitor decido di attivare il "visualizza orario" o "timestamp" e mi ritrovo con una roba del genere:

06:27:29.673 -> hello:
06:27:29.673 -> hello:
06:27:29.673 -> hello:
06:27:29.707 -> hello:
06:27:29.707 -> hello:
06:27:29.707 -> hello:
06:27:29.740 -> hello:
06:27:29.740 -> hello:
06:27:29.740 -> hello:
06:27:29.775 -> hello:
06:27:29.775 -> hello:
06:27:29.775 -> hello:

Perchè mi trovo 3 o 4 righe identiche? quando invece in teoria dovrebbe stampare una volta iogni 10 ms?
Ho provato con intervalli maggiori di 20 ms e tutto va bene. Invece più scendo sotto i 10 ms e più righe identiche mi ritrovo. Per 1 ms vedo circa 20 rughe uguali prima che il timestamp cambi.

Dov'è l'inghippo? colpa del serial monitor che non aggiorna abbastanza velocemente l'orario o c'è qualcosa con l'Arduino (Mega2560 in questo caso)?

Sicuramente è un problema legato alle latenze della trasmission seriale, non so se è più legato al serial monitor o alla trasmission in se. Puoi provar con altri programmi per leggere dalla seriale(CoolTerm o simili) e vedere se cambia qualcosa

Io credo che il serial monitor legga il suo buffer ogni circa 35 ms, per cui se lui scrive una volta ogni 10 ms ecco che ne vede 3 o 4 per volta.

Ma in fin dei conti: chettefrega? :wink:

Diciamo che devo essere sicuro che scriva in seriale ogni 10 ms e non 3 righe alla volta...
Comunque, dove hai trovato questa info della lettura della seriale ogni 35 millisecondi?

Da nessuna parte, do’ per scontato che Arduino mandi le stringhe con l’intervallo specificato di 10ms perché è così che l’hai programmato, e dato che il monitor seriale di Arduino non acquisisce sicuramente tutti i singoli byte ricevuti (dovrebbe avere un interrupt legato alla ricezione di ogni singolo byte) avrà certamente un suo timer per la verifica della presenza di caratteri nel suo buffer, scaricandolo integralmente. Almeno così in genere si fanno i programmi che devono interfacciarsi con la seriale e non hanno tempistiche critiche.
E stando ai dati che hai postato, credo che l’intervallo sia proprio circa 30-35ms che mi sembra un intervallo più che accettabile per qualsiasi scopo di debug, d’altronde è chiaro che il semplice monitor seriale dell’IDE non sia un task “time critical”…

Per cui ripeto, o ignori questa cosa, oppure se hai reale necessità di verificare al millisecondo, allora o usi un altro programma di terminale che abbia una gestione ad interrupt della seriale e visualizzazione del timestamp, oppure ti scrivi un tuo programma apposito che legge i singoli caratteri in quel modo e ad ogni riga ricevuta mostra timestamp al millisecondo ed i caratteri ricevuti.