Raspberry Pi

Raspberry Pi DS18B20 MQTT: Birden Fazla 1-Wire Sıcaklık Probunu Yayınlayın

Raspberry Pi'de 1-Wire'ı etkinleştirin, birden fazla DS18B20 sıcaklık probunu tek bir GPIO pinine bağlayın, ek kütüphane olmadan Python ile okuyun ve adlandırılmış, doğrulanmış ölçümleri MQTT üzerinden yayınlayın.

Bir Raspberry Pi DS18B20 MQTT projesinde tek bir 1-Wire hattı üzerinden Raspberry Pi'ye bağlı ve ölçümleri buluta gönderen birkaç su geçirmez DS18B20 sıcaklık probu
Bunu kendi MQTT broker’ınızda çalıştırınFree planla özel, yönetilen bir MQTT broker alın ve hazır kod örnekleriyle başlayın.
Ücretsiz deneyin Kod örnekleri Kart gerekmez

Bir Raspberry Pi DS18B20 MQTT kurulumu, aynı anda birden fazla noktada sıcaklık ölçmenin en sağlam yoludur: dondurucu ve buzdolabı, gidiş ve dönüş boruları, bir akvaryum, bir fermantasyon tankı veya bir sunucu kabini. Bu eğitimde 1-Wire hattını etkinleştirecek, birden fazla su geçirmez probu tek bir GPIO pinine bağlayacak, yalnızca çekirdek sürücüsünü kullanarak Python ile okuyacak ve adlandırılmış, doğrulanmış ölçümleri MQTT üzerinden yayınlayacaksınız.

DS18B20 Neden Harika Bir Seçim?

DS18B20 dijital bir sensördür; bu nedenle kablo uzunluğu ve elektriksel gürültü onu analog sensörlerden çok daha az etkiler. Her probun fabrikada yazılmış benzersiz bir 64 bitlik seri numarası vardır; bu da çok sayıda probun tek bir veri hattını paylaşmasına olanak tanır. Su geçirmez sürümler, uzun bir kablo üzerinde paslanmaz çelik bir kılıf içinde gelir ve sıvılarda veya dış ortamda kullanıma hazırdır. Doğruluk normal aralıkta yaklaşık yarım derecedir ve çözünürlük 0,0625 °C'ye kadar ayarlanabilir.

En iyisi de Raspberry Pi OS'un bunun için bir çekirdek sürücüsü içermesidir. Sensörleri okumak için herhangi bir Python kütüphanesine ihtiyacınız yoktur; dosya olarak görünürler.

Bir veya Birden Fazla Probu Bağlamak

Tüm problar aynı üç kabloya paralel olarak bağlanır:

DS18B20 kablosu (su geçirmez prob) Raspberry Pi
Kırmızı: VDD 3,3 V (fiziksel pin 1)
Siyah: GND GND (fiziksel pin 6)
Sarı: DATA GPIO4 (fiziksel pin 7)

DATA ile 3,3 V arasına bir adet 4,7 k direnç ekleyin. Bu tek pull-up tüm hatta hizmet eder; her prob için ayrı bir tane eklemeyin. Birden fazla probla daha az güvenilir olan parazitik besleme yerine gösterildiği gibi üç kablolu (beslemeli) modu kullanın. Uzun kablo hatlarında çok sayıda dallı yıldız düzeni 1-Wire için en zor topolojidir; kısa saplamalı tek bir hat en iyi sonucu verir ve uzun hatlarda 2,2 k gibi daha düşük bir pull-up yardımcı olabilir.

1-Wire'ı Etkinleştirmek

Hattı raspi-config ile etkinleştirin veya overlay'i kendiniz ekleyin:

sudo raspi-config nonint do_onewire 0
# or, equivalently, add this line to /boot/firmware/config.txt:
# dtoverlay=w1-gpio,gpiopin=4
sudo reboot

Yeniden başlatmadan sonra algılanan probları listeleyin:

ls /sys/bus/w1/devices/
cat /sys/bus/w1/devices/28-*/w1_slave

Her prob 28- ile başlayan bir dizin olarak görünür. w1_slave dosyası iki satır içerir: CRC kontrolü başarılıysa ilk satır YES ile biter, ikinci satır ise t= ve ardından derecenin binde biri cinsinden sıcaklıkla biter; örneğin 21,375 °C için t=21375. Raspberry Pi yapılandırma dokümantasyonu 1-Wire overlay seçeneklerini açıklar.

