Witam .
Poniżej skrypty do obsługi kontrolera I2C tiny USB + ekspander PCF8574/PCF8574A.
Za wyborem I2C tiny przemawia fakt prostoty rozbudowy systemu o kolejne wejścia-wyjścia, niski koszt takiego takiego rozwiązania w przypadku dużej ilości linii, obsługa do 128 wejść-wyjść na pojedynczym kontrolerze oraz to, że każda linia może być traktowana zarówno jako wejście jaki i wyjście.
Minusem jest to, że sterowanie jest całkowicie oparte na programie umieszczonym na routerze, czyli np po restarcie zasilania linie nie wrócą do poprzednich stanów bez wykonania odpowiedniego skryptu na routerze, oczywiście o ile stan taki został wcześniej zapisany
Nie ma również sprzętowego wsparcia "chwilówek" tak jak jest to zrealizowane np w powerSwitch-u, czyli np restart linii zasilania samego routera jest utrudniony
Oczywiście są inne ekspandery niż PCF8574/PCF8574A, np 16 bitowe i nic nie stoi na przeszkodzie aby ich używać, ale te są łatwo dostępne, proste w obsłudze i tanie nawet w postaci gotowych modułów
Wersja podstawowa skryptu (jeden PCF8574):
w zmiennej EXP podajemy parametry takie jak szyna i adres ekspandera
#!/bin/sh
EXP="-y 0 0x20"
OUT="0 7"
# usbrelay.sh polecenie [numer_portu]
# polecenie, pierwszy argument:
# off - wylacza przekaznik
# usbrelay.sh off 0
# on - wlacza przekaznik
# usbrelay.sh on 0
# status - podaje status wszystkich przekazników w postaci numer_przekaznika:on lub numer_portu:off, kazdy w osobnej linii
# usbrelay.sh status
# 0:on
# 1:on
# 2:off
# 3:off
# 4:off
# 5:off
# 6:off
# 7:off
# numer_portu, drugi argument
case "$1" in
off)
i2cset $EXP $(($(i2cget $EXP)&~(2**$2)))
;;
on)
i2cset $EXP $(($(i2cget $EXP)|(2**$2)))
;;
status)
for i in seq($OUT); do echo $i:$((($(i2cget $EXP)>>i)%2))| sed 's/:1/:on/;s/:0/:off/'; done
;;
esac
exit 0
Wersja rozbudowana dwa ekspandery PCF8574 + PCF8574A + pamięć eeprom 24CXX do przechowywania stanu portów
zmienna MEM określa adres pamięci eeprom, EXP... to adresy ekspanderów, FIR... nr do jakiego będzie przypisany w usbrealy pierwszy port ekspandera, NUM... ilość linii ekspandera, skrypt łatwo można zmodyfikować do obsługi kolejnych portów
#!/bin/sh
MEM="-y 0 0x50"
FIR1=0
NUM1=8
EXP1="-y 0 0x20"
FIR2=8
NUM2=8
EXP2="-y 0 0x38"
# usbrelay.sh polecenie [numer_portu]
# polecenie, pierwszy argument:
# off - wylacza przekaznik
# usbrelay.sh off 0
# on - wlacza przekaznik
# usbrelay.sh on 0
# status - podaje status wszystkich przekazników w postaci numer_przekaznika:on lub numer_portu:off, kazdy w osobnej linii
# usbrelay.sh status
# 0:on
# 1:on
# 2:off
# 3:off
# 4:off
# 5:off
# 6:off
# 7:off
# numer_portu, drugi argument
case "$1" in
off)
[ $2 -ge $FIR1 ] && [ $2 -lt $(($FIR1+$NUM1)) ] && i2cset $EXP1 $(($(i2cget $EXP1)&~(2**($2-$FIR1)))) && i2cset $MEM 1 $(i2cget $EXP1)
[ $2 -ge $FIR2 ] && [ $2 -lt $(($FIR2+$NUM2)) ] && i2cset $EXP2 $(($(i2cget $EXP2)&~(2**($2-$FIR2)))) && i2cset $MEM 2 $(i2cget $EXP2)
;;
on)
[ $2 -ge $FIR1 ] && [ $2 -lt $(($FIR1+$NUM1)) ] && i2cset $EXP1 $(($(i2cget $EXP1)|(2**($2-$FIR1)))) && i2cset $MEM 1 $(i2cget $EXP1)
[ $2 -ge $FIR2 ] && [ $2 -lt $(($FIR2+$NUM2)) ] && i2cset $EXP2 $(($(i2cget $EXP2)|(2**($2-$FIR2)))) && i2cset $MEM 2 $(i2cget $EXP2)
;;
status)
(for i in $(seq 0 $(($NUM1-1))); do echo $(($i+$FIR1)):$((($(i2cget $EXP1)>>i)%2))| sed 's/:1/:on/;s/:0/:off/'; done) 2>/dev/null
(for i in $(seq 0 $(($NUM2-1))); do echo $(($i+$FIR2)):$((($(i2cget $EXP2)>>i)%2))| sed 's/:1/:on/;s/:0/:off/'; done) 2>/dev/null
;;
esac
exit 0
warto dodać wpisy np do /etc/rc.local przywracające stan wyjść zapisany w pamięci eeprom przy starcie routera
i2cset -y 0 0x20 $(i2cget -y 0 0x50 1)
i2cset -y 0 0x38 $(i2cget -y 0 0x50 2)