Arduino Serielle Tidsforhold

Fra Holstebro HTX Wiki
Skift til: navigering, søgning

Her skriver Bent

Den serielle port har grundlæggende 2 tidsforhold man skal tage højde for.

  • Den tid det tager at sende karakterer over den serielle linje, der er bestemt fa Baud-raten, der er antallet af bit pr. sekund der sendes med. Denne Baud-rate er det der defineres når man i setup() skriver Serial.begin();
  • Den tid det tager softwaren at aflevere karakteren til sending.

For at de to ting ikke bare bliver det samme, så er der i Arduino-systemet etableret en buffer, som det er beskrevet i test af Seriel Buffer.

Målingsramme

For at kunne måle på tiderne kan vi lade softwaren selv registrere tiderne, ved at vi kan anvende micros() til at måle hvor lang tid noget kode tager.

Da micros() har en opløsning på 4μs[1] er vi nødt til at køre operationen mange gange ved hjælp af en for-løkke, der også tager tid, som det er angivet i Arduino Tidsforhold Sprogstrukturer. Der kan læses at det tager ca. 0,3μs for hver gang loopet gennemføres, når man anvender en int som tællevariabel.

Ud over dette tager det tid at kalde micros() inden måle-loopet og efter måle-loopet, det kan sammenregnes som et enkelt kald til micros(), hvilket tager 3,4μs.

Når vi skal teste det at aflevere karakterer til den serielle buffer, så er vi nødt til at forholde os til at bufferen kun kan indeholde 64 karakterer, så for at være på den sikre side, så begrænser vi os til at skrive 60 karakterer ud i alt. Herefter skal vi vente et stykke tid, så vi er sikre på at den serielle buffer er tømt. Udskrives der ca. 100 karakterer, så vil det med en Baud-rate på 115200 tage omkring 9 ms, så vi sætter et delay efter på 10 ms.

Udskrift af karakterer

Når man ønsker at skrive tekst ud, så vil det typisk være baseret på karakterer, derfor undersøges det hvor lang tid det tager at skrive karakterer ud - dette kan gøres ud fra forskellige typer af tekst.

Udskrift af en enkelt karakter som konstant char

For at teste det helt grundlæggende ved udskrift af en karakter defineret som 'X', der giver en enkelt karakter helt simpelt.

Til denne test er der konstrueret programmet Serial_Karakter1, der ligger i denne ZIP-fil.

/*
 * Test program til at teste tiden omkring det at læse karakterer ud til den serielle port
 */

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

unsigned long start, slut;
float sum = 0;
int antal = 0;
byte test = 33;

#define loops 60

void loop() {
  start = micros();
  for (int n = 0; n < loops; n++) {
    Serial.print('X');  // Det er denne programlinje der måles på
  }
  slut = micros();
  Serial.println();
  Serial.print(slut - start);  // Udskriv den aktuelle måling
  Serial.print("\t");
  antal++;
  sum += (float) (slut - start) - 3.4 - 0.3 * loops;  // Summer tiden op og træk tiden for micros fra samt tiden for de udførte for-loops
  Serial.print(antal);  // Udskriv antal målinger
  Serial.print("\t");
  Serial.println(sum / (float) antal / (float) loops);  // Udskriv den beregnede gennemsnitstid for programlinjen
  
  delay(10);
}

Dette giver følgende udskrift på Serial Monitor:

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
408	930	6.49
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
408	931	6.49
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
408	932	6.49
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
408	933	6.49
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
416	934	6.49
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
412	935	6.49
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
416	936	6.49
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
416	937	6.49
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
412	938	6.49
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
408	939	6.49
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
408	940	6.49
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
408	941	6.49
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
408	942	6.49

Det ses at det tager 6,49μs at udskrive en simpel karakter til den serielle port, så længe bufferen ikke løber fuld.

Udskrift af en enkelt karakter som variabel char

For at teste det helt grundlæggende ved udskrift af en variabel karakter defineret som 'X', der giver en enkelt karakter helt simpelt.

Til denne test er der konstrueret programmet Serial_Karakter2, der ligger i denne ZIP-fil.

Det er samme kode som den sidste, blot med en erklæring af en char variabel, der er tilskrevet et 'X';

Der er så også rettet i den linje der skriver ud i test-løkken, men ellers er det helt den samme kode.

char xx = "X";   // Karakteren der udskrives

    Serial.print(xx);  // Det er denne programlinje der måles på

Resultatet giver præcist det samme resultat som før, altså at det tager 6,49μs at udføre den linje.

Udskrift af en enkelt karakter som en del af en linje

