
2012
Raspberry Pi temperature reading with nodejs
In the previous post about Raspberry Pi I’ve showed what is needed to be done to install an OS with a mini www server on it ( as easy nodejs script).
RPI is not just a miniature version of a standard PC, where you can test applications or web pages. For this, you can use the VM (at the same time allocate more resources). Raspberry has something more – a built-in GPIO expansion port, with which we can interact with external electronic devices. Starting from a simple lighting a LED diodes, through reading the value of the devices to more advanced control possibilities.
In this post I will show you one of those options – the temperature reading from the 1-wire Dallas 18B20 sensor.
System update
Unfortunately, in the available in July Debian image, there were no 1-wire module, the kernel was in 3.1.9 version.
vokiel@rpi ~$ uname -a Linux raspberrypi 3.1.9+ #168 PREEMPT Sat Jul 14 18:56:31 BST 2012 armv6l GNU/Linux |
Work on the RPI is still going on, so the new updates, additions appear very often. In this case we need a system upgrade. There are a plenty instructions avalible on the net, such as: http://elinux.org/RPi_Kernel_Compilation, http://www.bootc.net/projects/raspberry-pi-kernel/. The easiest onve (if you do not want to compile the kernel yourselfs) is Hexxeh’s easy updater tool, the use of which boils down to three commands:
wget http://goo.gl/1BOfJ -O /usr/bin/rpi-update && chmod +x /usr/bin/rpi-update |
sudo apt-get install ca-certificates |
rpi-update 240 #podział pamięci na 240MB CPU / 16MB GPU |
Given solution does not not update the kernel to the latest available version, but it is sufficient to run the 1-wire:
vokiel@rpi ~ $ uname -a Linux rpi 3.2.18+ #20 Mon May 28 17:27:57 EDT 2012 armv6l GNU/Linux |
1-wire module
Forum Thread on RPI forum about 1-wire is quite extensive: http://www.raspberrypi.org/phpBB3/viewtopic.php?t=6649, one is important for us – enabling the kernel module.
Let’s see first if we have the w1 (1-wire) device visible:
vokiel@rpi ~ $ ls /sys/bus/ amba hid mmc platform scsi sdio spi usb |
As we see – we don’t, so we need to add the module, and reboot the Raspberry
root@rpi:~# modprobe w1-gpio |
After reboot everything seems to be ok:
vokiel@rpi ~ $ ls /sys/bus/ amba hid mmc platform scsi sdio spi usb w1 |
Our thermometer will appear in the /sys/bus/w1/devices/
directory, under it’s own id, for example: 28-00000249bf39
. But for this to happen, we need to get on with a small soldering.
Electronics

Dallas 18B20

