Met Serial.Write ()
in een tijdgevoelige applicatie. Ik realiseer me dat het aantal tekens dat werd geschreven niet alleen een impact had op de tijd die werd besteed aan het schrijven in de buffer, maar zelfs een grotere impact had dan verwacht.
Bekijk de volgende schets, die de tijd meet die het kost om NB_CHARS-tekens te schrijven met Serial.Write ()
. Ik heb 1000 keer gesampled om een betrouwbaardere meting te krijgen.
#define NB_CHARS 100void setup () {Serial.begin (115200); uint8_t tekens [NB_CHARS]; voor (int i = 0; i<NB_CHARS; i ++) {chars [i] = 66; } unsigned lange time1, time2; unsigned long totalTime = 0; vertraging (100); voor (int i = 0; i<1000; i ++) {time1 = micros (); Serial.write (tekens, NB_CHARS); time2 = micros (); totalTime + = time2 - time1; vertraging (10); Serial.println (""); vertraging (10); } float meanTime = (float) totalTime / 1000.0f; Serial.print ("meanTime ="); Serial.println (meanTime);} void loop () {}
Hier zijn enkele resultaten voor verschillende NB_CHARS-waarden:
NB_CHARS: Tijd (microseconden) 1: 122: 183: 24 [...] 99: 2912100: 2997101: 3082 [...] 199: 11412200: 11497201: 11582
Het lijkt erop dat in eerste instantie elke nieuwe karakter voegt ongeveer 6 microseconden vertraging toe, maar daarna wordt het 85 microseconden. Ik heb alle waarden van 1 tot 100 getest om te zien waar het verandert en het lijkt direct na 70 te zijn:
Het lijkt raar om me.
Een snelle Google-zoekopdracht brengt me bij deze post uit 2013 van Tom Carpenter. Ik weet niet zeker hoe waar dit is of dat het nog steeds relevant is.
Een deel van het probleem is dat de Hardware Serial-bibliotheek zo ongelooflijk inefficiënt is (ik denk niet dat ze het hadden kunnen maken minder efficiënt als ze het probeerden!). Nadat elke byte is verzonden, wordt er een interrupt aangeroepen die een leven lang de volgende byte in de buffer laadt om te verzenden. De schrijffunctie verspilt ook veel tijd aan het doen berekeningen over waar een teken in een ringbuffer moet worden geplaatst.
[... ]
Waarom is er zo'n "lange" vertraging voor elk teken en is is er een manier om het sneller te maken?
Wat gebeurt er na 70 tekens dat het nog verder vertraagt?