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:
- VCC — napajanje 3,3 V ali 5 V (odvisno od modula)
- DATA — podatkovna nožica na poljuben digitalni pin (v primeru uporabimo pin 2)
- 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
- 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.
- Prehitro branje: DHT11 potrebuje vsaj 1 sekundo, DHT22 vsaj 2 sekundi med branjem. Prehitro zaporedno branje povzroča NaN vrednosti.
- Manjkajoč pull-up upor: Pri golem senzorju brez vgrajenega upora 10 kΩ
- 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
- 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
- Manjkajoč upor 4,7 kΩ: Najpogostejša napaka — brez pull-up upora senzor ni dosegljiv
- Vrednost 85 °C: To je privzeta vrednost ob vklopu. Pomeni, da branje ni uspelo — ponavadi zaradi premajhnega zamika med request in get
- Zamenjana napajalna nožica: Pri navadnem TO-92 ohišju si pozorno poglejte podatkovni list — nožice so drugače kot pri drugih komponentah
- 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
- 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.