ADC a PWM s Raspberry Pi Pico

Návod o tom jak jednoduše začít používat ADC a PWM na Raspberry Pi Pico.

V tomto návodu si ukážeme jak jednoduše použít ADC a PWM na Raspberry Pi Pico.

ADC

ADC, neboli převodník analogového signálu do digitální podoby, se používá v případech kdy máme součástku, která má na výstupu analogový signál a my ho potřebujeme zpracovat mikrokontrolerem. Takové součástky jsou nejšastěji různá čidla.

RPi Pico má celkem 5 ADC kanálů. První 3 kanály (0, 1, 2) jsou vyvedeny na piny. Čtvrtý kanál slouží k měření systémového napětí VSYS a pátý kanál je napojen na vestavěný senzor teploty.

Rozlišení ADC je 12 bitů, to znamená, že můžeme převést analogový signál na číslo od 0 do 4095. V implementaci MicroPythonu je kvůli kompatibilitě s ostatními mikrokontroléry rozlišení transformováno do 16 bitů.

Pro použití ADC jej nejprve musíme inicializovat:

import machine

adc = machine.ADC(0)  # kanal 0 odpovida GP26
adc = machine.ADC(26)  # stejny efekt jako vyse

Poté můžeme číst hodnotu:

hodnota = adc.read_u16()

Abychom dostali napětí, které na pinu je, musíme provést jednoduchý výpočet. Víme, že maximální hodnota napětí je 3,3 V a přečtená hodnota z adc při 3,3 V bude 65535 (2^16 – 1). Z toho plyne že:

napeti = hodnota * 3.3 / 65535

Pojďme spojit vše dohromady a zkusme měřit napětí.

Budeme potřebovat jeden rezistor (alespoň 11 Ohm), potenciometr (libovolný), nepájivé pole a 3 dupont propojky.

Technická poznámka k zapojování: Proud na pinech RPi Pico by neměl přesáhnout 300 mA. Nikdy nepropojujte napětí přímo se zemí, v tu chvílí by protékal proud větší než 300 mA a mohlo by dojít k poškození mikrokontroléru.

import machine
import utime

CONVERSION_CONSTANT = 3.3 / 65535
adc = machine.ADC(0)  # kanal 0 odpovida GP26

while True:
    value = adc.read_u16()
    voltage = value * CONVERSION_CONSTANT
    print("{} V".format(voltage))
    utime.sleep(1)

Podobným způsobem můžeme měřit teplotu pomocí zabudovaného teplotního čidla. Stačí inicializovat kanál na který je čidlo připojeno a výsledné napětí dosadit do vzorce.

import machine
import utime

CONVERSION_FACTOR = 3.3 / 65535
temp_sensor = machine.ADC(4)

while True:
    reading = temp_sensor.read_u16() * CONVERSION_FACTOR
    temperature = 27 - (reading - 0.706 ) / 0.001721
    print("Voltage: " + str(reading) + " V, Temperature: " + str(temperature) + " °C")
    utime.sleep(1)

PWM

V minulém návodu jsme si ukázali jak rozblikat vestavěnou LED. Dosáhli jsme toho tak, že jsme přepínali mezi HIGH a LOW a LED buď svítila nebo byla zhasnutá, nic mezi tím. Dnes si ukážeme jak rozblikat LED plynule.

Budeme při tom využívat PWM neboli pulzně šířkovou modulaci. PWM se používá, když na výstupu můžeme mít jenom 2 hodnoty HIGH a LOW, ale potřebujeme dostat něco mezi tím. Uplatní se například při regulaci otáček elektromotorů či stmívání LED.

PWM funguje tak, že se výstup rozdělí do pulzů, kde každý pulz má stejnou periodu T. U každého pulzu pak můžeme definovat střídu (duty cycle), která vyjadřuje poměr mezi dobou kdy je aktivní signál HIGH a periodou pulzu.

https://www.hwlibre.com/wp-content/uploads/2020/01/duty-cycle.jpg.webp

Pro použití PWM jej musíme nejprve inicializovat. Frekvenci a střídu můžeme dodat rovnou do konkstruktoru nebo později.

import machine

pwm = machine.PWM(25, freq=200, duty_u16=65535>>1)

Tímto je PWM aktivní. Střídu můžeme měnit metodou duty_u16([value]) nebo duty_ns([value]), frekvenci metodou freq a když budeme chtít PWM vypnout, tak můžeme použít metodu deinit([value]). Zavoláním metod pro střídu nebo frekvenci bez argumentu vrací aktuální hodnoty. Kompletní dokumentace naleznete zde.

pwm.duty_u16(65535>>2)  # nastaveni stridy
pwm.duty_ns(1/200/2*1000000)  # nastaveni stridy
pwm.freq(120)  # nastaveni frekvence
pwm.deinit()  # vypnuti

Plynulého blikání LED se dosáhne jednoduše tím, že budeme měnit střídu v čase. Vzhledem k VA charakteristice LED budeme měnit střídu kvadraticky, to zajistí plynulejší přechody.

from machine import PWM, Pin
from utime import sleep_us

LED_PIN = 25
BLINK_FREQUENCY = 1
PWM_FREQUENCY = 200 # nastavime tak aby lidske oko nedokazalo rozpoznat blikani
                    # hranice je okolo 120 Hz muzete vyzkouset

led = Pin(LED_PIN)
pwm = PWM(led)
pwm.freq(PWM_FREQUENCY)

duty = 0
direction = 1

while True:
    pwm.duty_u16(duty * duty)
    duty += direction
    if duty >= 255:
        direction = -1
    elif duty <= 0:
        direction = 1
    sleep_us(1_000_000 // BLINK_FREQUENCY // 255 // 2)

Užitečné materiály

Sdílet článek

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *

Mohlo by se také líbit