Problarınızı Adlandırmak

28-3c01d0752a8b gibi seri numaraları bir panoda hiçbir anlam ifade etmez. Her seri numarasını MQTT topic'inin bir parçası olacak kısa bir ada eşleyen bir probes.json dosyası oluşturun:

{
  "28-3c01d0752a8b": "freezer",
  "28-3c01d075f1e2": "fridge",
  "28-0316a2794bff": "outdoor"
}

Hangi probun hangisi olduğunu bulmak için birini elinizde ısıtın ve hangi ölçümün yükseldiğine bakın. Dosyada listelenmeyen problar yine de seri numaraları altında yayınlanır; böylece yeni eklenen bir prob asla sessizce kaybolmaz.

Topic Düzeni

Topic Payload Retained
connectmq/demo/b81f2d/house/temp/<name> {"celsius": 4.2, "ts": ...} Hayır
connectmq/demo/b81f2d/house/temp/all Tek bir JSON nesnesinde tüm problar Hayır
connectmq/demo/b81f2d/house/status online / offline Evet

Prob başına topic'ler, panolara ve tek bir değer üzerindeki alarm kurallarına uygundur; birleşik mesaj ise her aralıkta bir satır yazan kaydediciler için kullanışlıdır. b81f2d değerini kendi rastgele dizenizle değiştirin.

Raspberry Pi DS18B20 MQTT Betiği

ds18b20_mqtt.py olarak kaydedin:

#!/usr/bin/env python3
"""Read all DS18B20 probes on the 1-Wire bus and publish them to MQTT."""
import json
import os
import time
import uuid
from pathlib import Path

import paho.mqtt.client as mqtt

BROKER = os.getenv("MQTT_HOST", "broker.connectmq.com")
PORT = int(os.getenv("MQTT_PORT", "1883"))
USERNAME = os.getenv("MQTT_USERNAME")
PASSWORD = os.getenv("MQTT_PASSWORD")
CLIENT_ID = os.getenv("MQTT_CLIENT_ID", f"ds18b20-{uuid.uuid4().hex[:8]}")
PREFIX = os.getenv("MQTT_PREFIX", "connectmq/demo/b81f2d/house")
INTERVAL = int(os.getenv("PUBLISH_INTERVAL", "60"))
W1_DIR = Path("/sys/bus/w1/devices")
NAMES_FILE = Path(os.getenv("PROBES_FILE", "probes.json"))


def load_names():
    try:
        return json.loads(NAMES_FILE.read_text())
    except (OSError, json.JSONDecodeError):
        return {}


def read_probe(device: Path, retries: int = 3):
    """Return degrees Celsius, or None if the probe gives no valid reading."""
    for _ in range(retries):
        try:
            lines = (device / "w1_slave").read_text().strip().splitlines()
        except OSError:
            return None  # probe unplugged
        if len(lines) == 2 and lines[0].endswith("YES") and "t=" in lines[1]:
            millis = int(lines[1].split("t=")[1])
            if millis != 85000:  # 85.0 °C is the power-on reset value
                celsius = millis / 1000.0
                if -55.0 <= celsius <= 125.0:
                    return celsius
        time.sleep(0.2)
    return None


def on_connect(client, userdata, flags, reason_code, properties):
    if reason_code.is_failure:
        print(f"Connection refused: {reason_code}")
        return
    print(f"Connected as {CLIENT_ID}")
    client.publish(f"{PREFIX}/status", "online", qos=1, retain=True)


client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID)
client.on_connect = on_connect
client.will_set(f"{PREFIX}/status", "offline", qos=1, retain=True)
client.reconnect_delay_set(min_delay=1, max_delay=60)
if USERNAME:
    client.username_pw_set(USERNAME, PASSWORD)
if PORT == 8883:
    client.tls_set()
client.connect(BROKER, PORT, keepalive=60)
client.loop_start()

