Kosztowało mnie to maleństwo mniej niż 8 złotych:
Czujnik temperatury DS18B20 z interfejsem 1-wire.
Żeby nie było wątpliwości, to ten "koralik z trzema drucikami" po prawej stronie 🙂 .
Wystarczy podłączyć zasilanie i już można mierzyć temperaturę.
Zakres pomiaru od -55 do 125°C, dokładność ± 0,5°C w zakresie -10 do 85°C.
Jak widzimy, czujnik ten ma trzy wyprowadzenia, masę, zasilanie (3 - 5,5V) i sygnał magistrali 1-Wire.
Z zasilania możemy zrezygnować, czujnik ten potrafi czerpać potrzebną mu energię z linii danych, jednak z pewnymi ograniczeniami, powiemy jeszcze o tym później.
Działania magistrali 1-wire nie będę tu szczegółowo omawiał, akurat na ten temat w internecie jest wiele rzeczowych informacji, powiem tylko o kilku podstawowych rzeczach.
- Do komunikacji między sobą urządzenia wykorzystują transmisję szeregową po przewodzie sygnałowym.
- Do wspólnego przewodu sygnałowego podłączony jest jeden kontroler (może ich być więcej, ale wtedy muszą z sobą współpracować, aby nie dopuścić do transmisji na magistrali w tym samym czasie) i wiele odbiorników.
- Każdy odbiornik posiada unikalny numer (64 bity, z czego 8 bitów to suma kontrolna, a więc 256 adresów)
- Kontroler korzystając ze specjalnego protokołu wykrywa urządzenie na magistrali i steruje transmisją, pilnując, żeby w jednym czasie tylko jedno urządzenie było aktywne.
- Wszystkie uządzenie na magistrali, kontroler również, mają wyjścia typu otwarty kolektor, magistrala musi być zwarta do zasilania opornikiem (typowo 4,7kΩ, choć przy dłuższej magistrali i większej liczbie odbiorników może okazać się potrzebne zmniejszenie tej wartości)
- Każdy odbiornik posiada kondensator 800 pF magazynujący energię, którą urządzenie może być zasilane. Pozwala to na doprowadzenie do odbiornika tylko dwu przewodów, odbiornik zasilany jest wtedy z przewodu sygnałowego. W pewnych przypadkach mogą się jednak pojawić problemy z komunikacją, energia w kondensatorze może okazać się niewystarczająca, dojdzie do resetu odbiornika. Zmniejszenie wartości rezystancji pullup np. do 1 kΩ może trochę pomóc.
- Prędkość transmisji jest niewielka, 16.3 kbit/s, zalecana długość magistrali do 30 metrów, choć w pewnych warunkach (kable o małej pojemności, specjalne nadajniki itp.) można ją zwiększyć nawet do 500 m.
No to koniec zanudzania, podłączamy.
- pin 1 czujnika do masy Raspberry, np. do pinu 9
- pin 2 czujnika do pinu 1-wire Raspberry, standardowo GPIO4 (pin 7)
- pin 3 czujnika do zasilania, np 3,3V, pin 1 Raspberry
- pin 2 i 3 czujnika zwieramy rezystorem 4,7 kΩ (pullup)
Uprzedzając, nie wystarczy skorzystanie w wewnętrznych rezystorów pullup pinów GPIO, mają rezystancję 40 kΩ, za dużo dla magistrali 1-wire. Jeśli bardzo nam przeszkadza ten dodatkowy rezystor, możemy skorzystać z GPIO2 lub GPIO3. Przeznaczone są do komunikacji I2C, mają wbudowane rezystory pullup 1,8kΩ. Oczywiście wtedy i2C nie będziemy mogli używać. Wprawdzie nie testowałem tego, ale powinno działać.
Teraz uruchamiamy w Raspberry 1-wire. Standardowo ta magistrala nie jest aktywna, wiec albo włączamy ją korzystając z komendy raspi-config, albo w pliku /boot/config.txt dodajemy linię:
dtoverlay=w1-gpioSpowoduje to uruchomienie kontrolera 1-wire na standardowym pinie, GPIO4.
jeśli z jakiegoś powodu chcemy użyć innego pinu, możemy go zdefiniować, wpisując na przykład dla GPIO17:
dtoverlay=w1-gpio,gpiopin=17Niestety konieczne bedzie przeładowanie systemu, ale na pocieszenie, to już wszystko, co musieliśmy zrobić, żeby mierzyć temperaturę.
Po restarcie systemu powinniśmy mieć załadowane moduły magistrali 1-wire:
root@minircp:~# lsmod |grep w1 w1_therm 28672 0 w1_gpio 16384 0 wire 36864 2 w1_gpio,w1_thermW /sys/bus/w1 pojawią się urządzenia:
root@minircp:~# ls /sys/bus/w1/devices/ 28-23b10b000900 w1_bus_master1w1_bus_master1 to nasz kontroler magistrali 1-wire, 28-23b10b000900 to nasz czujnik temperatury.
Oczywiście urządzeń odpowiadających urządzeniom magistrali 1-wire pojawi się więcej jeśli je podepniemy, kontroler będzie je odróżniał od siebie na podstawie ich unikatowego 64-bitowego numeru.
Ale jak tę temperaturę odczytać? Jakiś przykładowy program by się przydał, jakaś biblioteka...
No, tym razem jest to prostsze. Wystarczy odczytać zawartość /sys/bus/w1/devices/28-23b10b000900/temperature :
root@minircp:~# cat /sys/bus/w1/devices/28-23b10b000900/temperature 25000 root@minircp:~#25000 to właśnie zmierzona przez czujnik temperatura, w °C, przemnożona przez 1000, czyli w naszym przypadku 25.00°C.
Odczytać ją możemy w prosty sposób korzystając z dowolnego języka, a potem zrobić to, do czego ten pomiar był nam potrzebny.
Wyświetlić, włączyć wentylator, wyłączyć grzejnik, wysłać SMS o przegrzaniu serwerowni, zapisać w bazie danych dobowych temperatur na Kilimandżaro...