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.
W obecnych wydaniach OpenWrt brak jest modułów kmod-*-gpio-custom. Aby utworzyć daną magistralę należy odpowiednio zmienić plik DTS routera i przekompilować cały system.
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 schemat3Osobiś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 OpenWrtLiczba 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.