Cerca

modulo attività

modulo tecnica

Login Form

prove per misurare la durata dell'istruzione Serial.print()

Si prova a misurare la durata di esecusine dell'istruzione e si va a vedere se c'è un a qualche regolarità che fa corrispondere la durata al numero di caratteri inviati.

L'articolo è il seguito di questa pagina.

 Nello sketch già usato si inserisce una stringa di lunghezza variabile e si aggiunge un ritardo per poter essere sicuri che un determinato impulso abbia la durata che dipende dall'istruzione che vogliamo provare e non dalle interferenze indotte dalla USART che chiede tempo per finire di stampare.

Lo sketch usato è lo stesso impiegato nella pagina di cui a questo link a cui rinvio per la descrizione.

serial Test 1

Preliminarmente viene misurata la durata del ciclo base con le righe di stampa (30) e di ritardo (34) disabilitate.

ciclo base

 

Risulta una durata del ciclo pari a12,6 * 20µs ≠ 252µs.

Come già misurato altrove la durata di esecuzione dei comandi digitaWrite() la si può ricavare dallo stesso grafico dove se ne vedono 5 che durano 1,6 * 20µs = 32µs

cioè pari a 32/5 = 6,4µs ciascuno.

 

 

Se si abilita la riga 29 e si stampa un carattere nullo ("") la durata del ciclo cresce leggermente (le due figure non hanno la stessa scala).

ciclo printNull

 

La misurazione del ciclo fornisce:

12,8*20µs = 256µs

4µs in più.

 

 

 

 

Si può controllare con una figura di dettaglio:

ciclo dett1

 

- il primo impulso è dovuto all'esecuzione delle righe 27 e 28, significa che la riga 28 è stata eseguita in 3,2*2µs = 6,4µs (come già calcolato sopra)

- l'intervallo con valore basso corrisponde all'esecuzione della riga 28 (6,4µs) seguito dall'elaborazione della riga 30 con Serial.print (""), cioè con la stampa di un carattere nullo che penso sia l'elaborazione più breve possibile

- la durata complessiva è di 5,65*2µs = 11,3µs

- dedotta la durata dell'istruzone digitalWrite() risulta che l'esecuzione dell'istruzione Serial.print() ha bisogno di almeno 11,3-6,4 = 4,9µs.

 

 

 

Ora si passa a misurazioni con stringhe di lunhezza crescente per misurare la durata di esecuzione dell'istruzione Serial.print() e vedere se c'è una qualche regolarità.

La riga 34 contiene l'istruzione delay() che viene attivata per misurare la durata del comando seriale di stampa.

Alla riga 11 si inserisce una stringa di lunghezza variabile: 5, 10, 15, 20 caratteri con tempi di ritardo, riga 12, sufficienti a contenere la trasmissione della stringa entro la durata del ciclo (quindi in assenza di pausa dovuta alla USART).

In questo modo il ritardo che si osserva dopo l'impulso generato dalle istruzioni delle righe 27 e 28 è dovuto solo all'esecuzione delle righe 28 e 30.

Si eseguono le misurazioni e si compila la seguente tabella dove viene calcolata la durata della sola istruzione Serial.print() ottenuta sottraendo la durata ddell'esecuzione dell'istruzione digitalWrite():grafSer2Tab

 

 

Il grafico che ne segue è il seguente:grafSeriale2

 

 

da cui si deduce che si tratta di una retta.

Il risultato era attendibile: più caratteri ci sono da inviare e più tempo ci vuole ed in proporzione al loro numero, a quanto pare.

 

La retta però non passa per l'origine e ce lo si poteva attendere perchè abbiamo già misurato che la durata dell'istruzione Serial.print() ha bisogno di un po' di tempo di esecuzione anche se non invia nulla: 4,9µs.

Se si fa eseguire una regressione lineare dei dati risulta la seguente tabella:

grafSer2Stat 

- la pendenza, positiva, è 8,7 µs per carattere inviato al buffer

- l'intersezione con l'asse y è 4,2µs, questa potrebbe rappresentare il ritardo minimo fisso di esecuzione del'istruzione che corrisponde solo approssimativamente a quanto misurato sopra (dato che è un valore inferiore si può pensare che l'invio di niente, cioè "", non sia proprio privo di fabbisogno di tempo). 

I valori possono essere utlizzati per stimare la durata dell'istruzione Serial.print() quando è noto il numero di caratterida inviare.

Si può prevedere che l'invio di un blocco di 40 caratteri debba durare:

t= 4,2 + 8,7*40 = 352,2µs

Si va ad eseguire la misura con l'accortezza di non fare intervenire la pausa prodotta dalla USART che aggiungerebbe un allungamento all'esecuzione dell'istruzione Serial.print() necessaria a liberare il buffer di 40 posizioni e questo lo si realizza introducendo il ritardo di almeno 1040*4 µs, poniamo 5ms.

Oppure si va a misurare la durata della prima istruzione di Serial.print() eseguita dopo un reset (come quello della foto sotto):print40c init

 

In entrambi i casi, la durata misurata è di 6,9*50µs = 345µs, valore un po' inferiore a quello calcolato ma accettabile (l'errore è inferiore al 2%).

 

Sembra plausibile pensare che il calcolo della durata sia valido anche per valori più alti ma bisogna vedere cosa accade quando la stringa eccede la dimensoine del buffer; si potrebbe calcolare che per inviare un blocco di 80 caratteri ci volgiono

con il quale vengono inviati impulsi sul pin D9 che servono a misurare la durata del comando Serial.print() della riga 30.

Si è già visto che una tringa di 40 caratteri in un unico blocco dà un risultato di durata dell'istruzione abbastanza prevedibile con l'uso dell'equazione della retta.

Se la stringa è composta da 80 caratteri il risultato atteso sembra calcolabile allo stesso modo:

t= 4,2 + 8,7*80 = 700,2µs.

La verifica viene realizzata in altra esperienza (qui).

 

note