For at teste det helt grundlæggende ved udskrift af en karakter defineret som 'X', der giver en enkelt karakter helt simpelt.

Til denne test er der konstrueret programmet Serial_Karakter3, der ligger i denne ZIP-fil.

/*
 * Test program til at teste tiden omkring det at læse karakterer ud til den serielle port
 */

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

unsigned long start, slut;
float sum = 0;
int antal = 0;

#define loops 60

void loop() {
  start = micros();
  for (int n = 0; n < loops; n++) {
    Serial.print("X");  // Det er denne programlinje der måles på
  }
  slut = micros();
  Serial.println();
  Serial.print(slut - start);  // Udskriv den aktuelle måling
  Serial.print("\t");
  antal++;
  sum += (float) (slut - start) - 3.4 - 0.3 * loops;  // Summer tiden op og træk tiden for micros fra samt tiden for de udførte for-loops
  Serial.print(antal);  // Udskriv antal målinger
  Serial.print("\t");
  Serial.println(sum / (float) antal / (float) loops);  // Udskriv den beregnede gennemsnitstid for programlinjen
  
  delay(10);
}

Dette giver følgende udskrift på Serial Monitor:

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
756	982	12.35
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
764	983	12.35
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
764	984	12.35
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
760	985	12.35
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
764	986	12.35
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
764	987	12.35
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
760	988	12.35

Det kan være lidt overraskende, men tiden bliver næsten fordoblet til 12,35μs, hvilket skyldes at karakteren lagres som en del af en konstant streng.

Udskrift af en flere karakterer som konstant streng

For at teste det helt grundlæggende ved udskrift af en streng defineret som 'X01234567Y', der giver en enkelt karakter helt simpelt.

Til denne test er der konstrueret programmet Serial_Karakter4, der ligger i denne ZIP-fil.

/*
 * Test program til at teste tiden omkring det at læse karakterer ud til den serielle port
 */

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

unsigned long start, slut;
float sum = 0;
int antal = 0;
byte test = 33;

#define loops 6

void loop() {
  start = micros();
  for (int n = 0; n < loops; n++) {
    Serial.print('X01234567Y');  // Det er denne programlinje der måles på
  }
  slut = micros();
  Serial.println();
  Serial.print(slut - start);  // Udskriv den aktuelle måling
  Serial.print("\t");
  antal++;
  sum += (float) (slut - start) - 3.4 - 0.3 * loops;  // Summer tiden op og træk tiden for micros fra samt tiden for de udførte for-loops
  Serial.print(antal);  // Udskriv antal målinger
  Serial.print("\t");
  Serial.println(sum / (float) antal / (float) (loops * 10));  // Udskriv den beregnede gennemsnitstid for programlinjen
  
  delay(10);
}

Dette giver følgende udskrift på Serial Monitor:

X01234567YX01234567YX01234567YX01234567YX01234567YX01234567Y
480	1766	7.99
X01234567YX01234567YX01234567YX01234567YX01234567YX01234567Y
480	1767	7.99
X01234567YX01234567YX01234567YX01234567YX01234567YX01234567Y
484	1768	7.99
X01234567YX01234567YX01234567YX01234567YX01234567YX01234567Y
480	1769	7.99
X01234567YX01234567YX01234567YX01234567YX01234567YX01234567Y
484	1770	7.99
X01234567YX01234567YX01234567YX01234567YX01234567YX01234567Y
480	1771	7.99
X01234567YX01234567YX01234567YX01234567YX01234567YX01234567Y
488	1772	7.99

Dette viser større effektivitet, fordi der udskrives flere karakterer fra samme streng, så tiden kommer ned på 7,99μs.

Ved at teste med en variabel defineret som:

char str [] = "X01234567Y";

Det giver det resultat at det tager fuldstændig den samme tid.

Udskrift af en flere karakterer som variabel String type

For at teste det helt grundlæggende ved udskrift af en String defineret som 'X01234567Y', der giver en streng af karakterer.

Til denne test er der konstrueret programmet Serial_Karakter5, der ligger i denne ZIP-fil.

/*
 * Test program til at teste tiden omkring det at læse karakterer ud til den serielle port
 */

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

unsigned long start, slut;
float sum = 0;
int antal = 0;
String str = "X01234567Y";

#define loops 6