try:
    while True:
        started = time.monotonic()
        names = load_names()
        now = int(time.time())
        combined = {}
        for device in sorted(W1_DIR.glob("28-*")):
            name = names.get(device.name, device.name)
            celsius = read_probe(device)
            if celsius is None:
                combined[name] = None
                print(f"{name}: no valid reading")
                continue
            combined[name] = round(celsius, 2)
            payload = {"celsius": round(celsius, 2), "ts": now}
            client.publish(f"{PREFIX}/temp/{name}", json.dumps(payload), qos=1)
        client.publish(
            f"{PREFIX}/temp/all", json.dumps({"probes": combined, "ts": now}), qos=1
        )
        print(combined)
        time.sleep(max(0, INTERVAL - (time.monotonic() - started)))
except KeyboardInterrupt:
    pass
finally:
    client.publish(f"{PREFIX}/status", "offline", qos=1, retain=True).wait_for_publish(2)
    client.loop_stop()
    client.disconnect()

Herhangi bir sensör kütüphanesi gerekmez; tek bağımlılık paho-mqtt'dir:

mkdir -p ~/ds18b20-mqtt && cd ~/ds18b20-mqtt
python3 -m venv .venv && source .venv/bin/activate
pip install "paho-mqtt>=2.0"
python ds18b20_mqtt.py

Betik probes.json dosyasını her döngüde yeniden okur; böylece yeniden başlatmadan bir probu yeniden adlandırabilirsiniz. Eksik veya hatalı problar düşürülmek yerine birleşik mesajda null olarak raporlanır; bu da kopuk bir kabloyu panoda görünür kılar.

Klasik Tuzaklar

  1. Tam olarak 85,0 °C ölçümü: prob, bir dönüşümü tamamlamadan önce açılış varsayılan değerini döndürmüştür; genellikle zayıf besleme veya parazitik beslemeden kaynaklanır. Betik bu değeri atar.
  2. w1_slave ilk satırda NO gösteriyor: gürültü veya uzun bir kablo nedeniyle CRC başarısız olmuştur. Betik üç kereye kadar yeniden dener.
  3. Problar dizinde görünüp kayboluyor: gevşek bağlantılar veya aşırı yüklenmiş bir hat; lehim noktalarını ve pull-up değerini kontrol edin.
  4. Hiç 28- dizini yok: 1-Wire etkin değil, veri kablosu GPIO4'te değil veya pull-up eksik.
  5. Çok sayıda probla yavaş döngüler: her 12 bitlik dönüşüm yaklaşık dörtte üç saniyeye kadar sürer ve çekirdek probları art arda okur. Dolayısıyla on prob döngü başına birkaç saniye sürer; bu da 60 saniyelik bir aralıkta sorun değildir.

Hız İçin Çözünürlükten Feragat Etmek

Çoğu uygulamanın 0,0625 °C'lik adımlara ihtiyacı yoktur. Güncel çekirdekler her prob için bir resolution dosyası sunar; böylece çözünürlüğü düşürüp dönüşüm süresini kısaltabilirsiniz:

cat /sys/bus/w1/devices/28-3c01d0752a8b/resolution
echo 10 | sudo tee /sys/bus/w1/devices/28-3c01d0752a8b/resolution

10 bitte adım 0,25 °C olur ve her dönüşüm 12 bitlik sürenin küçük bir bölümünde tamamlanır; bu da bir hat çok sayıda prob taşıdığında veya daha hızlı güncellemeler istediğinizde işe yarar. Ayar probun geçici belleğinde tutulur; bu yüzden probun EEPROM'una da kaydetmediğiniz sürece bir güç döngüsünden sonra sıfırlanır. EEPROM'a yazmadan önce sürümünüz için çekirdeğin w1_therm dokümantasyonunu kontrol edin.

Ayrıca probun yalnızca ne kadar hassas olduğunu değil, nerede durduğunu da düşünün. Bir boruya bantlanmış bir prob, metal bir kelepçeyle sıkıca tutulup yalıtımla örtüldüğünde boruyu daha doğru ölçer. Bir dondurucudaki prob, yiyeceğin sıcaklığını öğrenmek istemiyorsanız donmuş bir pakete değmemeli, havada asılı durmalıdır.

Ölçümleri İzlemek

mosquitto_sub -h broker.connectmq.com -p 1883 -i watch-b81f2d \
  -t 'connectmq/demo/b81f2d/house/#' -v

