Операції аналогового введення-виводу, робота зі звуком Знайомство з Arduino частина 3
Хоча цифрові операції вводу-виводу дозволяють вирішувати широке коло завдань, проте наявність в мікроконтролері плати Arduino вбудованого аналого-цифрового перетворювача (АЦП) і можливість виведення аналогових сигналів за допомогою широтно-імпульсної модуляції (ШІМ) забезпечують роботу з аналоговими датчиками та всілякими виконавчими пристроями, впливають на об'єкт пропорційно до керуючого сигналу.
У режимі виведення всі лінії портів Arduino можуть передавати тільки дискретні сигнали, що мають лише два стани. Але мікроконтролер здатний змінювати ці стани дуже швидко, генеруючи прямокутні імпульси. Якщо подати ці імпульси на будь-який пристрій, що володіє інерційними властивостями, воно поводитиметься так, ніби напруга, що подається на нього, постійна, рівна середньому значенню імпульсного, і змінюється плавно, а не стрибками між високим і низьким логічними рівнями.
У режимі ШІМ порт формує імпульсний сигнал постійної частоти та змінної шпаруватості (це відношення періоду проходження імпульсів до їх тривалості). Часто замість шпаруватості оперують оберненою їй величиною - коефіцієнтом заповнення, який можна змінювати від 0 (немає імпульсів) до 100% (імпульси слідують, злившись, без пауз). Отже, хоча кожен окремий момент вихідна напруга відповідає високому чи низькому логічному рівню, його середнє значення пропорційно коефіцієнту заповнення. Якщо до цього виходу підключити звичайний мультиметр, він покаже це значення (звичайно, якщо частота імпульсів досить висока).
В Arduino UNO в режимі ШІМ можуть працювати виходи D3, D5, D6, D9, D10 та D11. Зазвичай на платі вони позначені знаками.
або абревіатурами "PWM". Слід зазначити, що у плат Arduino інших модифікацій кількість таких виходів може бути більшою або меншою.
У найпростішому випадку ШІМ можна застосувати для керування яскравістю світлодіоду. Цей прилад практично безінерційний, але людський зір має достатню інерційність, щоб послідовність швидких спалахів світлодіода сприймалася як безперервне світіння із залежною від коефіцієнта заповнення яскравістю.
Дискретні виходи, здатні формувати ШІМ, налаштовані використання цього режиму за промовчанням, тому викликати функцію pinMode() їхнього роботи у такому режимі не нужно. Для встановлення коефіцієнта заповнення ШІМ-сигналу є стандартна функція analogWrite(N, M), де N - номер виведення, M - число, пропорційне необхідному коефіцієнту заповнення. Воно має лежати в інтервалі від 0 до 255, причому 0 відповідає нульовому коефіцієнту заповнення (навихід постійний низький рівень), 255 - коефіцієнту заповнення 100% (на виході постійний високий рівень). Тимчасові діаграми вихідної напруги при деяких значеннях M і коефіцієнта заповнення Кз показані на рис. 1.

Мал. 1. Тимчасові діаграми вихідної напруги
Наприклад розглянемо наведену у табл. 1 програму, яка поступово збільшує яскравість світла світлодіода, підключеного до цифрового виходу D9, а потім поступово зменшує її. Вона заснована на стандартному прикладі examples3.AnalogFading із комплекту поставки Arduino IDE. Перебір значень коефіцієнта заповнення імпульсів реалізований тут за допомогою вже розглянутих у [1] операторів циклу for.

Для прийому аналогових сигналів від зовнішніх пристроїв Arduino призначені входи A0-A5, за умовчанням встановлені внеобхідне цього стан, отже додаткової ініціалізації не потрібно. АЦП, вбудований Arduino UNO, формує 10-розрядні двійкові коди і вхідна напруга, що лежить в інтервалі від 0 до +5 В, перетворює в ціле число від 0 до 1023 (210-1).
Для зчитування результату перетворення функція analogRead(N), де N - номер аналогового входу.
До аналогових входів Arduino можна підключати різноманітні датчики, вихідна напруга яких пропорційно до вимірюваної величини (змінні резистори, терморезистори, фоторезистори та ін.). Однак слід пам'ятати, що на аналоговий вхід можна подавати напругу лише від 0 до +5 В. Якщо вихідна напруга датчика лежить в іншому інтервалі або воно негативної полярності, сигнал необхідно попередньо укласти у вказаний інтервал. Опитування аналогового входу виконується з частотою менше 10 кГц [2], що може виявитися недостатнім для аналізу деяких швидкозмінних сигналів.
Наявність аналогових входів дозволяє перетворити Arduino на найпростіший цифровий вольтметр, що вимірює постійну напругу від 0 до +5 В і передає результат вимірювання на комп'ютер. Для цього достатньо завантажити в програму Arduino, наведену в табл. 2.