Dallas 18B20
In the picture on the right you can see how the Dallas 18B20 looks like. It is very small and compact, suitable for miniaturization of the RPI.
Next diagram shows pin marks: 0V (GND), DQ, V + – ground, the signal. power. We need a resistor with a resistance of 4.7kΩ, which need to be inserted between 2-3 pin.
Example schema: (To be sure of right connection, check manufacturer’s datasheet.)
To finish the project, set of cables will be needed yet. A good source might be an old pc, from which we can take out front panel to the motherboard connection cables. The advantage of such is that, they are ready to connect them to the GPIO pins. Another useful thing can be shrink tubs, to have the termometer not look so tragic like mine – isolated with the tape.
Since this is not an electronics blog, I will not be showing here the soldering process, it is not complicated, or even interesting. Ready, connected set looks as follows:
The doubled plug (blue + grey wire) is doubled just because I’ve lacked of single;), gray wire in this case is unnecessary.
Temperature reading
By default w1-wire for RPi operates on GPIO4 (pin 7) – the blue wire on the photo above. I suggest you refer to the system of pins and their markings, convenient schedule is available at http://www.raspberrypi-spy.co.uk/2012/06/simple-guide-to-the-rpi-gpio-header-and-pins/. The white wire visible in the picture, is connected to P1 – Power 3.3 V, black on the back – to the GND.
If everything is connected correctly, you should see the device in the system:
vokiel@rpi ~ $ ls -l /sys/bus/w1/devices/ razem 0 lrwxrwxrwx 1 root root 0 wrz 16 08:16 28-00000249bf39 -> ../../../devices/w1_bus_master1/28-00000249bf39 lrwxrwxrwx 1 root root 0 wrz 16 13:04 w1_bus_master1 -> ../../../devices/w1_bus_master1 |
We can see couple files and folder in the device directory:
vokiel@rpi ~ $ cd /sys/bus/w1/devices/28-00000249bf39 vokiel@rpi /sys/bus/w1/devices/28-00000249bf39 $ ls -la razem 0 drwxr-xr-x 3 root root 0 wrz 16 08:16 . drwxr-xr-x 4 root root 0 wrz 16 08:16 .. lrwxrwxrwx 1 root root 0 wrz 16 13:52 driver -> ../../../bus/w1/drivers/w1_slave_driver -r--r--r-- 1 root root 4096 wrz 16 13:52 id -r--r--r-- 1 root root 4096 wrz 16 13:52 name drwxr-xr-x 2 root root 0 wrz 16 13:52 power lrwxrwxrwx 1 root root 0 wrz 16 13:52 subsystem -> ../../../bus/w1 -rw-r--r-- 1 root root 4096 wrz 16 13:52 uevent -r--r--r-- 1 root root 4096 wrz 16 08:16 w1_slave |
The most important for us is the w1_slave
, from which we will be reading current tempreature. It can be done jus by using cat
program:
vokiel@rpi /sys/bus/w1/devices/28-00000249bf39 $ cat w1_slave c3 01 4b 46 7f ff 0d 10 2f : crc=2f YES c3 01 4b 46 7f ff 0d 10 2f t=28187 |
As it is not difficult to guess, t=28187
is the current temperature from the sensor (28.187 °C). Of course, this figure is not very suitable for further use. Ways to read the temperature in a more readable format is as many as programmers, my looks as follows:
vokiel@rpi /sys/bus/w1/devices/28-00000249bf39 $ \ > cat ./w1_slave | grep t= | cut -f2 -d= | awk '{print $1/1000}' 28.125 |
Node
Since we can read the temperature from the sensor, it’s time to combine it with nodejs.
For start we will need child_process
module by which we call systems command and pick the result of its action.
#!/usr/bin/node var exec = require('child_process').exec; var tempId = '28-00000249bf39', dispTempInterval, dispTempIntervalClock = 10; //sec var dispTemp = function(){ exec( "cat /sys/bus/w1/devices/" + tempId + "/w1_slave | grep t= | cut -f2 -d= | awk '{print $1/1000}'", function( error, stdout, stderr ){ if ( error != null ){ console.log( "Error: " + error); } var temp = parseFloat(stdout).toFixed(2); console.log ( "Current temperature: " + temp + "°C" ); }); } console.log( 'Started node-temp'); console.log( '-----------------'); /* Start interval */ dispTempInterval = setInterval( function(){ dispTemp(); }, dispTempIntervalClock*1000 ); |
We lauch the script and every 10 seconds will se current temperature readings, which could be saved into a database to draw some pretty chart.
Started node-temp ----------------- Current temperature: 22.50°C Current temperature: 22.50°C Current temperature: 24.19°C
After some small modyfications ( github – rpi-node-temp ) the effect looks a little better. I’ve added one threshold that separates “safe” temperature from the critical and colors them respectively. Touching RPi chip with the thermometer shows the effect of colours:
Hej właśnie podłączam ten czujnik według twojego opisu i nie pojawia mi się plik w1_slave. Katalog czujnika pojawia się po podłączeniu.
po wykonaniu: #ls /sys/bus/
amba event_source hid i2c mmc platform scsi sdio spi usb w1
Ruszyło dopiero po załadowaniu kolejnego modułu:
modprobe w1-therm
mój system to też rasbian
Proponuję dodanie obu modułów do /etc/modules:
da to pewność, że będą ładowane przy starcie systemu.
AK
@ZuKo dzięki za tip.
Pewnie się przyda, później, bo jeszcze nie restartowałem jeszcze RPi od czasu tego wpisu;)
edit: po restarcie trzeba było dodać oba moduły. Dopisane do /etc/modules, dzięki za komentarze.
Wie ktoś jak to obsłużyć z poziomu C/C++? Coś bardziej eleganckiego niż cat /sys/bus/w1/…
@guzik nie wiem jak odczyt wartości sensora, ale może dasz radę przez obsługę samego GPIO: http://elinux.org/RPi_Low-level_peripherals#GPIO_Driving_Example_.28C.29
Witam, czy nie masz może skryptu do publikowania odczytu temperatury. Może zamiast wysyłania odczytu do konsoli zapis byłby do pliku lub na stronkę web.
Mam prosty skrypt zapisujący odczyty do sqlite3, ale jeszcze wymaga dorpacowania. W najbliższym czasie planuję kolejne wpisy o RPi, więc pewnie niedługo się pojawi.
Witam, mam jeszcze jedno pytanko: co jakiś czas otrzymuje błędny odczyt temperatury np. w pomieszczeniu mam temp. 22.5 C a czasmi mam odczyt na poziomie -0.012 C. Nie wiem z czego to wynika. Masz moze pomysł co może być źle?
Czasem pojawiają się błędne odczyty, ale zwykle przy nich jest też niepoprawny CRC (pierwsza linia odczytu).
Zatem trzeba przerobić trochę skrypt odczytu, tak aby brał pod uwagę sumę kontrolną i odrzucał wpisy, gdzie jest niepoprawna.
Hej. Próbowaliście podłączać 2 czujniki do jednego gpio? Mi po podłączeniu zaczęły pojawiać się błędy, że jest niewłaściwe CRC. Otrzymuję coś w rodzaju:
zawsze mam ff na początku, złe crc, ale temperatura jest podawana dobra np. tak jak powyżej wyszłoby 28.187
ff ff ff ff ff ff ff ff ff : crc=2f NO
c3 01 4b 46 7f ff 0d 10 2f t=-0.62
jaką macie wartość w pliku w1_master_pullup?
Błędy mogą wynikać z niewłaściwego pull up . Wartość 4k7 jest dla 5V i przy 1 czujniku pewnie jest OK nawet z napięciem 3V. Przy 3V dałem 3k0 i nie ma problemu z 3 czujnikami.
1) czy mogę zamotować 5 takich czujników ?
2) ile max metrów może mieć kabel łączący gpioczujnik ?
1. Możesz zamontować tyle czujników ile pinów GPIO zmusisz do obsługi
2. Testowane przez kumpla na 4m kabla telefonicznego – działa bardzo dobrze. Myślę, że do 10m nie powinno być problemów, powyżej trzeba by policzyć spadki napięcia i rezystancję i ewentualnie skorygować parametry rezystora.
podłączyłem 5 czyhbników równolegle z rezystorem 2.5k i wszystko jest ok. Kabele do czujników maja około 4m.
podłączyłem 5 czujników równolegle, z 1 rezystorem 2.5k i wszystko jest ok(wykorzystałem 3 piny na gpio). Kabele do czujników maja około 4m.
Jak zmienić domyślny pin GPIO4(7) na inny ?
Zobacz w tych wątkach: http://www.raspberrypi.org/phpBB3/viewtopic.php?f=44&t=11127, http://www.raspberrypi.org/phpBB3/viewtopic.php?f=72&t=17975.
Funkcje “General purpose Clock” można uzyskać też na innych pinach: http://elinux.org/RPi_BCM2835_GPIOs#GPCLK0
No to jak dla mnie lipa, bo moduł działa na alternatywnej funkcji GPIO, a nie bezpośrednio na sterowanym pinie GPIO4. Próbowałeś napisać własny program obsługi protokołu 1-wire ??
chyba “wykorzystując po prostu program cat”
Tak, jasne, thx.
Jako zapalony Arduinowiec już od dawna czaiłem się na zakup rPi, ale cały czas powstrzymywał mnie kompletny brak polskich stron poświęconych początkowym boją z tym maleństwem. Mam nadzieję, że szybko się nie poddasz i będziesz kontynuował swoje dzieło 🙂
Pozdrawiam serdecznie!
I tak w ogóle, to skądś Cię kojarzę. Z Blipa? 😉
Może z WordCamp’a 2011 ?
Chyba gdzieś wcześniej już widywałem tego nicka i avatara… No nieważne 🙂
A tak w ogóle, to od kilku dni http://blog.vokiel.com/raspberry-pi-pierwsze-starcie/ zwraca 404…
Dzięki za info, w3 total cache potrafi wyświetlić stronę dla zalogowanego użytkownika, ale dla anonymous już sypie 404.
Witam, mógłbyś wrzucić schemat podłączenia? Byłbym wdzięczny.
@Gizmor jasne, dodałem schemat w treści wpisu.
I learnt a lot from you guys. Thanks for this discussion.
Hej,
jednak uwaga, w tekscie piszesz opernik 47 Ohm
o oznaczenia wskazują na 4.7 kOhm i tak też na schemacie!
to jest roznica 100x i nie wiem czy czegoś ktoś nie usmaży (chyba nie jak podłączy do 3.3V, ale jakby tak do 5V …)
Racja, urwało
k
, dzięki za uwagę.Wpis poprawiony.
Super artykuł! Abstrhując od porządnej treści merytorycznej to czytając czułem się jak w latach 80-tych majstrując interfejs oparty o centroniks w oparciu o artykuł z bajtka. Rozumiem, że nodejs to taki dodatkowy bajer, bo odczyt można zrobić z dowolnego języka pozwalającego na dostęp do systemu plików z /sys/bus/w1/devices/ …
Bardzo pomocny artykuł.
Czy próbował ktoś podłączyć do pojedynczego RPi więcej niż jeden taki termometr? Niestety nie udało mi się znaleźć w Sieci opisów takich konstrukcji
[…] Raspberry Pi odczyt temperatury przez nodejs […]
Witam udało się odczytać 9 termometrów, chodziły w miarę stabilnie, długość kabla ok 20mb z jednym rezystorem 4.7 k napięcie 3,3V kabel skrętka kat 5, powyżej tej 20 m lub większej liczbie czujników albo wyświetla czujniki z wartością 0.0 stopnia lub ich nie widzi. Jestem w trakcie prób może na 5 V lub z rezystorem na końcu lini będzie jakaś poprawa.
Piękna sprawa z tym czujnikiem. A jak zapisywać dane z czujnika do bazy danych? Byłoby o wiele wygodniej z nich korzystać.
Pozdrawiam Autora 🙂
Najprościej zrobić to chociażby w sqlite3, chociaż do node bardziej by pasował jakiś nosql.
Tworzenie bazy:
Odczyt temp z zapisem do bazy:
Dzięki za odpowiedź, niestety nie moge poeksperymentować, bo mój termometr się nie pojawia, wygląda to tak:
pi@raspberrypi ~ $ ls -la /sys/bus/w1/devices/
razem 0
drwxr-xr-x 2 root root 0 mar 19 19:13 .
drwxr-xr-x 4 root root 0 mar 19 19:13 ..
pi@raspberrypi ~ $
sprawdzam jeszcze:
pi@raspberrypi ~ $ ls /sys/bus/
i mam
amba container hid mmc sdio w1
czyli wygląda że dotąd jest ok, połączenia sprawdziłem 10 razy, łącznie z pomiarami napiecia na DS18B20. Szukając przyczyny znalazłem niespójność w schemacie i na zdjęciu. Na chemacie jest podłączone napięcie 5V, a na zdjęciu 3,3V. W necie znalazłem że dla 5V należy zastosować rezystor 4,7kΩ, ale dla 3,3V – 2,7kΩ., Może tu mam przyczynę. Zmieniałem rezystor na 3,67kΩ, potem na 2,8kΩ i nadal nic. Następnym krokiem byłoby podłączenie na 5V z rezystorem 4,7kΩ, ale ponieważ zauważyłem w/w niespójność, a nie chcę zniszczyć malinki pochpnym działaniem (bo nie wiem czy to nie zaszkodzi) wolę się upewnić jak powinno być. Skoro to działa u Ciebie i u wielu innych osób to znaczy że ja coś źle robię, tylko nie wiem co. Proszę o pomoc, pozdrawiam.
Witam. Jest możliwość wystosowania jakichś alertów np. sms czy mail po przekroczeniu danej wartości? Znaczy na RaspberryPi postawić serwer który to będzie obsługiwał?
Odsyłam tutaj – http://www.ematador.pl/pl/p/Modul-Raspberry-Pi-GPIO-Breakout-40-pin/788
Jak się sprawuje, kto go posiada i czy polecacie? Ewentualnie co innego za podobną kasę?