Zápisník experimentátora
Hierarchy: Časovač (timer)
Ak potrebujete v pravidelných intervaloch vykonávať v Arduine nejakú činnosť, nevyhnete sa použitiu timera. Interne je to v mikrokontroléri zariadené tak, že nastavíte hodnoty v pár registroch a časovač sa spustí. Vyžaduje si to ale rátanie presných čísiel, ktoré sú závislé od frekvencie. Dá sa to ale aj inak. Pomocou jednoduchej knižnice, ktorá výpočet a nastavenie registrov urobí za vás.
V novších verziách IDE si knižnicu nainštalujete pohodlne cez Library Manager. V staršej verzii je nutné ísť na stránku a stiahnuť si knižnicu odtiaľ. Existujú dve stránky, pôvodná na Arduino Playground, ale rozumnejšie je ísť rovno na stránku Paula Stoffregena, ktorý knižnicu ďalej rozvíja.
Knižnica používa šestnásťbitový timer 1, ktorý je obvykle nevyužitý na iné činnosti. Pozor ale na to, že manipulácia s ním ovplyvňuje PWM na pinoch 9 a 10. Knižnica poskytuje dve základné funkcie:
V nasledovnom texte budem komentovať príklad Interrupt, ktorý je súčasťou knižnice. Prvým krokom je inicializovať timer na konkrétnej frekvencii. Hodnota sa zadáva v mikrosekundách. V nastavenom intervale sa bude volať váš kód.
Ak chcete zadať hodnotu v tvare frekvencie, použijete výpočet v tvare 1000000/frekvencia a dostanete hodnotu v mikrosekundách, ktorú musíte dosadiť ako parameter. Pozor na to, že exotickejšie frekvencie sa nemusia dať dosiahnuť presne. Čiže 1000 Hz, 10000 Hz a 100000 Hz sa dajú dosiahnuť presne, pri hodnote 100001 Hz bude výsledok zaokrúhlený na čo najbližšiu hodnotu, ktorá je dosiahnuteľná nastavením registrov.
V príklade som nechal iba podstatné časti na pochopenie, celý príklad si môžete pozrieť v IDE. Daný príklad bude blikať LED diódou každých 150 ms.
#include <TimerOne.h>
const int led = LED_BUILTIN; // the pin with a LED
void setup(void)
{
pinMode(led, OUTPUT);
Timer1.initialize(150000);
Timer1.attachInterrupt(blinkLED); // blinkLED to run every 0.15 seconds
}
int ledState = LOW;
void blinkLED(void)
{
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
digitalWrite(led, ledState);
}
Druhý príklad slúži na pochopenie generovania PWM signálu. Klasické Arduino Uno používa dve pevné frekvencie na generovanie PWM. Tieto frekvencie je možné mierne zmodifikovať pomocou nastavenia prescalera, ale nie je to také pružné. Pomocou tejto knižnice sa dá nastavovať signál v jemnejších krokoch.
V komentári sa budem držať približne príkladu FanSpeed, ale kvôli pochopeniu sem doplním iba podobný kód. Celý príklad si môžete pozrieť v IDE. 25 kHz signál dostaneme z výpočtu 1000000/25000=40. (50/100)*1023 je nastavenie striedy (duty).
Pozor na číslo pinu, na ktorom to skúšate. V pôvodnom príklade je pin 4, čo nebude fungovať na Arduino Uno. Asi je to tým, že posledný správca knižnice súčasne propaguje aj svoje kompatibilné dosky Teensy 3.0, na ktorých by to malo byť použiteľné aj na tomto pine. Vždy si skontrolujte svoj mikrokontrolér podľa súboru config\known_16bit_timers.h v knižnici.
#include <TimerOne.h>
const int fanPin = 9;
void setup(void)
{
Timer1.initialize(40); // 40 us = 25 kHz
Timer1.pwm(fanPin, (50 / 100) * 1023);
}
18.09.2015