Obsługa GPIO w OpenWrt
Ostatnia zmiana: 2023-09-05 18:13

O sterowaniu liniami GPIO można przeczytać w pierwszej części poradnika. GPIO maja różne zastosowania w routerach. Zwykle wykorzystywane są jako linie do sterowania konfiguracją przełącznika, skojarzone są z diodami led oraz przyciskami. Przy odrobinie umiejętności można takie linie wykorzystać do własnych potrzeb.

Cześć linii może być wykorzystywana przez system i wtedy należy wykorzystywać mechanizmy dostępne systemowo (patrz: sterowanie diodami LED i przyciskami), lub odpowiednio modyfikując kody źródłowe zwolnić system od wykorzystywania tych linii.

Każdą linię można zdefiniować jako wejściową lub wyjściową, opisane to zostało w pierwszej części poradnika.

W przykładach założono, że dostępne są cztery GPIO o numerach 2, 3, 4 oraz 5. Dostępne numery zależą od konkretnego modelu urządzenia; należy więc polecenia dostosować o posiadanego sprzętu.

Liczba dostępnych GPIO: 1

Sterowanie diodą

UWAGA: dla niektórych routerów wydajność prądowa gpio może być niewystarczająca do bezpośredniego zasilenia diody LED


    # echo "2" > /sys/class/gpio/export
    # echo out > /sys/class/gpio/gpio2/direction

Sterowanie to:


    # echo 1 > /sys/class/gpio/gpio2/value

dla włączenia linii, oraz


    # echo 0 > /sys/class/gpio/gpio2/value

dla wyłączenia linii.



Odczyt przycisku

Ustawiamy linię jako wejściową i odczytujemy jej wartość


    # echo "2" > /sys/class/gpio/export
    # echo in > /sys/class/gpio/gpio2/direction
    # cat /sys/class/gpio/gpio2/value

Ponieważ nie jest to skojarzone z systemem, to musimy samodzielnie zapewnić odpytywanie linii (nie będzie wołany żaden skrypt z hotpluga).

Cykliczny odczyt wartości możemy zrobić prostym skryptem:


    # GPIO=2; while true; do sleep 1; [ $(cat /sys/class/gpio/gpio$GPIO/value) = "1" ] && echo -n -|| echo -n _; done

Stan "_" to wciśnięcie przycisku.



Sterowanie przekaźnikiem

Podobnie jak w poprzednim przykładzie, linia wyjściowa może służyć do sterowania przekaźnikami czy triakami, a tym samym włączeniem/wyłączeniem urządzeń zasilanych z 230V. Przykładowe schematy:

schemat1 schemat2 schemat3

Osobiście wykonałem urządzenie wg schematu pierwszego - działa wyśmienicie. Koszt elementów takiego układu dla jednego kanału - ok 10zł.

Magistarala 1-Wire

Magistrala 1-Wire jest znana chociaż by z powodu popularnego czujnika temperatury DS1820 - ale oczywiście są też dostępne inne czujniki, a także chipy pamięci czy portów I/O. Zaletą tej magistrali jest użycie tylko jednej linii danych.

Aby utworzyć magistralę 1-Wire należy zainstalować pakiet kmod-w1-gpio-custom


    # opkg install kmod-w1 kmod-w1-master-gpio kmod-w1-gpio-custom

Konfiguracja to określenie która linia GPIO ma być wykorzystywana; w tym przykładnie to GPIO2, wiec wygląda to w następujący sposób:


    # insmod w1-gpio-custom bus0=0,2,0

Oczywiście można uprościć sobie sprawę wprowadzając ten parametr na stałe:


    # echo "w1-gpio-custom bus0=0,2,0" > /etc/modules.d/59-w1-gpio-custom

Należy pamiętać że, linie gpio są bezpośrednio wprowadzone do układów SoC - w związku z tym wyprowadzenie ich na zewnątrz i podłączenie długim kablem bez żadnych zabezpieczeń jest raczej złym pomysłem. Należy także pamiętać że napięcie z routera to 3,3v, niektóre układy mogą wymagać zasilania z 5V.

Jako przykład można podać właśnie odczyt temperatury z chipu DS1820. Należy zainstalować pakiet kmod-w1-slave-therm


    # opkg install kmod-w1-slave-therm

A następnie odczytać wartość z czujnika. Dane zawarte są w podkatalogu /sys/bus/w1/drivers/w1_slave_driver/numer_seryjny_czujnika. Czujników może być kilka i należy jest wtedy połączyć równolegle. Odczyt wartości to:


    # cat /sys/bus/w1/drivers/w1_slave_driver/*/w1_slave

W tym przypadku był to wynik:


    7c 01 4b 46 7f ff 04 10 09 : crc=09 YES
    7c 01 4b 46 7f ff 04 10 09 t=23750

