Blog o spletnem programiranju in elektroniki
💬 👤
back Nazaj na blog
Arduino & Elektronika

Kako pravilno brati senzorje: DHT11, DHT22, DS18B20 in druge pasti

Temperaturni in vlažnostni senzorji so med najpogosteje uporabljenimi komponentami v Arduino projektih — vremenske postaje, avtomatsko zalivanje, inkubatorji, pametni dom. A medtem ko je priključitev senzorja preprosta, je branje vrednosti polno pasti: napačne knjižnice, senzorji, ki "zmrznejo", popačene vrednosti in tipične napake priključitve. V tem članku si bomo ogledali tri najbolj priljubljene senzorje in kako jih prebrati pravilno.

Pregled senzorjev

Preden se lotimo kode, poglejmo, kaj ponujajo posamezni senzorji:

Lastnost DHT11 DHT22 DS18B20
Temperatura 0 do 50 °C (±2 °C) -40 do 80 °C (±0,5 °C) -55 do 125 °C (±0,5 °C)
Vlažnost 20–80 % (±5 %) 0–100 % (±2 %) ne meri
Protokol enoredni, lasten enoredni, lasten 1-Wire
Najmanjši interval med branjem 1 sekunda 2 sekundi 750 ms (12-bitna ločljivost)
Cena najnižja srednja nizka

Kratka izbira: za sobne razmere in učenje zadostuje DHT11. Za resnejše projekte izberite DHT22, ki meri tudi pod ničlo. Za čisto temperaturo (tudi v vodi, na daljavo po enem kablu, več senzorjev na en pin) je DS18B20 najboljša izbira.

DHT11 in DHT22: priključitev

Oba senzorja imata (pri 3-pin modulu) tri nožice:

  1. VCC — napajanje 3,3 V ali 5 V (odvisno od modula)
  2. DATA — podatkovna nožica na poljuben digitalni pin (v primeru uporabimo pin 2)
  3. GND — masa

POMEMBNO: Mnogi DHT moduli že vsebujejo vgrajeni upor (pull-up) na podatkovni nožici. Če uporabljate "prazen" 4-nožni senzor, morate med DATA in VCC priključiti upor 10 kΩ. Brez njega senzor ne bo deloval ali bo vračal naključne vrednosti.

Branje DHT senzorjev

Za branje uporabimo knjižnico Adafruit DHT sensor library (skupaj z odvisnostjo Adafruit Unified Sensor):

// Branje temperature in vlažnosti s senzorjem DHT22
// Knjižnica: Adafruit DHT sensor library

#include <DHT.h>

#define DHTPIN 2 // podatkovni pin
#define DHTTYPE DHT22 // DHT11 ali DHT22

DHT dht(DHTPIN, DHTTYPE);

void setup() {
    Serial.begin(9600);
    dht.begin();
}

void loop() {
    // branje traja približno 250 ms
    float temperatura = dht.readTemperature();
    float vlaznost = dht.readHumidity();

    // preveri, ali branje uspelo
    if (isnan(temperatura) || isnan(vlaznost)) {
        Serial.println("Napaka pri branju senzorja!");
    } else {
        Serial.print("Temperatura: ");
        Serial.print(temperatura);
        Serial.print(" °C, Vlažnost: ");
        Serial.print(vlaznost);
        Serial.println(" %");
    }

    delay(2000);  // DHT22 največ eno branje na 2 sekundi!
}

Najpogostejše težave z DHT senzorji

  1. Napačen tip v kodi: Če v kodi piše DHT11, priključen pa je DHT22 (ali obratno), branje ne bo uspelo ali bo popačeno.
  2. Prehitro branje: DHT11 potrebuje vsaj 1 sekundo, DHT22 vsaj 2 sekundi med branjem. Prehitro zaporedno branje povzroča NaN vrednosti.
  3. Manjkajoč pull-up upor: Pri golem senzorju brez vgrajenega upora 10 kΩ
  4. Predolga žica: Pri žici daljši od približno 1 meter pri 5 V (in še krajši pri 3,3 V) postane signal nestabilen
  5. Nizka kakovost senzorja: Tržišče je polno ponaredkov DHT11/DHT22, ki vračajo nestabilne vrednosti

DS18B20: več senzorjev na en pin

DS18B20 je digitalni temperaturni senzor s protokolom 1-Wire. Njegova največja prednost: na en sam podatkovni pin lahko priključimo več senzorjev hkrati — vsak ima svojo unikatno 64-bitno naslovno kodo, po kateri ga nastavimo.

