Raspberry Pi a GPIO – co nefunguje

Jak jsem psal v předchozím článku, Raspberry Pi se často používá na projektech místo Arduino. Na Arduino běžně používáme PWM, pro generování pulzů např. pro ovládání servomechanizmů a ADC pro převod analogové hodnoty, třeba ze senzoru, na digitální podobu. Na Raspberry Pi je to ale vše jinak.
Nálepky:
Pulzně šířková modulace
Pulzně šířková modulace (Pulse-width modulation, PWM) slouží pro generování pulsu s různou mírou plnění. Zjednodušeně řečeno zapínáte a vypínáte napětí na pinu, pin necháváte různě dlouho ve stavu log. 1, a tím regulujete množství energie. Můžete tak ovlivňovat napětí pro analogové výstupy, jas LED, nebo posílat „digitální“ informaci k dalšímu zpracování, servo.
Zařízení, která chcete pomocí PWM ovládat, vyžadují různou přesnost a frekvenci generování pulsů. LED to bude asi dost jedno a bude fungovat ve velkém rozsahu frekvencí, ale modelářské servo vyžaduje velmi přesné hodnoty. Proto mikrokontroléry, třeba AVR na Arduino, obsahují speciální hardwarové obvody, které se o PWM starají.
Raspberry Pi, na rozdíl od Arduino, má jen jeden GPIO se speciální funkcí PWM na pinu 12 (BOARD). Pokud potřebujete více PWM, tak máte dvě možnosti. Nejjednodušší možnost je generování PWM signálu na úrovni software. Tady se vystavujete riziku, že operační systém bude mít na práci něco s vyšší prioritou než vaše aplikace, a pulsy nebudou generovány v požadované kvalitě. Pro Python je doporučena knihovna RPIO.PWM, která využívá DMA, takže by měla být dostatečně nezávislá na CPU. Druhá možnost je využití externího hardware, který se o PWM postará, třeba Adafruit 16-Channel 12-bit PWM/Servo Driver – I2C interface.
A/D převodník
A/D převodník (Analog-to-digital converter, ADC) slouží k převodu analogové hodnoty na digitální. Proces je poměrně složitý a tak je běžné, že na mikrokontrolérech máte jen jeden ADC převodník, který obsluhuje více vstupů. Na Raspberry Pi chybí však úplně. Jedinou možností je použít externí modul, např. Adafruit 16-Bit ADC.
Vlastní modul
Pro PWM je dobrý nápad použít externí modul a pro ADC je to nezbytnost. Cena modulů může být ale zbytečně vysoká. Jak si vyrobit vlastní modul, který bude umět vše co komerční moduly, ale bude levnější a optimálně lepší? Většina modulů je postavena na jednoúčelových obvodech, které komunikují přes sběrnici I2C. Tyto jednoúčelové obvody lze nahradit mnohem univerzálnějším mikrokontrolérem.
Běžné mikrokontroléry PWM i ADC podporují, tak říkajíc, od přírody. Mikrokontrolérů je k dispozici obrovské množství s různými možnostmi. Mezi nejznámější patří asi AVR od společnosti Atmel a PIC od společnosti Microchip. Bohužel programování těchto mikrokontrolérů vyžaduje výrazně větší znalosti než programování pro Raspberry Pi a také musíte mít příslušnou hardwarovou výbavu, tedy programátor mikrokontroléru. Je tady ale jedna možnost, jak si vše velmi zjednodušit a zlevnit.
PICAXE
Když to hodně zjednoduším, tak PICAXE je mikrokontrolér PIC, který programujete v jazyce BASIC a celý programátor jsou dva rezistory a sériový port. Vývojové prostředí je dostupné pro Linux, Mac a Windows.
Nebudu se zde zabývat základy programování pro PICAXE. K dispozici je několik příruček v češtině. Zejména doporučuji sebrané články z různých časopisů.
PICAXE jako modul pro Raspberry Pi
Rozšiřující moduly se nejčastěji připojují na sběrnici I2C, kde Raspberry Pi funguje jako Master a modul jako Slave. Mikrokontroléry PICAXE ve verzích X2 podporují režim I2C Slave. Tento režim není dostupný na nižších verzích. V režimu I2C Slave se PICAXE chová jako paměť, tzv. scratchpad memory, o velikosti 128 (20X2) nebo 256 byte (28X2, 40X2). Z této části paměti může Master číst nebo do něj zapisovat.
Následující kód zapisuje na adresu 0x01 scratchpad memory hodnotu z analogového senzoru:
#no_data
#no_table
init:
' nastaveni vyssi frekvence kvuli rychlosti I2C
setfreq m16
' Nastaveni adresy, pozor, do adresy se pocita jen 7 bitu
hi2csetup i2cslave, %01110000
main:
readadc 1, b1
' zde zapisujeme do pameti pristupne pres I2C
put 1, b1
pause 1000
goto main
Hodnota zapsaná na adresu 0x01 (put) je pak přístupná s Raspberry Pi.
Pokud potřebujeme ihned reagovat na zapsání hodnoty z I2C Master, tak můžeme využít přerušení. Přerušení je vyvoláno, pokud Master zapíše hodnotu do libovolné paměťové buňky scratchpad memory. Na vás je pak zpracování uložené informace.
#no_data
#no_table
init:
' nastaveni vyssi frekvence kvůli rychlosti I2C
setfreq m16
' Nastaveni adresy, pozor, do adresy se pocita jen 7 bitu
hi2csetup i2cslave, %01110000
' preruseni na I2C
setintflags %01000000, %01000000
main:
' Tady neco delam
goto main
interrupt: ' preruseni pri prichozi I2C komunikaci
' nacteni hodnoty na adrese 0x00 scratchpad memory do registru b0
get 0, b0
debug
' reset preruseni
let hi2cflag = 0
setintflags %01000000,%01000000
return
Závěr
Raspberry Pi je rozhodně zajímavá alternativa k velmi populárním deskám Arduino, zejména díky ceně a možnostem komunikace s internetem.