void loop() {
  start = micros();
  for (int n = 0; n < loops; n++) {
    Serial.print(str);  // Det er denne programlinje der måles på
  }
  slut = micros();
  Serial.println();
  Serial.print(slut - start);  // Udskriv den aktuelle måling
  Serial.print("\t");
  antal++;
  sum += (float) (slut - start) - 3.4 - 0.3 * loops;  // Summer tiden op og træk tiden for micros fra samt tiden for de udførte for-loops
  Serial.print(antal);  // Udskriv antal målinger
  Serial.print("\t");
  Serial.println(sum / (float) antal / (float) (loops * 10));  // Udskriv den beregnede gennemsnitstid for programlinjen
  
  delay(10);
}

Dette giver følgende udskrift på Serial Monitor:

X01234567YX01234567YX01234567YX01234567YX01234567YX01234567Y
460	1024	7.61
X01234567YX01234567YX01234567YX01234567YX01234567YX01234567Y
456	1025	7.61
X01234567YX01234567YX01234567YX01234567YX01234567YX01234567Y
460	1026	7.61
X01234567YX01234567YX01234567YX01234567YX01234567YX01234567Y
460	1027	7.61
X01234567YX01234567YX01234567YX01234567YX01234567YX01234567Y
456	1028	7.61

Det viser sig altså at det er lidt hurtigere (7,61μs) når karaktererne ligger i en String.

Test af udskrift af tal

Når Arduinoen skal til at udskrive tal, så kommer der først noget formattering af tallet inden det skrives ud som karakterer. Dette tager tid, så når det drejer sig om udskrift af tal, så vil det tage længere tid.

Udskrift af byte med hhv. 1, 2 og 3 ciffre

Der laves en byte-variabel som indeholder tallet 3, der skrives ud 60 gange, så tiden kan måles.

Til denne test er der konstrueret programmet Serial_Tal1, der ligger i denne ZIP-fil.

/*
 * Test program til at teste tiden omkring det at læse tal ud til den serielle port
 */

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

unsigned long start, slut;
float sum = 0;
int antal = 0;
byte tal = 3;

#define loops 60

void loop() {
  start = micros();
  for (int n = 0; n < loops; n++) {
    Serial.print(tal);  // Det er denne programlinje der måles på
  }
  slut = micros();
  Serial.println();
  Serial.print(slut - start);  // Udskriv den aktuelle måling
  Serial.print("\t");
  antal++;
  sum += (float) (slut - start) - 3.4 - 0.3 * loops;  // Summer tiden op og træk tiden for micros fra samt tiden for de udførte for-loops
  Serial.print(antal);  // Udskriv antal målinger
  Serial.print("\t");
  Serial.println(sum / (float) antal / (float) (loops * 1));  // Udskriv den beregnede gennemsnitstid for programlinjen
  
  delay(10);
}

Dette giver følgende output, der kan ses i Serial Monitor

333333333333333333333333333333333333333333333333333333333333
3508	624	58.15
333333333333333333333333333333333333333333333333333333333333
3508	625	58.15
333333333333333333333333333333333333333333333333333333333333
3508	626	58.15
333333333333333333333333333333333333333333333333333333333333
3508	627	58.15
333333333333333333333333333333333333333333333333333333333333
3508	628	58.15

Det kan ses at det tager væsentlig længere tid, nemlig 58,15μs, altså næsten 10 gange mere end en enkelt karakter.

Retter man programmet til, så det er et 2-cifret tal der skrives ud, så får man følgende udskrift:

232323232323232323232323232323232323232323232323232323232323
3208	350	53.27
232323232323232323232323232323232323232323232323232323232323
3208	351	53.27
232323232323232323232323232323232323232323232323232323232323
3208	352	53.27
232323232323232323232323232323232323232323232323232323232323
3208	353	53.27

Det giver altså lidt bedre effektivitet pr. ciffer, hvor tiden er sænket til 53,27μs

Ved yderligere rettelse til 3 cifre får man følgende udskrift:

123123123123123123123123123123123123123123123123123123123123
3124	482	51.90
123123123123123123123123123123123123123123123123123123123123
3120	483	51.90
123123123123123123123123123123123123123123123123123123123123
3124	484	51.90
123123123123123123123123123123123123123123123123123123123123
3124	485	51.90

Igen giver det lidt bedre effektivitet pr. ciffer, hvor tiden nu er sænket til 51,90μs

Udskrift af int med 1 - 5 ciffre

Der laves en byte-variabel som indeholder tallet 5, der skrives ud 60 gange, så tiden kan måles.

Til denne test er der konstrueret programmet Serial_Tal2, der ligger i denne ZIP-fil.

/*
 * Test program til at teste tiden omkring det at læse karakterer ud til den serielle port
 */

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

unsigned long start, slut;
float sum = 0;
int antal = 0;
int tal = 5;

#define loops 60

