3.12. Зчитування аналогового сигналу за допомогою ADC¶
До цього моменту камера зчитувала цифрові сигнали – вивід або 0, або 1, перемикач або розімкнений, або замкнений. Більшість сигналів від реальних датчиків є аналоговими: неперервна напруга, яка плавно змінюється в деякому діапазоні. Фоторезистор проходить через усі значення напруги між шинами живлення при зміні навколишньої освітленості. Вихід датчика температури повільно змінюється на кілька мілівольт при нагріванні кімнати. Вихід мікрофона піднімається та опускається залежно від навколишнього звуку.
Аналого-цифровий перетворювач (ADC) є сполучною ланкою. Він зчитує напругу на виводі та повертає ціле число, яке Python може читати як будь-яке інше значення.
3.12.1. Квантування¶
Цифрове значення не може точно представити неперервну напругу. Завдання ADC – квантувати – прив’язати кожен зразок до найближчого з фіксованого набору рівнів. N-бітний ADC має 2^N рівнів; 12-бітний перетворювач має 4096 рівнів, розподілених по всьому діапазону входу.
Квантування: кожна вибірка аналогового сигналу (суцільна лінія) округлюється до одного з кінцевого набору цифрових рівнів (ступінчаста пунктирна лінія).¶
Напруга між двома сусідніми рівнями – це крок ADC; усе, що менше цього значення, зникає у процесі округлення. 12-бітний ADC при діапазоні 3,3 В має крок близько 3.3 / 4096 ≈ 0.8 mV – достатньо малий, щоб більшість сигналів виглядали в програмному забезпеченні фактично неперервними.
3.12.2. Клас machine.ADC¶
machine.ADC обгортає один аналоговий вхідний канал. Створіть його з виводом, який потрібно зчитати, а потім викличте read_u16():
from machine import ADC
adc = ADC("P6")
value = adc.read_u16()
print(value)
read_u16() завжди повертає беззнакове 16-бітне ціле число від 0 до 65535. Власна роздільна здатність ADC залежить від плати (12 біт на STM32, залежить від порту в інших місцях); результат вирівнюється по лівому краю до 16 біт, щоб деталі апаратного забезпечення не просочувалися в Python – значення 65535 є максимальним незалежно від мікросхеми.
Опорна напруга – вхід, що відповідає повній шкалі – залежить від плати. Перевірте Плати OpenMV для значення на вашій камері. Усе, що перевищує опорну напругу, читається як повна шкала (і може пошкодити вивід, якщо перевищує абсолютну максимальну вхідну напругу).
3.12.2.1. Перетворення відліків у напругу¶
Відображення від відліків до напруги є лінійним, при цьому максимальні відліки точно відповідають Vref:
voltage = counts × Vref / 65535
У коді:
VREF = 3.3 # cam-dependent; see the quickref
counts = adc.read_u16()
voltage = counts * VREF / 65535
print(voltage, "V")
3.12.3. Дільники напруги¶
Два резистори, з’єднані послідовно між шиною живлення і землею, утворюють дільник напруги. Точка між ними перебуває під напругою, яка визначається відношенням двох резисторів:
Дільник напруги: R1 і R2 послідовно знижують Vin до V_out.¶
V_out = Vin × R2 / (R1 + R2)
Рівні резистори дають половину напруги шини; R2 значно менший за R1 ставить відгалуження близько до землі; R2 значно більший ставить відгалуження близько до шини.
Формула передбачає, що нічого більше не відбирає значного струму від V_out. Вивід ADC є високоомним (мегоми, наноампери) і легко задовольняє цю умову, тому дільник, що живить ADC, поводиться так, як передбачає формула.
3.12.4. Потенціометри¶
Потенціометр – це єдиний фізичний компонент, який є дільником напруги з ковзним рушієм, що переміщує відгалуження між двома кінцями. Обертання ручки змінює R1 і R2 разом, зберігаючи їх суму (загальний опір потенціометра) постійною.
Потенціометр, підключений як ручне джерело напруги для ADC: 3,3 В на одному кінці, земля на іншому, рушій до виводу.¶
Потенціометр – це типовий вхідний пристрій для випробування ADC. Підключіть один кінець до 3.3 V, інший до землі, а рушій до виводу з підтримкою ADC; обертання ручки переміщує рушій через усі значення напруги між шинами.
import time
from machine import ADC
pot = ADC("P6")
VREF = 3.3
while True:
counts = pot.read_u16()
voltage = counts * VREF / 65535
print(voltage, "V")
time.sleep_ms(100)
3.12.5. Зчитування вищих напруг за допомогою дільника¶
Напруга вище Vref заблокує ADC на повній шкалі і може пошкодити вхід, якщо перевищить абсолютний максимальний номінал. Щоб зчитати більш високе джерело – акумулятор, вихід датчика, що виходить за межі Vref – знизьте його за допомогою фіксованого дільника напруги перед тим, як він досягне виводу:
Масштабування джерела високої напруги для ADC: R1 і R2 утворюють фіксований дільник напруги, відгалуження якого живить вивід ADC.¶
Підберіть R1 і R2 так, щоб поділена напруга залишалася в діапазоні ADC при максимальній очікуваній вхідній напрузі:
V_adc = V_in × R2 / (R1 + R2)
Для максимального V_in = 12 V і опорної напруги 3,3 В відношення R2 / (R1 + R2) має бути не більше 3.3 / 12 ≈ 0.275. Поширений вибір з невеликим запасом – R1 = 33 kΩ, R2 = 10 kΩ. Відношення дорівнює 10 / 43 ≈ 0.233, тому V_adc досягає максимуму близько 12 × 0.233 ≈ 2.79 V – безпечно нижче Vref.
Щоб відновити оригінальний V_in з показання ADC, оберніть формулу дільника:
V_in = V_adc × (R1 + R2) / R2
У коді:
from machine import ADC
R1 = 33_000
R2 = 10_000
VREF = 3.3
adc = ADC("P6")
counts = adc.read_u16()
v_adc = counts * VREF / 65535
v_in = v_adc * (R1 + R2) / R2
print(v_in, "V")
Кілька практичних зауважень:
Дільник безперервно споживає
V_in / (R1 + R2). ПриR1 + R2 = 43 kΩіV_in = 12 Vце близько 280 мкА – зазвичай нехтовно мало, але якщо джерело живиться від акумулятора, розгляньте більші резистори (від 100 кОм до 1 МОм), щоб зменшити холостий струм.Допуск резисторів (зазвичай ±1 % або ±5 %) безпосередньо впливає на точність вимірювання. Два резистори з допуском ±5 % можуть дати відновленому
V_inмаксимальну помилку приблизно ±10 %.Вихідний імпеданс дільника у поєднанні з будь-якою паразитною ємністю утворює фільтр низьких частот для входу. Для сигналів, що швидко змінюються, це має значення; для перевірки напруги акумулятора – ні.