Бібліотека TimerOne
Коли програмуєш для Arduino, іноді буває потрібно періодично виконувати якісь дії через певні інтервали часу – скажімо, 100 разів на секунду; або хочеться мати ШІМ з більшою роздільною здатністю або іншою частотою, ніж дозволяє стандартна функціяanalogWrite(), або раптом хочеться виконувати якусь роботу паралельно, а всюдисущийdelay()все псує. Ось тут може стати в нагоді бібліотекаTimerOne, яку я вам у двох словах опишу.
Ця бібліотека дозволяє використовувати з метою один з таймерів в МК AVR, встановлених на платах Arduino. Апаратних таймерів в ATmega168 і ATmega328 є 3 штуки (ATmega1280 і ATmega2560 їх 6), і називаються вони Timer0, Timer1 і Timer2. Всі вони використовуються для ШІМ у функціїanalogWrite(), але розрядність такої ШІМ обмежена найменшою розрядністю таймерів, а Timer0 і Timer2 - 8-розрядні, тому максимальне значення, яке сприймаєanalogWrite()- 255. Але Timer1-то 16-розрядний! Щоб задіяти міць цього таймера, одна добра людина і написав бібліотеку TimerOne. Скачаємо бібліотеку звідси, встановимо та подивимося, які методи доступні в бібліотеці:
Цей метод потрібно викликати для ініціалізації таймера, перш ніж викликати будь-які інші. За замовчуванням задається інтервал спрацьовування за 1 секунду, але можна вказати свій у мікросекундах. Мінімальний доступний інтервал – 1 мікросекунда. Після ініціалізації піни 9 і 10 на Arduino (11 і 12 на Arduino Mega) зможуть використовуватись бібліотекою для ШІМ, але зупинитьсяanalogWrite()'івська ШІМ на цих пінах, якщо така була задіяна до викликуinitialize(). Поки працюєте з бібліотекою TimerOne, для перерахованих вище пінівanalogWrite() не викликайте, і навпаки.
Встановлює інтервал спрацьовування таймера мікросекундах. Мінімальний інтервал дорівнює 1 мкс (відповідно, максимальна частота – 1 МГц), максимальний – 8388480 мкс (близько 8.4 с).
Встановлює заповнення ШІМ для вказаного піна, якщо ШІМ на ньому вже включено.
Вимикає ШІМ на вибраному піні.
Встановлює функцію (переробник переривання), яка буде викликатися після завершення встановленого інтервалу таймера. Така функція повинна мати вигляд:
Параметрperiod, як завжди, задає інтервал спрацьовування (і, як завжди, для всього таймера). Потрібно бути обережним, і не виконувати занадто багато коду в обробнику, інакше головний цикл (loop) взагалі може ніколи не отримати управління. Якщо задати період 1 мкс, такий результат практично гарантований, т.к. за цей час AVR з кварцом в 16 МГц (як на Arduino) встигне виконати інструкцій десь на десяток тактів - тобто, скласти пару-трійку чисел, і навіть на один digitalWrite( ) цього часу не вистачить . Загалом, не раджу встановлювати обробник для періодів менше 100 мкс (0.1 мс), якщо ви не розрахували за тактами час виконання оброблювача і не впевнені на 100%, що часу вистачить (:
Вимикає обробник переривання.
Запускає таймер, якщо його було зупинено.
Застосування всьому цьому придумати нескладно: перше, що спало на думку — мигалка двома світлодіодами не те що без delay(), а взагалі без нашої участі. Світлодіоди будуть на пінах 9 і 10:
Ну, а що ще можна зробити, використовуючи TimerOne, вже залежить від вашої фантазії.