Ważną daną jest wartość CRC (YES) wskazujący poprawność odczytu. Temperatura to wartość t=, jej odczyt w postaci czytelnej dla człowieka to:


    # awk -F= '/t=/ {printf "%.02f\n", $2/1000}' /sys/bus/w1/drivers/w1_slave_driver/*/w1_slave



Liczba dostępnych GPIO: 2

Magistrala i2c

Wymagane jest zainstalowanie modułu kmod-i2c-gpio-custom


    # opkg install kmod-i2c-gpio-custom

Konfiguracja to załadowanie modułu z odpowiednimi opcjami:


    # insmod i2c-gpio-custom.ko bus0=0,2,3

lub


    # echo "i2c-gpio-custom bus0=0,2,3" > /etc/modules.d/i2c-gpio-custom

Gdzie 0 to numer kolejny magistrali i2c (ma zostać 0 jak innej nie ma), 2 to linia SDA (dane - gpio2), 3 to linia SCL (zegar - gpio3).
Jeżeli zostało to wykonane, można już odczytać wartości z rejestrów podłączonego chipu (w tym przypadku był to LM75 - po instalacji pakietu i2c-tools)


    # i2cdetect 0
    WARNING! This program can confuse your I2C bus, cause data loss and worse!
    I will probe file /dev/i2c-0.
    I will probe address range 0x03-0x77.
    Continue? [Y/n] y
                        0 1 2 3 4 5 6 7 8 9 a b c d e f
    00: -- -- -- -- -- -- -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
    50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    70: -- -- -- -- -- -- -- --
    # i2cget 0 0x48 0 w
    WARNING! This program can confuse your I2C bus, cause data loss and worse!
    I will read from device file /dev/i2c-0, chip address 0x48, data address
    0x00, using read word data.
    Continue? [Y/n]
    0x0016

Należy teraz zdekodować tylko tą wartość (zgodnie z wymaganiami danego chipu).

Należy także pamiętać że napięcie z routera to 3.3V, niektóre chipy mogą wymagać zasilania z 5V.



Magistrala I2C otwiera dostęp do możliwości podłączenia szerokiej gamy czujników, urządzeń, wyświetlaczy LCD.

Magistrala SPI

SPI over GPIO in OpenWrt

Liczba dostępnych GPIO: 4

SDMOD

Jeden z najpopularniejszych sposobów wykorzystania linii - SDMOD, czyli dodanie karty SD do systemu. Pozwalało to uzyskać dodatkową przestrzeń na dane i programy w czasach, kiedy routery z portem USB nie były dostępne.

Do obsługi niezbędne są pakiety kmod-mmc-over-gpio z zależnościami oraz obsługa systemu plików, np. vfat.


    # opkg install kmod-mmc-over-gpio kmod-fs-vfat kmod-nls-cp437 kmod-nls-iso8859-1

Konfiguracja zawarta jest w pliku /etc/config/mmc_over_gpio. W zależności od sposobu podłączenia należy umieścić tam odpowiednie wartości, np.


    # uci set mmc_over_gpio.@mmc_over_gpio[0].enabled=1
    # uci set mmc_over_gpio.@mmc_over_gpio[0].DI_pin=3
    # uci set mmc_over_gpio.@mmc_over_gpio[0].DO_pin=5
    # uci set mmc_over_gpio.@mmc_over_gpio[0].CLK_pin=4
    # uci set mmc_over_gpio.@mmc_over_gpio[0].CS_pin=2
    # uci commit mmc_over_gpio

Przy takim połączeniu


    Karta SD router
    
    9
    1 CS GPIO 2
    2 DI GPIO 3
    3 GND GND
    4 VDD +3,3v
    5 CLK GPIO 4
    6 GND GND
    7 DO GPIO 5
    8

Uruchomienie to


    # /etc/init.d/mmc_over_gpio start

Jeżeli zostało to poprawnie podłączone to w logach powinna pojawić się informacja typu:


    mmc_spi spi0.0: ASSUMING 3.2-3.4 V slot power
    mmc_spi spi0.0: SD/MMC host mmc0, no DMA, no WP, no poweroff
    gpio-mmc: MMC-Card "mmc" attached to GPIO pins di=3, do=5, clk=4, cs=2
    mmc_spi spi0.0: can't change chip-select polarity
    mmcblk0: mmc0:0000 SD 1960448KiB
        mmcblk0: p1

Zostaje jeszcze tylko zamontowanie systemu plików (lub wykona się do automatyczne jeżeli został zainstalowany pakiet block-mount)


    # mkdir -p /mnt/sd
    # mount -t vfat /dev/mmcblk0p1 /mnt/sd

LCD

Cztery linie wystarczą do wysterowania oddzielnego wyświetlacza LCD (np. od nokii 5110/3310). Oczywiście są też wyświetlacze na i2c, wtedy wymagana ilość linii spada do 2.

W większości przypadków (magistrala 1-Wire, i2c, a także sterowanie przełącznikami) dostępne są także gotowe moduły na USB (do kupienia np. na allegro), które umożliwiają realizację podobnych tematów.