Priključitev: VCC na 5 V, GND na ozemljitev, DATA na digitalni pin (v primeru pin 2) in upor 4,7 kΩ med DATA in VCC. Ta upor je pri DS18B20 obvezen!

Branje DS18B20

Potrebujemo knjižnici OneWire in DallasTemperature:

// Branje temperature s senzorjem DS18B20
// Knjižnici: OneWire, DallasTemperature

#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2 // podatkovni pin

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature senzorji(&oneWire);

void setup() {
    Serial.begin(9600);
    senzorji.begin();
}

void loop() {
    senzorji.requestTemperatures(); // zahtevaj meritve

    // prvi senzor na vodilu (indeks 0)
    float temperatura = senzorji.getTempCByIndex(0);

    if (temperatura == DEVICE_DISCONNECTED_C) {
        Serial.println("Napaka: senzor ni povezan!");
    } else {
        Serial.print("Temperatura: ");
        Serial.print(temperatura);
        Serial.println(" °C");
    }

    delay(1000);
}

Za branje več senzorjev na istem pinu spremenimo indeks: getTempCByIndex(1) vrne drugi senzor in tako naprej. Če želimo naslove izpisati (npr. za shranjevanje, kateri senzor je kje), uporabimo funkcijo senzorji.getAddress(adresa, i).

Najpogostejše težave z DS18B20

  1. Manjkajoč upor 4,7 kΩ: Najpogostejša napaka — brez pull-up upora senzor ni dosegljiv
  2. Vrednost 85 °C: To je privzeta vrednost ob vklopu. Pomeni, da branje ni uspelo — ponavadi zaradi premajhnega zamika med request in get
  3. Zamenjana napajalna nožica: Pri navadnem TO-92 ohišju si pozorno poglejte podatkovni list — nožice so drugače kot pri drugih komponentah
  4. Parazitno napajanje: DS18B20 podpira napajanje prek podatkovne nožice (parasite mode), ki pa je manj zanesljivo. Za začetek uporabljajte normalno napajanje na 3 nožice
  5. Predolgi kabli: Pri daljših vodilih (več metrov) je priporočena nižja vrednost pull-up upora

Glajenje vrednosti (averaging)

Vsi trije senzorji občasno oddajajo popačeno vrednost — konico zaradi električnega šuma ali motenj. Programerji jo preprosto odpravijo z večkratnim odčitavanjem in povprečenjem:

// Povprečje iz 5 meritev
float preberiT(const int STEVILO = 5) {

    float vsota = 0;
    int uspesnih = 0;

    for (int i = 0; i < STEVILO; i++) {

        float t = dht.readTemperature();

        if (!isnan(t)) {
            vsota += t;
            uspesnih++;
        }

        delay(2200); // spoštuj najmanjši interval!
    }

    if (uspesnih == 0) {
        return NAN; // nobena meritev ni uspela
    }

    return vsota / uspesnih;
}

Še boljša rešitev za odstranjevanje konic je mediana — meritve razvrstimo po velikosti in vzamemo srednjo vrednost. Konice (nenadni ekstremi) pokvarijo povprečje, vendar mediana ostane stabilna.

Napake, ki jih NE smemo delati

Napaka Zakaj je slaba Pravilno
delay(100) v zanki za DHT Branje spodleti, ker senzor potrebuje vsaj 1–2 sekundi delay(2000) za DHT22, delay(1000) za DHT11
Ne preverjati isnan() vrednosti NaN se razprši med izračuni in obdelavo Vedno preveri isnan() pred uporabo vrednosti
Zanašati se na eno samo meritev Ena sama konica pokvari celotno odločitev Več meritev + povprečje ali mediana
3,3 V pri dolgi žici Signal oslabljen, vrednosti naključne 5 V in čim krajša žica
DHT22 za merjenje vlažnosti v vodi Senzor ni vodotesen, lahko se uniči Za vodo uporabite DS18B20 v zaprti sondi

Zaključek

Pravilno branje senzorjev ni samo priklop in branje – gre za spoštovanje intervalov med odčitki, preverjanje neveljavnih vrednosti, uporabo pravih uporov in zmerno zaupanje v poceni klone. Tisti, ki upoštevajo te osnove, bodo imeli vremensko postajo ali namakalni sistem, ki bo nemoteno deloval več mesecev. Tisti, ki tega ne storijo, bodo iskali napake v programski opremi, medtem ko je težava v enem samem manjkajočem uporniku.

back Nazaj na blog