void loop() {
  start = micros();
  for (int n = 0; n < loops; n++) {
    Serial.print(tal);  // Det er denne programlinje der måles på
  }
  slut = micros();
  Serial.println();
  Serial.print(slut - start);  // Udskriv den aktuelle måling
  Serial.print("\t");
  antal++;
  sum += (float) (slut - start) - 3.4 - 0.3 * loops;  // Summer tiden op og træk tiden for micros fra samt tiden for de udførte for-loops
  Serial.print(antal);  // Udskriv antal målinger
  Serial.print("\t");
  Serial.println(sum / (float) antal / (float) (loops * 1));  // Udskriv den beregnede gennemsnitstid for programlinjen
  
  delay(10);
}

Dette giver følgende output, der kan ses i Serial Monitor

555555555555555555555555555555555555555555555555555555555555
3508	649	58.15
555555555555555555555555555555555555555555555555555555555555
3508	650	58.15
555555555555555555555555555555555555555555555555555555555555
3508	651	58.15
555555555555555555555555555555555555555555555555555555555555
3508	652	58.15
555555555555555555555555555555555555555555555555555555555555
3508	653	58.15

Der er altså praktisk taget ingen forskel fra hvis det er en byte der skrives ud.

Tiderne pr. karakter bliver ved forskellige antal cifre i tallet:

Antal Cifre Tid pr. ciffer
1 58.15
2 53.27
3 51.96
4 51.32
5 50.78

Udskrift af long

Hvis man tester med en variabel af typen long, så viser det sig, at de giver de samme tider som ved int - det betyder altså ikke nogen forskel.

Udskrift med float

Der laves en byte-variabel som indeholder tallet 12.45, der skrives ud 12 gange, så tiden kan måles. Der måles stadig på hvor lang tid det tager for den enkelte karakter at blive skrevet ud - dette er for at kunne sammenligne direkte.

Til denne test er der konstrueret programmet Serial_Tal3, der ligger i denne ZIP-fil.

/*
 * Test program til at teste tiden omkring det at læse tal ud til den serielle port
 */

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

unsigned long start, slut;
float sum = 0;
int antal = 0;
float tal = 12.45;

#define loops 12

void loop() {
  start = micros();
  for (int n = 0; n < loops; n++) {
    Serial.print(tal);  // Det er denne programlinje der måles på
  }
  slut = micros();
  Serial.println();
  Serial.print(slut - start);  // Udskriv den aktuelle måling
  Serial.print("\t");
  antal++;
  sum += (float) (slut - start) - 3.4 - 0.3 * loops;  // Summer tiden op og træk tiden for micros fra samt tiden for de udførte for-loops
  Serial.print(antal);  // Udskriv antal målinger
  Serial.print("\t");
  Serial.println(sum / (float) antal / (float) (loops * 5));  // Udskriv den beregnede gennemsnitstid for programlinjen
  
  delay(10);
}

}

Dette giver følgende output, der kan ses i Serial Monitor

12.4512.4512.4512.4512.4512.4512.4512.4512.4512.4512.4512.45
4868	592	81.20
12.4512.4512.4512.4512.4512.4512.4512.4512.4512.4512.4512.45
4884	593	81.20
12.4512.4512.4512.4512.4512.4512.4512.4512.4512.4512.4512.45
4872	594	81.20
12.4512.4512.4512.4512.4512.4512.4512.4512.4512.4512.4512.45
4884	595	81.20
12.4512.4512.4512.4512.4512.4512.4512.4512.4512.4512.4512.45
4876	596	81.20

Der ses her at typen float er mere besværlig at arbejde med, den tager længere tid 81,20μs pr. karakter om at blive skrevet ud.

Test af tidsforhold med fyldt buffer

Det vil ikke give så meget mening at teste tiderne mens man fylder bufferen og så efter bufferen er fyldt i samme test. Derfor er denne test lavet, så den tester afviklingen når bufferen er fyldt op.

Hele indstillingen af Baud-rate (bit pr. sekund) sker i programlinjen Serial.begin(9600); hvor netop de 9600 er Baud-raten. Selve indstillingen sker i nogle registre nede i processoren [2], hvor der asynkrone serielle port er gennemgået i afsnit 19 s. 176ff.

Den forventede tid for en karakter er (1+8+1)/Baud-rate - grunden til 1+8+1 er at der sendes 8 databit, men for at framingen skal være rigtig, så sendes der 1 start-bit før byten og en stop-bit efter byten, så der i alt sendes 10 bit.