Her dakika prob başına bir mesaj, ardından birleşik mesajı göreceksiniz. Genel MQTT test broker'ında bu topic'ler herkese görünür; bu yüzden test verileri ve rastgele bir önekle sınırlı kalın.

Sırada Ne Var?

Bir 1-Wire hattı kompakt bir düğüm için doğal bir seçimdir; betik bir Raspberry Pi Zero 2 W MQTT sensör düğümünde değişiklik yapılmadan çalışır. Nem de istiyorsanız aynı topic stilini kullanan Raspberry Pi DHT22 MQTT rehberiyle birleştirin. Uzun vadeli grafikler için Raspberry Pi Grafana ve InfluxDB yığını bu topic'lere Telegraf üzerinden abone olur ve aylarca geçmiş veri saklar.

Üretim Kurulumu

Dondurucu alarmları ve ısıtma izleme, özel ve şifreli bir bağlantıyı hak eder. ConnectMQ tam yönetilen bir MQTT hizmetidir: portalda bir broker oluşturun, ardından betiği TLS ile çalıştırın:

export MQTT_PORT=8883
export MQTT_USERNAME=YOUR_USERNAME
export MQTT_PASSWORD=YOUR_PASSWORD
export MQTT_CLIENT_ID=YOUR_CLIENT_ID
export MQTT_PREFIX=home/kitchen
python ds18b20_mqtt.py

ConnectMQ portalında home/kitchen/temp/freezer üzerindeki, örneğin -12 °C'nin üzeri için bir eşik alarm kuralı, alarm günlüğünde inceleyebileceğiniz bir alarm kaydeder. Elektrik kesintilerinden sonra yeniden başlaması için betiği bir systemd servisi olarak çalıştırın; şablon Raspberry Pi MQTT eğitiminde yer alıyor.

ConnectMQ ile Başlayın

Problarınızı panoların, kaydedicilerin ve alarm kurallarının her yerden erişebileceği bir buluttaki MQTT broker'a gönderin. Kredi kartı gerekmeden Serverless planda ücretsiz bir ConnectMQ broker oluşturun, otomatik oluşturulan kimlik bilgilerini ortamınıza yapıştırın ve 8883 portunda TLS üzerinden bağlanın.

Sık Sorulan Sorular

Bir Raspberry Pi pinine kaç DS18B20 probu bağlayabilirim?

Benzersiz seri numaraları sayesinde çok sayıda prob tek bir hattı paylaşabilir. Pratikte adres alanından önce kablo uzunluğu ve topoloji sizi sınırlar; iyi kablolanmış bir hatta birkaç adetten birkaç düzineye kadar prob gerçekçidir.

DS18B20'm neden 85 derece okuyor?

85,0 °C, sensörün açılıştan sonra ilk dönüşümünden önce tuttuğu değerdir. Genellikle bir besleme sorununa veya çok erken yapılmış bir okumaya işaret eder; bu değeri atın ve kablolamayı kontrol edin.

DS18B20'yi okumak için bir Python kütüphanesine ihtiyacım var mı?

Hayır. w1-gpio ve w1-therm çekirdek sürücüleri her probu /sys/bus/w1/devices içinde, düz Python'un okuyabileceği bir dosya olarak sunar.

1-Wire için farklı bir GPIO pini kullanabilir miyim?

Evet. /boot/firmware/config.txt dosyasında dtoverlay=w1-gpio,gpiopin=17 (veya başka bir pin) ayarlayın ve yeniden başlatın.

İlgili yazılar

RC522 Okuyucu ile Raspberry Pi RFID MQTT Erişim Kaydı

Bir RC522 RFID okuyucuyu Raspberry Pi'ye bağlayın, etiketleri Python ile okuyun, yerel bir izin listesiyle karşılaştırın ve her erişim denemesini kayıt araçlarının, panellerin ve uyarı araçlarının tüketebileceği bir MQTT olayı olarak yayınlayın.

6 dk okuma

Tüm yazılar →

Özel MQTT broker’ınız birkaç tık uzağınızda

Hesabınızı oluşturun, broker kimlik bilgilerinizi alın ve ilk cihazınızı bağlayın — kurulacak, yamalanacak ya da ölçeklendirilecek sunucu yok.