Přesnost časování pomocí Arduina

Wiring, C++, C, Java, ...
Pravidla fóra
Toto subfórum slouží k řešení obecných otázek kolem programování (konstrukce, knihovny, alokace paměti, ...)
Odpovědět
petan
Příspěvky: 358
Registrován: 23 črc 2017, 10:19
Reputation: 0
Kontaktovat uživatele:

Přesnost časování pomocí Arduina

Příspěvek od petan » 05 bře 2018, 09:17

Jen ze zajímavostí jsem měřil přesnost časování Arduina. Je jasné, že pro získání přesného času je nutné použít RTC modul, ale jak to ve skutečnosti funguje s příkazem delay(), nebo s časováním pomocí millis()? Měření jsem prováděl přibližně, jako referenci jsem bral normální počítač.

Článek si můžete prohlédnout na mém webu, konkrétně zde: https://www.mylms.cz/text-presnost-caso ... i-arduina/

Obrázek

Obrázek

AstroMiK
Příspěvky: 593
Registrován: 08 pro 2017, 19:05
Reputation: 0

Re: Přesnost časování pomocí Arduina

Příspěvek od AstroMiK » 07 bře 2018, 18:06

Můj příspěvek k měření přesnosti časování Arduina.

Pro testy jsem použil čínský klon Arduina Nano s nějakým NONAME rezonátorem.
Fotka: http://www.astromik.org/forum/nano-rezonator.jpg

Vycházím z toho, že procesor očekává jako zdroj základního kmitočtu 16MHz krystal.
Od této frekvence se pak odvíjí veškeré časování.

Když samotný krystal kmitá rychleji (vyšší frekvencí), procesor nemá žádnou možnost zjistit, že frekvence neodpovídá 16MHz, a proto jsou všechny funkce millis() i delay() zrychlené (trvají kratší dobu, než by měly).

Při mojí metodě zkoumání přesnosti časování jsem tedy zkusil přesně změřit kmitočet, na kterém 16MHz krystal opravdu kmitá.

Protože není možné měřit krystal přímo (jakékoliv kapacitní zatížení krystalu hýbe výrazně s frekvencí), napsal jsem program, který tuto základní frekvenci vydělí přesně 256 a pošle ji na samostatný pin (D3)
Je to v podstatě jen klasické nastavení PWM signálu pomocí registrů v ATmega328.

Kód: Vybrat vše

void setup(void)
  {
    pinMode(3,OUTPUT);                // pin D3 na vystup
    TCCR2A = 0b00100011;              // nastaveni PWM: "Clear OC0B on Compare Match" a zaroven "Fast PWM"
    TCCR2B = 0b00000001;              // prescaler = 1x   (frekvence = 16000000/256 = 62.5kHz)
    OCR2B = 127;                      // 50% strida na pinu D3
  }
  
void loop(void)
  {
  }

Ideálně bych tedy na pinu D3 očekával frekvenci 16000000 / 256 = 62500 Hz
(číslo 256 je rozlišení PWM střídy)

Frekvenci jsem pak měřil metodou porovnávání dvou frekvencí na osciloskopu (Lissajousovy obrazce).
Teorie například tady: http://vyuka.hradebni.cz/mod/resource/v ... ue&id=9712

Jeden kanál osciloskopu byl zapojen na pin D3 v Arduinu, a druhý byl připojený k velmi přesnému nastavitelnému generátoru.

Nastavováním frekvence generátoru byl hledán stav, kdy se obrazec ustálí.
Čím je rozdíl frekvencí vyšší, tím rychleji se obrazec na osciloskopu pohybuje.

Na přiloženém videu je vidět, že frekvence na pinu D3 je 62536 Hz.
Video: https://youtu.be/CbTdadjba6Y

Když se tato frekvence vynásobí 256, je výsledkem skutečná frekvence krystalu.

62536 * 256 = 16009216 Hz

Rozdíl mezi ideální a skutečnou frekvencí krystalu je tedy "plus" 9216 Hz.

Převedeno na procenta je to odchylka ( 9216 / 16000000 ) * 100 = + 0.0576 %


Pokud by tato chyba byla konstantní (ve skutečnosti je závislá i na teplotě), projevila by se v časovači chybou 1s asi za 29 minut.

Výpočet:
1 / 0.000576 = 1736s = 29 minut

Uživatelský avatar
gilhad
Příspěvky: 788
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Přesnost časování pomocí Arduina

Příspěvek od gilhad » 08 bře 2018, 13:56

petan píše:
05 bře 2018, 09:17
Jen ze zajímavostí jsem měřil přesnost časování Arduina. Je jasné, že pro získání přesného času je nutné použít RTC modul, ale jak to ve skutečnosti funguje s příkazem delay(), nebo s časováním pomocí millis()? Měření jsem prováděl přibližně, jako referenci jsem bral normální počítač.

Článek si můžete prohlédnout na mém webu, konkrétně zde: https://www.mylms.cz/text-presnost-caso ... i-arduina/
Jak sam pises, problem je v tom, ze krome delay(1000) ten program taky neco dela a cim vic toho dela, tim vic se ti rozchazi ten cas.

Ve skutecnosti potrebujes uplne jiny pristup, kdy sse podivas, kolik je prave ted a kolik bude za 1 sekundu (nebo jak dlouho chces cekat, pak provedes veskerou cinnost, co potrebujes (ty vypisy a tak) a pak uz jen cekas zbytek te doby.

https://www.baldengineer.com/arduino-ho ... illis.html
https://www.baldengineer.com/millis-tutorial.html

Pokud to chces jeste pravidelneji, tak misto

Kód: Vybrat vše

 previousMillis = currentMillis;
(ktere zaruci stejnou dobu mezi udalostmi) zvetsis previousMillis o pozadovanou hodnotu, takze i kdyz ti nekde (treba mezi navratem z loop a novym skokem do nej) nejaka milisekunda utece, tak o to zkratis nasledujici cyklus a zase se dostanes do tempa (cili doba mezi udalostmi se muze drobne lisit (zvlast kdyz se nektara pretahne prez limit), ale udalosti se budou snazit dostat na nasobky toho rozdilu od zacatku, i kdyby mely nektere z nich trvat lehce jinou dobu. (cili misto aby tihly k danemu intervalu mezi sebou (a nastavaly se stejnym odstupem - dobre pro prubezne casovani), tak tihnou k danemu nasobku intervalu od zacatku programu (a nastavaji v danou dobu -
vhodne pro absolutni casovani a treba nastenne hodiny)

petan
Příspěvky: 358
Registrován: 23 črc 2017, 10:19
Reputation: 0
Kontaktovat uživatele:

Re: Přesnost časování pomocí Arduina

Příspěvek od petan » 09 bře 2018, 09:00

No, výzkum jsem na to nedělal, ale myslím, že se program bude chovat úplně stejně.
Když si do proměnné uložím čas posledního provedení a pak porovnávám s časem + posune, tak je to podobné jako když si uložím dobu příštího provedení a porovnávám s aktuálním časem.
Rozdíl by mohl být jenom při porovnání aktuálního času s proměnou, do které se přičítá konstanta. A porovnání aktuálního času a již předpřipravené proměnné.

Podobně to jde vidět u mě v programu na grafu. Přesně to koresponduje s tím, co napsal AtroMiK. Krystal má o něco větší frekvenci, takže se Arduino předbíhá. Záleží samozřejmě na stavbě programu (každý příkaz jinak dlouho trvá, lze použít jiný přístup ke kódu, ...)

Obrázek

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 17 hostů