Årsagen til at det er denne tid der skal regnes med er, at når bufferen er fyldt op, så er det kommunikationstiden der skal gå før den næste karakter kan sendes den næste karakter, altså vil afviklingen være afhængig af Baud-raten.

Koden der testes med gør det at for hver test, så sikres det at bufferen er fyldt op, ved at der skrives 100 karakterer ud, og for strukturens skyld udskrives Start test.

Herefter udskrives 100 karakterer hvor der måles hvor lang tid det tager, og til sidst skrives resultatet ud.

Dette er realiseret i følgende kode i programmet Serial_Baud, der ligger i denne ZIP-fil:

/*
 * Test program til at teste tiden omkring den serielle kommunikation
 */

void setup() {
  Serial.begin(9600);
}

unsigned long start, slut;
float sum = 0;
int antal = 0;

#define loops 100

void loop() {
  for (int n = 0; n < 100; n++) {
    Serial.print("X");  // Her fyldes bufferen op
  }
  Serial.println();
  Serial.println("Start test");
  start = micros();
  for (int n = 0; n < loops; n++) {
    Serial.print('X');  // Det er denne programlinje der måles på
  }
  slut = micros();
  Serial.println();
  Serial.print(slut - start);  // Udskriv den aktuelle måling
  Serial.print("\t");
  antal++;
  sum += (float) (slut - start) - 3.4;  // Summer tiden op og træk tiden for micros fra
  Serial.print(antal);  // Udskriv antal målinger
  Serial.print("\t");
  Serial.println(sum / (float) antal / (float) (loops));  // Udskriv den beregnede gennemsnitstid for programlinjen
  
  delay(10);
}

En test med 9600 Baud giver følgende resultat:

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Start test
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
103996	41	1039.93
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Start test
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
103996	42	1039.93
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Start test
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
103996	43	1039.93

Den forventede tid er 10/9600 = 1041.66μs, så den målte tid er lidt under, hvilket kan stamme fra den fejl på 0,2% der er angivet i databladet[2] Tabel 19-12 side 203.

Der måles med forskellig Baud-rate, for at se hvor godt den opfylder kommunikationshastigheden:

Baud-rate Forventet tid Målt tid Afvigelse Afvigelse i % Afvigelse fra databladet
300 33333,33 33329,36 -3,36 -0,01% ikke angivet
2400 4166,66 4164,95 -1,71 -0,04% 0,0%
9600 1041,66 1039,93 -1,73 -0,17% 0,2%
115200 86,81 84,95 -1,86 -2,14% 2,1%
250000 40,00 39,95 -0,05 -0,13% 0,0%
1000000 10,00 10,00 0,00 0,0% 0,0%
2000000 5,00 5,47 0,47 9,4% 0,0%

Som det kan ses i tabellen herover, så passer de fleste af afvigelserne ganske pænt, bortset fra fortegnet, hvilket kan skyldes at man regne afvigelsen til den anden side. Det kan ses på den højeste Baud-rates, at afvigelsen bliver større ved 2000000 Baud. Det skyldes at processoren ikke kan fylde så meget i bufferen at den er løbet fuld, så resultatet siger bare at koden kan ikke følge med til at fylde i så hurtigt som der kan kommunikeres.

Forhold omkring afvigelser i Baudrate

Hvis man overvejer hvordan en karakter modtages, så skal alle 10 bit ramme rigtigt, altså må det sidste bit ikke skride mere end ½ bit til hver side, altså må den reelle Baud-rate ikke afvige mere end 5%, hvis det skal kunne lade sig gøre at modtage korrekt.

Hvis man kigger i databladet [2] side 193, så er der to angivelser for variationer i tabel 19-2 og 19-3. Forskellen på tabellerne er hvordan Baud-raten dannes internt i processoren, hvor det bedste gæt er at man kan gå ud fra tabel 19-2 til langt de fleste Baud-rates, på nær 2000000 Baud, hvis man ser i tabel 19-12, at denne Baud-rate ikke kan realiseres med opsætningen i tabel 19-2. I tabel 19-2 kan man aflæse at man kan gå ud til ±4,5%, men at det anbefales at man holder sig inden for ±2,0%. Forholder man det til målingerne, så ses det at alle Baud-rates overholder dette, lige på nær ved 2000000, men her er det kodens afviklingstid der får indflydelse på målingen, ikke den aktuelle variation.

Det ses altså at afvigelserne i målingerne holder sig fint inden for de kriterier der er givet for den serielle port.

Referencer

  1. Arduino reference om micros()
  2. 2,0 2,1 2,2 Datablad for den processor Atmega328P som sidder i en Arduino UNO