Зверніть увагу, що в програмі константами задані зразкова напруга АЦП Uref (у мілівольтах) і коефіцієнт перерахунку вихідного коду АЦП в напругу Ku. Значення коефіцієнта обчислюється розподілом заданої зразкової напруги на 1023. Коефіцієнт зазвичай дробовий, тому константа Кі має тип float (число з плаваючою комою). Константа Uref має такий самий тип для правильного обчислення коефіцієнта. Оскільки в правій частині формули знаходяться лише константи, обчислює коефіцієнт не мікроконтролер, виконуючи програму, а сам компіляторетап її трансляції.
Все це дозволяє підвищити точність вольтметра, вимірявши мультиметром точне значення зразкової напруги на виводі Uref плати Arduino і записавши його в програму, надавши константі Uref. Про інші способи підвищити точність аналого-цифрового перетворення можна прочитати [3, 4].
Під час роботи програми на платі блимає світлодіод TX, що сигналізує про передачу інформації через послідовний порт. Світлодіод RX не світиться, оскільки комп'ютер нічого не передає у відповідь. Вбудований термінал Arduino IDE відображає прийняту інформацію (рис. 2) – результати вимірювання напруги гальванічної батареї 3332.

Мал. 2. Вікно програми
Arduino може подавати як світлові, а й звукові сигнали. Для цього до одного з його виходів необхідно підключити п'єзовипромінювач звуку, наприклад, ЗП-1 (рис. 3).

Мал. 3. Підключення п'єзовипромінювача звуку
Для роботи зі звуком передбачено спеціальну функцію tone(N, F, T), де N - номер виведення, на якому будуть сформовані прямокутні імпульси; F – частота звуку, Гц; T – тривалість звуку, мс. Останній параметр не є обов'язковим. За його відсутності звук буде безперервним. Щоб вимкнути його, передбачено функцію noTone(N).
Звичайно, п'єзокерамічний випромінювач звуку складно назвати пристроєм високоякісного відтворення, а сигнал, що формується мікроконтролером, має прямокутну форму, проте використання цих функцій дозволяє виконувати нескладні мелодії. Приклад наведено у табл. 3. Це трохи змінена програма examples 02.Digital oneMelody, що входить до комплекту середовища розробки Arduino IDE. Оскільки задавати вручну частоту кожної ноти мелодії незручно, до програми у її заголовку директивою #includeпідключено файл pitches.h. Ця операція є рівнозначною включенню в програму повного тексту цього файлу. У цьому випадку він містить список назв нот, які можна відтворити, та їх частот.

Випромінювач звуку має бути підключений до виходу D8.
У прикладі використані два масиви: int melody[] містить назви нот мелодії, int note Durations[] - їх тривалість в мілісекундах. Для звернення до елемента масиву вказують його ім'я із укладеним у квадратні дужки порядковим номером. Щоб легко змінювати число нот у мелодії, воно обчислюється з допомогою функцій sizeof(V), повертають число байтів, займаних її аргументом (змінної чи його масивом) у пам'яті мікроконтролера. У цьому випадку масив melody займає 16 байт, а довжина його елементів типу int - два байти. Тому змінна Note отримує значення 8 і саме стільки разів буде повторено тіло циклу for, що по черзі відтворює ноти.
Якщо до масиву melody[] додати кілька нот, відповідно зміниться значення Note. Потрібно не забути доповнити масив noteDurations[] тривалістю звучання цих нот.
Оскільки мелодія виконується один раз, всі необхідні для цього операції розміщені всередині функції setup().
Для повторного виконання потрібно привести мікроконтролер у вихідний стан, натиснувши на кнопку Arduino, що знаходиться на платі Arduino,
Розглянуті в статті програми Arduino можна скачати тут.
1. Лекомцев Д. Arduino. Операції цифрового введення-виводу. – Радіо, 2016, № 8, с. 51-54.