Poniższy opis w dużym stopniu jest oparty na tekście Raspberry Pi odczyt temperatury przez nodejs.
Czujniki temperatury DS18B20 firmy Dallas należy dołączyć do portu GPIO (styki P1, P4 oraz P7)
Do wykonania instalacji potrzeba:
Tzw. przewody połączeniowe żeńskie (4 zł za 10 sztuk); w oryginale to się nazywa jumper wire.
REZYSTOR 0,25W 4,7K OHM węglowy (1,50 zł za 100 sztuk).
DS18B20 termometr 1-wire (4,00--5,00 zł za sztukę).
Kostka elektryczna (około 3 zł za 10 sztuk).
Rurka termokurczliwa do izolacji i wzmocnienia połączeń.
Przewód telefoniczny czterożyłowy lub inny podobny.
Trzy wyprowadzenia układu DS18B20 to: masa (GND), linia danych (DQ) i zasilanie (Vdd). Jeżeli położymy układ ,,napisem do góry''/,,stykami do dołu'' (por. rys. #1), to pierwszy styk od lewj (#1) to GND, środkowy (#2) to DQ a prawy (#3) to Vdd.
Styki DQ oraz Vdd należy złączyć za pomocą rezystora 4K7 (4k7 ohm resistor).
Ja to zrobiłem w ten sposób, że obciąłem złącza żeńskie po jednej stronie przewodów połączeniowych i wsadziłem je do kostki elektrycznej. Następnie dolutowałem dwa kilkucentymetrowe przewody po obu stronach rezystora i końce tych przewodów wsadziłem do odpowiednich styków w kostce elektrycznej. W ten sposób połączyłem DQ oraz Vdd za pomocą rezystora (rys. #5).
Styki czujnika DS18B20 dolutowuję do poszczególnych żył przewodu telefonicznego (jedna żyła jest zbędna). Ponieważ DS18B20 jest bardzo mały, to żeby piny się nie stykały izoluję każdą żyłę cienką rurką termokurczliwą (por. zdjęcie #2, umieszczone obok). Żeby ładniej wyglądało, ale przede wszystkim żeby połączenie czujnik-kabel było mocniejsze (żyły są bardzo cienkie) to na cały przewód naciągam szerszą rurkę (por. zdjęcie #3) i też zgrzewam (por. zdjęcie #4). Zgrzewam zapalniczką....
Odpowiednie żyły przewodu telefonicznego z dolutowanym na końcu układem DS18B20 łączę z kostką. Wydaje mi się, że tak jest lepiej--można łatwiej dodać kolejny termometr lub wydłużyć przewód. Układ jest gotowy i można go podłączyć: Vdd do pina P1, GND do pina P4 a DQ do pina P7. Który pin jest P1 jest jasno oznaczone na płytce.
Moja instalacja ma dwa układy DS18B20: jeden do mierzenia temperatury w pokoju a drugi do mierzenia temperatury na zewnątrz (por. rysunek #5/schemat #6).
Aby Raspberry obsługiwał 1-Wire należy dokonać aktualizacji systemu, co można wykonać na kilka sposobów. Zgodnie z sugestią ze strony Raspberry Pi odczyt temperatury przez nodejs zdecydowałem się na Hexxeh's easy updater tool:
wget http://goo.gl/1BOfJ -O rpi-update sudo mv rpi-update /usr/bin/rpi-update sudo chmod +x /usr/bin/rpi-update # Na wszelki wypadek: sudo apt-get install ca-certificates # rpi-update wymaga zainstalowania gita sudo apt-get install git-core
Teraz można wykonać aktualizację (zabieg zawsze potencjalnie ryzykowny dlatego lepiej się zabezpieczyć wykonaniem kopii systemu, co opisano tutaj.)
pi@raspberrystar ~ $ sudo rpi-update Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS Performing self-update Autodetecting memory split Using ARM/GPU memory split of 192MB/64MB We're running for the first time Setting up firmware (this will take a few minutes) Using HardFP libraries If no errors appeared, your firmware was successfully setup A reboot is needed to activate the new firmware
Teraz należy dodać do jądra moduły niezbędne do obsługi instalacji pomiaru temperatury:
sudo modprobe w1-gpio sudo modprobe w1-therm
Uwaga: aby moduły były dodawana automatycznie, przy starcie systemu należy
dodać w1-gpio
oraz w1-therm
do pliku /etc/modules
.
Mój plik /etc/modules
wygląda następująco:
pi@raspberrystar ~ $ less /etc/modules snd-bcm2835 w1-gpio w1-therm
Po podłączeniu ,,magistrali 1-Wire'' (czytaj kabelków z czujnikami DS18B20
w opisany wyżej sposób) wykonanie polecenia ls
w katalogu /sys/bus/w1/devices/
powinno ujawnić urządzenia
dołączone do magistrali:
pi@raspberrystar ~ $ ls -l /sys/bus/w1/devices/ lrwxrwxrwx 1 root root 0 paź 3 13:45 w1_bus_master1 -> ../../../devices/w1_bus_master1 lrwxrwxrwx 1 root root 0 paź 3 13:58 28-0000032562aa -> ../../../devices/w1_bus_master1/28-0000032562aa lrwxrwxrwx 1 root root 0 paź 3 19:27 10-000802012743 -> ../../../devices/w1_bus_master1/10-000802012743
W przypadku mojej ,,magistrali'' są
to dwa termometry: 28-0000032562aa
oraz 10-000802012743
.
Do odczytania temperatury korzystamy z pliku w1_slave
:
pi@raspberrystar ~ $ cat /sys/bus/w1/devices/28-0000032562aa/w1_slave 60 01 4b 46 7f ff 10 10 b5 : crc=b5 YES 60 01 4b 46 7f ff 10 10 b5 t=22000
Wielkość temperatury to 22,000 stopnie Celsjusza (t=22000
).
Aby odczytać dwa termometry na raz, dodać datę i czas odczytu, a następnie
zapisać wszystko do pliku LOG można zastosować następujący
skrypt (,,prywatne'' skrypty umieszczam w katalogu ~/bin/
):
#!/bin/bash LOG_DIR=/home/pi/Logs/Digitemp ## Data/czas odczytu echo "@`date "+%Y%m%d%H%M%S"`" >> $LOG_DIR/digitemp.log ## Czujnik nr1 echo "28-0000032562aa `cat /sys/bus/w1/devices/28-0000032562aa/w1_slave | tr '\n' ' '`" >> $LOG_DIR/digitemp.log ## Czujnik nr2 echo "10-000802012743 `cat /sys/bus/w1/devices/10-000802012743/w1_slave | tr '\n' ' '`" >> $LOG_DIR/digitemp.log
Zapis wygląda jakoś tak (przy założeniu, że powyższy skrypt znajduje się w pliku ~/bin/dt2ht.sh
):
pi@raspberrystar ~ $ ~/bin/dt2ht.sh @20121004100001 28-0000032562aa 5f 01 4b 46 7f ff 01 10 9b : crc=9b YES 5f 01 4b 46 7f ff 01 10 9b t=21937 10-000802012743 1e 00 4b 46 ff ff 0d 10 38 : crc=38 YES 1e 00 4b 46 ff ff 0d 10 38 t=14937
Gdzie: @20121004100001
oznacza datę i czas,
28-0000032562aa
/10-000802012743
to identyfikatory
czujników a zapis w stylu t=21937
,
to temperatura (21,937 stopni Celsjusza).
Teraz wystarczy dodać odpowiedni wpis do pliku crontab
użytkownika pi
,
aby, przykładowo temperatura była rejestrowana
co godzinę (dt2ht.sh
to nazwa opisanego wyżej
skryptu służącego odczytu temperatury i zapisania wyników do pliku LOG):
pi@raspberrystar ~ $ mkdir ~/Crontab pi@raspberrystar ~ $ vi ~/Crontab/crontab # do pliku ~/Crontab/crontab wpisuję jeden wiersz: # 0 * * * * /home/pi/bin/dt2ht.sh # zapisuję/kończę pracę vi # dodanie zawartości ~/Crontab/crontab do zadań crona pi@raspberrystar ~ $ crontab ~/Crontab/crontab # sprawdzenie czy wszystko jest OK: pi@raspberrystar ~ $ crontab -l 0 * * * * /home/pi/bin/dt2ht.sh
Pozostaje tylko wykonanie (np. za pomocą prostego skryptu PeHaPe) jakiś bardziej efektownego sposobu wyświetlania zawartości pliku LOG.
Dopisane 14 października 2012: W zasadzie działa, ale nie do końca. Czasami nie odczytuje temperatury wypisując CRC error, co wygląda następująco:
62 01 4b 46 7f ff 0e 10 03 : crc=03 NO 62 01 4b 46 7f ff 0e 10 03 t=-1250
Nie mam pojęcia czemu tak się dzieje. Jako workaround wymyśliłem kilkukrotny odczyt:
#!/bin/bash LOG_DIR=/home/pi/Logs/Digitemp function ReadSensor() { local sensorId=$1 local WYNIK="" local SUCCESS="" ## próbuj odczytać max 3 razy for i in 1 2 3; do WYNIK=`cat /sys/bus/w1/devices/$sensorId/w1_slave | tr '\n' ' '` ## pole 12 ($12) to wynik odczytu (YES albo NO): SUCCESS=`echo $WYNIK | awk '{ print $12}'` if [ "$SUCCESS" = "YES" ] ; then ## zapisuje numer próby oraz odczytaną informację : echo "$sensorId=$i $WYNIK" >> $LOG_DIR/digitemp.log ## przerwij pętlę odczytano temperaturę: break fi sleep 3; done ## Trzy próby okazały się nieudane: if [ $SUCCESS = "NO" ] ; then echo "$sensorId=? $WYNIK" >> $LOG_DIR/digitemp.log fi } echo "@`date "+%Y%m%d%H%M%S"`" >> $LOG_DIR/digitemp.log ## Czujnik w pokoju: ReadSensor "28-0000032562aa" ## Czujnik na zewnątrz: ReadSensor "10-000802012743"
Plik LOG wygląda jakoś tak:
@20121014220001 28-0000032562aa=1 62 01 4b 46 7f ff 0e 10 03 : crc=03 YES 62 01 4b 46 7f ff 0e 10 03 t=22125 10-000802012743=1 0e 00 4b 46 ff ff 0f 10 fd : crc=fd YES 0e 00 4b 46 ff ff 0f 10 fd t=6812
gdzie pierwszy wyraz to numer sensora, znak równości, numer próby
w której odczytano temperaturę lub ?
, jeżeli temperatury nie
odczytano.