Аналогово-цифрові перетворювачі в мікроконтролерах

Про обробку аналогових сигналів в мікроконтролерах, або як відчуває комп'ютер

Для отримання даних зовнішнього світу до мікроконтролерів підключаються різного роду датчики і прилади вимірювання. Термометри, датчики світла, електронні вольтметри - це все приклади електронних датчиків. Але звичайні GPIO-входи мікроконтролера можуть зчитувати лише цифрові сигнали, які мають два рівні напруги: високий та низький, в той час як більшість датчиків формують на виході напругу самих різних значень в деякому діапазоні. Такі прилади і сигнали називають аналоговими. Найпростішим прикладом аналогового приладу є потенціометр.

Приклад АЦП з потенціометромНа малюнку зображено приклад підключення потенціометра до Ардуіно-плати. Справа резистор, два його кінці під'єднано до напруги живлення і "землі". Рухомий вивід під'єднано до піна плати. Зміною положення ручки плавно регулюється рівень сигналу на вході А0, від мінімального 0В до максимального - 3,3В. Для зчитування таких сигналів мікроконтролери мають аналогово-цифрові перетворювачі, або АЦП (англ. ADC). Такі перетворювачі вміють зчитувати таку напругу і перетворювати її в цифрове значення, яке далі можна використовувати в коді програми. Зазвичай мікроконтролери мають строго визначений набір пінів, які вміють зчитувати аналогові сигнали. Щоб дізнатись, які саме піни підтримують АЦП, звертайтесь до документації вашої плати (чіпа). Спосіб і результат зчитування в програмі може різнитись між мікроконтролерами, фреймворками, налаштуваннями. Ми покажемо приклад для фреймворку Ардуіно - найпростіший варіант для новачків:

#include "Arduino.h"

void setup() {

Serial.begin(9600);   // ініціалізація UART для виводу в консоль
}

void loop() {
int value = analogRead(A0);  // читання аналогового входу A0

  Serial.print("ADC value: ");
  Serial.println(value);       // вивід у Serial Monitor

  delay(500);                  // пауза 500 мс
}

Рівень сигналу легко зчитується функцією analogRead, яка автоматично вмикає для вказаного піна режим аналогового ВХОДУ і повертає значення від 0 (при мінімальній напрузі на вході) до 1023 (при максимальній напрузі). Також в коді прикладу виводиться інформація у Serial Monitor.

По суті тут потенціометр - це просто дільник напруги. Більшість датчиків мають з себе просто змінний резистор, що змінює свій опір під впливом певного фізичного явища. Так, наприклад, фоторезистор має більший опір при кращому освітленні, більший опір - коли освітлення гірше. Термістор змінює опір в залежності від температури тощо. Таким чином, збираючи схему подільника напруги на подібних резисторах-датчиках ми маємо можливість отримувати дані про навколишній світ в мікроконтролері, і певним чином реагувати на нього. Приклад такого подільника напруги, зібраного з фоторезистором зображено на малюнку:

Підключення фоторезистора до мікроконтролера

Зліва фоторезистор R1 грає роль верхнього плеча подільника - напруга буде зростати при зменшені опору фоторезистора. Справа ж фоторезистор - нижнє плече, і в результаті отримуємо обернену логіку: чим більше світла, тим менша напруга на піні. Резистори R2 і R4 підбираються в залежності від характеристик фоторезистора.

Для лівої схеми, наприклад, напруга буде коливатися між:

  Umin = R2 / (R1+R2) * Vcc = 47000 / (250000 + 47000) * 5 = 0,8V

Umax = R2 / (R1+R2) * Vcc = 47000 / (2000 + 47000) * 5 = 4,8V

Також приклад використання АЦП можна подивитись в навчальному проєкті Детектор перешкод на Arduino.