3.12. Зчитування аналогового сигналу за допомогою ADC

До цього моменту камера зчитувала цифрові сигнали – вивід або 0, або 1, перемикач або розімкнений, або замкнений. Більшість сигналів від реальних датчиків є аналоговими: неперервна напруга, яка плавно змінюється в деякому діапазоні. Фоторезистор проходить через усі значення напруги між шинами живлення при зміні навколишньої освітленості. Вихід датчика температури повільно змінюється на кілька мілівольт при нагріванні кімнати. Вихід мікрофона піднімається та опускається залежно від навколишнього звуку.

Аналого-цифровий перетворювач (ADC) є сполучною ланкою. Він зчитує напругу на виводі та повертає ціле число, яке Python може читати як будь-яке інше значення.

3.12.1. Квантування

Цифрове значення не може точно представити неперервну напругу. Завдання ADC – квантувати – прив’язати кожен зразок до найближчого з фіксованого набору рівнів. N-бітний ADC має 2^N рівнів; 12-бітний перетворювач має 4096 рівнів, розподілених по всьому діапазону входу.

A smooth analog curve plotted against time, overlaid with a stepped digital approximation. Dashed horizontal lines mark the quantization levels; the stepped curve snaps to whichever level is nearest the analog signal at each sample point.

Квантування: кожна вибірка аналогового сигналу (суцільна лінія) округлюється до одного з кінцевого набору цифрових рівнів (ступінчаста пунктирна лінія).

Напруга між двома сусідніми рівнями – це крок 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. Дільники напруги

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

A voltage divider. Vin at the top connects through R1 to a node tapped off as V_out, which then connects through R2 to ground.

Дільник напруги: R1 і R2 послідовно знижують Vin до V_out.

V_out = Vin × R2 / (R1 + R2)

Рівні резистори дають половину напруги шини; R2 значно менший за R1 ставить відгалуження близько до землі; R2 значно більший ставить відгалуження близько до шини.

Формула передбачає, що нічого більше не відбирає значного струму від V_out. Вивід ADC є високоомним (мегоми, наноампери) і легко задовольняє цю умову, тому дільник, що живить ADC, поводиться так, як передбачає формула.

3.12.4. Потенціометри

Потенціометр – це єдиний фізичний компонент, який є дільником напруги з ковзним рушієм, що переміщує відгалуження між двома кінцями. Обертання ручки змінює R1 і R2 разом, зберігаючи їх суму (загальний опір потенціометра) постійною.

A potentiometer wired between 3.3 V and ground. The wiper is tapped off to an ADC pin.

Потенціометр, підключений як ручне джерело напруги для 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 – знизьте його за допомогою фіксованого дільника напруги перед тим, як він досягне виводу:

A voltage divider scaling a high V_in down to an ADC pin. R1 runs from V_in down to a junction, which is tapped off horizontally to the ADC pin; R2 continues from the junction down to ground.

Масштабування джерела високої напруги для 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 , R2 = 10 . Відношення дорівнює 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 і V_in = 12 V це близько 280 мкА – зазвичай нехтовно мало, але якщо джерело живиться від акумулятора, розгляньте більші резистори (від 100 кОм до 1 МОм), щоб зменшити холостий струм.

  • Допуск резисторів (зазвичай ±1 % або ±5 %) безпосередньо впливає на точність вимірювання. Два резистори з допуском ±5 % можуть дати відновленому V_in максимальну помилку приблизно ±10 %.

  • Вихідний імпеданс дільника у поєднанні з будь-якою паразитною ємністю утворює фільтр низьких частот для входу. Для сигналів, що швидко змінюються, це має значення; для перевірки напруги акумулятора – ні.