Raspberry pi a používání 1-wire bus
Teno příspěvek je soubor postřehů k problematice One Wire Bus a jeho propojení s RPi a instalaci a ladění owfs (a finálně připojení senzorů přes owfs do Homeassistantu – ale tím se zabývá jiný příspěvek).
1-wire bus
Pěkný článek tady. Česky něco málo na začátku tohoto článku.
Topologie a délka kabelů
Doporučení jednoho z výrobců využívající HW master.
Typy připojení 1-wire senzorů k Raspberry pi
Základní srovnání c češtině je pěkně zde – kapitola „Jak připojit 1-wire zařízení k RPi“. K tématu je i diskuze pod článkem.
GPIO
Nejlevnější a nejjednodušší řešení. Ale viz. článek zde, asi bude možné připojit jen méně senzorů na kratších drátech. Asi je to SW řešení – controllerem 1wire sběrnice je přímo RPi, ostatní řešení mají HW controller a pak po jiné sběrnici (I2C, usb, serial) do RPi komunikují výsledky.
V owfs.conf bude jako zdroj „server: w1 = all“.
I2C
Podle prvního článku níže lepší řešení z hlediska stability, není drahé < 100 Kč, ale pracnější než ostatní (v postupu z návodu je třeba pájení, nicméně možná už někde bude také „hotovější“ řešení).
Návod v češtině zde.
Novější návod v angličtině zde a jiný zde.
Hotové řešení i se schématem, které používá MOSFET na pinu 6 DS2482-100 je zde.
Projekt PoEpi od Ondřeje Caletky, který také obsahuje 1-wire kontroller na I2C s DS2482-100 v angličtině zde a zde.
V owfs.conf bude jako zdroj „server: i2c = /dev/i2c-0:ALL“ (parametry za /dev/ možná bude třeba upravit).
USB adaptér (DS9490)
Na netu jsou dostupná hotová řešení.
Návod (z roku 2012) na zprovoznění owfs s pomocí USB adaptéru typu DS9490 zde.
V owfs.conf bude jako zdroj „server: usb = all“.
RS232 adaptér (DS9097)
Na netu jsou dostupná hotová řešení.
V owfs.conf bude jako zdroj „server: device = /dev/ttyS0“ (parametry za /dev/ možná bude třeba upravit).
Více 1-wire busů
Pokud máte s připojením více senzorů na jednom pinu problém a nepomohly typy níže a máte kabely částečně do hvězdy (více kabelů končí u RPi s GPIO) je možno rozdělit na více pinů.
Pro otestování jsem zkoušel připojit druhý 1-wire bus na GPIO pin 17.Pro zprovoznění je třeba upravit konfiguraci.
sudo nano /boot/firmware/config.txt
Nyní přidat řádek
dtoverlay=w1-gpio,gpiopin=17
Po restartu se senzor připojený na tento pin ukázal v „/sys/bus/w1/devices“ a stejně tak ho zdetekoval owserver.
Test 1
Po přečtení článků jsem usoudil že tpologii hvězda zkoušet nebudu (všude od toho odrazují). Jelikož mám spoustu zbytků cat5e UTP drátu, žekl jsem si, že ho zkusím použít. Nemám doma žádné šílené vzdálenosti (řádově bude do 30m kamkoli), ale kabely k některým čidlům už mám natahané z jednoho místa (právě ta nedporučovaná hvězda). Cat5e UTP má nicméně 8 drátů a 1 wire potřebuje 3 (respaktive 2 ale počítám s připojením pinu napájení), napadlo mne proto použít jeden drát pro cestu „tam“ a druhý pro cestu zpátky. Pro cestu „tam“ jsem použil zelený drát, pro cestu zpátky modrý. Pro napájení jsem používal oranžový a pro zem všechny bílé od těchto tří (později jsem používal oranžová + oranžovobílá pro napájení a modrobílá + zelenobílá pro zem, rozdíl jsem nepozoroval). Připravil jsem si 2 kabely 10m a 30m a několik DS18B20 čidel. Některá čidla jsem měl na připravených asi metrových drátech – ty jsem používal na konce kabelů a připojil tím co bylo po ruce (čokolády). Pár dalších čidel jsem hodil na breadboard.
Test s 4,7 kohm pullup
Nejprve jsem připojil na pin 4 dvě čidla na breadboardu, a další 3 na 10m kabelu a pak ještě jedno na breadboardu na vracejícím se modrém kabelu (tedy na obrázku to co jde od arduina + čidla nejvíc nalevo). Jako pullup odpor jsem měl 4,7 kohm. Napájel jsem 3,3V z Arduina. V této konfiguraci funkgovalo, ale jakmile jsem připojil k datovému vodiči 30m kabel – byť bez připojeného čidla, zmizeli teploty na všech čidlech.
Poté jsem přehodil napájení pro senzory z 3,3V na 5V. Takto se mi podařilo připojit navíc jedno čidlo na konci 30m kabelu. Pokud jsem ale připojil i modrý (návrat), zase spadlo.
Test s 1kohm pullup
Poté jsem nahradil pullup odpor 4,7kohm -> 1 kohm a od té chvíle fungovalo bez problémů. Připojil jsem další čidlo na breadboardu na vracející se modrý na 30m kabelu a pak ještě jedno na breadbordu, kde jsem „prodloužil drát“ použitím páru hnědobílá / hnědá. Tato konfigurace je na schématu.
- na 0m 2 senzory na breadboard (2 senzory vpravo nahoře)
- na 10m 3 senzory na 1m kabelech (vlevo dole – v nákresu je jeden)
- na 20m 1 senzor na breadboard
- na 50m 1 senzor na 1m kabelu
- na 80m 1 senzor na breadboard
- na 140m 1 senzor na breadbord
Co se týká napájení a země, ty neřetězím, ale propojuji z nejbližšího místa, tedy reálně jsem netestoval vliv délky napájení a země, pokud by skutečně byla trasa 140m. Nicméně na 5V jsem naměřil proud pod 1mA. Cat5e má odpor na 100m drátu ~ 10 ohm (0,22mm2 Cu) tedy úbytek napětí by měl být někde okolo 0,01V na 100m kabelu, což by neměl být žádný problém (reálně když použiju 2 kabey pro plus 5V a mínus, tak ještě dělím odpor zhruba na polovinu). Netuším ale samozřejmě jemnější nuance – beru to selským rozumem a vzorečky ze základky.
V této konfiguraci všecny senzory fungovaly.
Popravdě nevím, proč je všude primárně doporučovaný pullup 4,7kOhm, když s 1kOhm to vypdá, že funguje lépe. Jestli je to jen kvůli úspoře energie, tak je to trochu hloupé a v návodech by bylo vhodné uvádět, že pro větší než malé instalace je lepší menší odpor. Já jsem si bohužel napájel 4,7kOhm, naštěstí mám ale odpor „na vrchu“ desky, takže pokud zjistím, že mám problém, prostě paralelně připojím ještě menší odpor.
Test 1 – závěr
Doporučení z testu tedy jsou
- pokud pájíte spoj a plánujete více čidel / delší trasy tak nepoužívat natvrdo odpor 4,7kOhm ale buď dopředu vyzkoušet, nebo lépe už bych dneska použil místo odporu trimr 5kOhm.
- používat i napájení a to asi lépe 5V (ale pokud nepoužijete 5V přímo z RPi, tak pozor na některé 5V zdroje, které mají při nízkých odběrech vyšší napětí než 5V).
- pokud máte vícežilové kabely (ověřeno s Cat5e UTP) do nedoporučované hvězdy, lze použít workaround, kdy po jednom kabelu vedete signál tam a po druhém zpátky, čímž de fakto z topologie hvězda uděláte lineární topologii.
owfs / owserver
owfs je sada aplikací pro práci s 1-wire pro mnoho různých systémů včetně raspberry pi.
Rozsáhlá dokumentace – oficiální stránky k owfs je zde, zde a starší site zde.
Součástí balíku owfs jsou 4 programy. Všechny jsou na Raspbianu spouštěné po instalaci jako služby. Jde o
- owserver – otevře socket na určeném portu (default 4304) a na něm komunikuje a lze se tam dotazovat na nalezená zařízení. Lze se dotazovat i vzdáleně z jiného compu. Všechny 3 následující programy využívají pro svou funkci owserver. owserver jako zdroj také používá aktuální 1-wire integrace do hass.io.
- owfs – vytváří virtuální filesystem (defaultně v /mnt/1wire/), kam periodicky zapisuje stavy nalezených zařízení. Tedy je to něco podobného jako základní řešení pro onewire na RPi (to pracuje nad /sys/bus/w1/devices/). Nepoužívám a nezkoušel jsem.
- owhttd – web server pro zobrazování stavu. Nepoužívám a nezkoušel jsem.
- owftpd – ftp server. Nepoužívám a nezkoušel jsem.
Instalace owfs
sudo apt-get install owfs
Kontrola instalace
eoj@somecomp:~ $ sudo apt show owfs Package: owfs Version: 3.2p4+dfsg1-4.1 Priority: optional Section: electronics Maintainer: Vincent Danjean <vdanjean@debian.org> Installed-Size: 21.5 kB Depends: owfs-fuse (>= 3.2p4+dfsg1-4.1), owserver (>= 3.2p4+dfsg1-4.1), owhttpd (>= 3.2p4+dfsg1-4.1), owftpd (>= 3.2p4+dfsg1-4.1) Suggests: owfs-doc Homepage: http://owfs.org/ Download-Size: 6012 B APT-Manual-Installed: yes APT-Sources: http://deb.debian.org/debian bookworm/main arm64 Packages Description: Dallas 1-wire support The 1-Wire bus is a cheap low-speed bus for devices like weather sensors, access control, etc. It can be attached to your system via serial, USB, I2C, and other interfaces. . This package is a metapackage depending on various other OWFS packages. Installing this package gets you a FUSE daemon, server arbitrates access to the bus from multiple client processes, small ftp and webserver. eoj@somecomp:~ $ ps -A | grep ow 466 ? 00:00:03 owftpd 467 ? 00:00:00 owserver 533 ? 00:00:00 owfs 542 ? 00:00:00 owhttpd
Po instalaci balíku se pustili všechny 4 programy jako služba. Můžeme vypsat stav služby – například pro owserver (pro ostatní je command stejný, jen se mění jméno).
eoj@somecomp:~$ systemctl status owserver.service ● owserver.service - Backend server for 1-wire control Loaded: loaded (/lib/systemd/system/owserver.service; enabled; preset: enabled) Active: active (running) since Fri 2024-02-02 22:27:19 CET; 5min ago TriggeredBy: ○ owserver.socket Docs: man:owserver(1) Main PID: 5038 (owserver) Tasks: 3 (limit: 1571) CPU: 57ms CGroup: /system.slice/owserver.service └─5038 /usr/bin/owserver --foreground -c /etc/owfs.conf Feb 02 22:27:19 somecomp systemd[1]: Starting owserver.service - Backend server for 1-wire control... Feb 02 22:27:19 somecomp systemd[1]: Started owserver.service - Backend server for 1-wire control.
Jeden návod pro zprovoznění owfs uváděl na začátku potřebu před instalací owfs vytvořit v /etc/modprobe.d/ soubor, kde se zakáží (blacklist) 3 moduly, které kolidují s funkcí owfs – jména viz níže. Toto u mne (Raspbian 12) nebylo potřeba, jelikož si owfs při instalaci tento soubor sám vytvořil. Jmenuje se /etc/modprobe.d/owfs-common.conf. Můžete zkontrolovat, že ho máte.
cat /etc/modprobe.d/owfs-common.conf blacklist ds9490r blacklist ds2490 blacklist wire
Nastavení owfs
Nastavení je v /etc/owfs.conf
V konfiguraci je defaultně odkomentovaný řádek „server: FAKE = DS18S20,DS2405“. To se hodí pro testování serveru, kdy pak emuluje tyto 2 senzory. Pokud tedy žádné senzory nemáte, dá se takto otestovat owserver a ukáží se i v homeassistantu.
Default example konfiguraci si pro jistotu odzálohujeme a pak editujeme.
sudo cp /etc/owfs.conf /etc/owfs.conf.example sudo mcedit /etc/owfs.conf
Pro základní konfiguraci (senzor na GPIO4) je nastavení zdroje „server: w1 = all“. Toto nastavení bohužel v příkladu (default konfiguraci) ani v manuálech není, takže to zabralo chvilku hledání. Moje konfigurace s popisem jednotlivých nastavení vypadá následovně. Používám jen owserver, takže jsem neřešil nastavení pro owfs, owhttpd ani owftpd.
# Eoj'z configuration file for the OWFS # This is the main OWFS configuration file. You should read the # owfs.conf(5) manual page in order to understand the options listed # here. ######################## SOURCES ######################## # v teto sekci se nachazi nastaveni zdroju - tedy odkud nacitame data ### Zdroj pro vsechny krom owserver je owserver # nasledujici nastaveni rika ze owfs, owhttpd a owftd pouzivaji # jako server owserver bezici na lokale na urcenem portu # tedy nesahaji primo na HW # vykricnik rika ze nastaveni neplati pro owserver (a plati pro vsechny ostatni) # jelikoz pouzivam jen owserver, neni pro mne dulezite, ale nechavam zde ! server: server = localhost:4304 # USB device: DS9490 #server: usb = all # Serial port: DS9097 #server: device = /dev/ttyS1 # w1 bus directly on GPIO (GPIO4 default) server: w1 = all # w1 on I2C #server: i2c = /dev/i2c-0:ALL # nasledujici nastaveni umoznuje aby server nacital data ze serveru na jine masine / portu #server: server = 10.193.42.11:3131 # Fake zarizeni pro testovani #server: FAKE = DS18S20,DS2405 ######################### nastaveni pro OWFS ########################## # #mountpoint = /mnt/1wire #allow_other # ####################### nastaveni pro OWHTTPD ######################### #http: port = 2121 ####################### nastaveni pro OWFTPD ########################## #ftp: port = 2120 ####################### nastaveni OWSERVER ######################## ### nastaveni portu na kterem posloucha owserver # pokud je v nastaveni portu pred portem localhost: je owserver pristupny pouze z localhostu server: port = localhost:4304 # s nasledujicim nastavenim muzeme na owserver pristupovat i vzdalene po siti # vhodne na firewallu nastavit omezeni pristupu #server: port = 4304
Základní popis možných parametrů a syntaxe konfiguračního souboru je v manpage owfs.conf.
Vzdálený přístup k owserver
Tohle mi také zabralo trochu času, protože v manpage k owfs.conf toto není popsáno (je možné, že je tato syntaxe localhost:port v definici portu pro omezení na localhost je nějaké obecnější chování na linuxu, ale nepodařilo se mi k tomu víc dohledat).
Pokud je v konfiguraci „server: port = localhost:4304“ tak je povolen přístup jen z localhostu, pokud změním na „server: port = 4304“ lze se k owserveru připojit i po síti z jakékoliv IP adresy.
eoj@somecomp:~ $ sudo netstat -pln | grep owserver tcp6 0 0 ::1:4304 :::* LISTEN 14445/owserver eoj@somecomp:~ $ sudo mcedit /etc/owfs.conf # zmeneno zmazan localhost pred cislem portu eoj@mccoy:~ $ sudo netstat -pln | grep owserver tcp 0 0 0.0.0.0:4304 0.0.0.0:* LISTEN 14463/owserver
Testování připojení je možné telnetem (pokud po připojení k serveru nic nenapíšete, tak připjení vyprší po cca 10s). Pokud běží owserver měli byste mít možnost se připojit. V default nastavení je to možné jen ze stejného počítače.
telnet localhost 4304 Trying ::1... Connected to localhost. Escape character is '^]'.
Připojení ze vzdáleného počítače ale nebude možné.
telnet x.x.x.x 4304 Trying x.x.x.x... telnet: Unable to connect to remote host: Connection refused
Lokální přístup k owserver přes 127.0.0.1
Pozor na localhost vs 127.0.0.1 – u mne jak je vidět v netstat výše, pokud je zadáno localhost, tak owserver poslouchá jen na IPv6 (tcp6) a pak pokus o připojení na 127.0.0.1 což je IPv4 nefunguje.Níže je pokus o připojení na localhost na IPv4 (neúspěšný) a pak na IPv6 (úspěšný).
telnet 127.0.0.1 4304 Trying 127.0.0.1... telnet: Unable to connect to remote host: Connection refused telnet ::1 4304 Trying ::1... Connected to ::1. Escape character is '^]'.
Toto chování může způsobit problém s fungováním některých klientů používajících owserver, kteří by používali 127.0.0.1 místo localhost. Při problémech s připojením doporučuji zkusit upravit definici portu v konfiguraci na „server: port = 4304“ a vyzkoušení s touto konfigurací.
Zabezpečení při otevření portu
TODO – pokud otevřeme port owserveru do sítě, je vhodné nějak zabezpečit. Já použiji firewall pro omezení přístupu na počítač, na kterém mi běží homeassistant.
Zákaz nepoužívaných služeb
Po úpravě konfiguračních souborů u mne běží 2 služby – owserver a owfs, ostatní mají FAILED.
sudo systemctl status ow* ● owfs.service - 1-wire filesystem FUSE mount Loaded: loaded (/lib/systemd/system/owfs.service; enabled; preset: enabled) Active: active (running) since Thu 2024-02-01 22:04:28 CET; 3 days ago ... × owhttpd.service - Tiny webserver for 1-wire control Loaded: loaded (/lib/systemd/system/owhttpd.service; enabled; preset: enabled) Active: failed (Result: signal) since Fri 2024-02-02 16:02:20 CET; 2 days ago ... × owserver.socket - Listening socket for owserver Loaded: loaded (/lib/systemd/system/owserver.socket; enabled; preset: enabled) Active: failed (Result: resources) since Fri 2024-02-02 22:01:09 CET; 2 days ago ... ● owserver.service - Backend server for 1-wire control Loaded: loaded (/lib/systemd/system/owserver.service; enabled; preset: enabled) Active: active (running) since Mon 2024-02-05 10:23:20 CET; 1h 31min ago ... × owftpd.service - Anonymous FTP server for 1-wire access Loaded: loaded (/lib/systemd/system/owftpd.service; enabled; preset: enabled) Active: failed (Result: exit-code) since Fri 2024-02-02 22:12:01 CET; 2 days ago ...
Jelikož využívám jen owserver, rozhodl jsem se ostatní služby zakázat.
sudo systemctl disable owfs sudo systemctl disable owhttpd sudo systemctl disable owftpd
Po restartu vypdá výpis takto
sudo systemctl status ow* ● owserver.service - Backend server for 1-wire control Loaded: loaded (/lib/systemd/system/owserver.service; enabled; preset: enabled) Active: active (running) since Mon 2024-02-05 13:16:43 CET; 1min 38s ago TriggeredBy: ● owserver.socket Docs: man:owserver(1) Main PID: 469 (owserver) Tasks: 4 (limit: 765) CPU: 138ms CGroup: /system.slice/owserver.service └─469 /usr/bin/owserver --foreground -c /etc/owfs.conf Feb 05 13:16:42 dixie systemd[1]: Starting owserver.service - Backend server for 1-wire control... Feb 05 13:16:43 dixie owserver[469]: DEFAULT: ow_opt.c:(780) systemd mode -- ignore foreground request Feb 05 13:16:43 dixie owserver[469]: DEFAULT: ow_opt.c:(670) systemd mode -- ignore 'p' option Feb 05 13:16:43 dixie systemd[1]: Started owserver.service - Backend server for 1-wire control. ● owserver.socket - Listening socket for owserver Loaded: loaded (/lib/systemd/system/owserver.socket; enabled; preset: enabled) Active: active (running) since Mon 2024-02-05 13:16:42 CET; 1min 39s ago Triggers: ● owserver.service Docs: man:owserver(1) Listen: [::]:4304 (Stream) Tasks: 0 (limit: 765) CPU: 3ms CGroup: /system.slice/owserver.socket Feb 05 13:16:42 dixie systemd[1]: Listening on owserver.socket - Listening socket for owserver.
A ostatní služby se nenastartovali – například owhttpd
eoj@dixie:~ $ sudo systemctl status owhttpd ○ owhttpd.service - Tiny webserver for 1-wire control Loaded: loaded (/lib/systemd/system/owhttpd.service; disabled; preset: enabled) Active: inactive (dead) Docs: man:owhttpd(1)
Ten owserver.socket přesně nevím co je – asi služba co spustí owserver, pokud zdetekuje připojení na daném portu? Když jsem si hrál s nastavením owserveru, tak někdy skončilo ve failed stavu, ale po restartu bylo zase active. I pokud byla tato složba failed, ale owserver.service active, tak vyčítání teploty fungovalo OK.
Více 1-wire busů a owfs
Není potřeba nic měnit, po úpravě konfigurace /boot/firmware/config.txt owserver začal zobrazovat senzory na obou pinech.
Při testování jsem zkoušel připojit druhý 1-wire bus na GPIO pin 17. Poté co jsem do /boot/firmware/config.txt přidal řádek „dtoverlay=w1-gpio,gpiopin=17“ a restartoval, tak se senzor připojený na tento pin ukázal v „/sys/bus/w1/devices“ a stejně tak ho zdetekoval owserver (po reloadu v homeassistantu se senzor na pinu 17 zobrazil).
Ladění owserver
Pokud vám owserver stále nefunguje, níže jsou některé články k tématu, které jsem během ladění našel a zaujali mne. Většina je v angličtině.
Pro ladění je vhodné vypnout službu a pouštět si owserver přímo z command line.
Další zdroje k tématu pro debugování: Pomoc owserver, run OWFS on Raspberry Pi with GPIO only, OWFS and Pi GPIO, stránka owfs, Remote access to owserver, Owserver instalace přímo v hass.io, Příspěvek o instalaci owfs na fóru hass.io