Arduino Umweltsensoren

Aktuell erweitere ich mein Sensor Netzwerk. Als Basis dienen Arduinos welche über KNX angebunden sind.

Als Sensor habe ich mich für einen DHT22 entschieden. Er ist billig, sehr genau und es gibt schon eine fertige Arduino Bibliothek, so daß sich das Auslesen der Temperatur und Luftfeuchtigkeitswerte sehr einfach gestaltet. Die dazugehörige Arduino Bibliothek lässt sich bequem aus der Android IDE heraus nachinstallieren.

Schaltplan zur Anbindung des DHT22 Sensors an das Arduino Mini Pro Board

Arduino
DHT22
GND
GND (PIN 4)
Digital Input (Pin 4)
Data (PIN 2)
VCC
VCC (PIN 2)

Genauigkeit und Kalibrierung

Was die Genauigkeit angeht. Es musst immer kalibriert werden. Es gibt keine Sensoren die nicht kalibriert werden müssen. Selbst wenn sie vor kalibriert sind müssen sie spätestens nach 1-2 Jahr wieder neu kalibriert werden da sich im Laufe der Zeit die Eigenschaften der Bauteile leicht ändern. Es sollte auch so nah wie möglich im späterem Wertebereich kalibrieren. Als Referenz zum Temperatur kalibrieren habe ich mir einen GTH 175 PT von Greisinger geholt. Er "soll" sehr genau sein.

Die Luftfeuchtigkeit werde ich über eine Sättigungsmessung durchführen. Hierzu einfach ein Glas mit Kochsalz füllen. Etwas Wasser drauf. Zusammen mit dem Sensor in eine Tüte stellen und Luftdicht verschliessen. Nach 24 bis 48 Stunden sollte sich bei einer Umgebungstemperatur von ca 20°C eine Luftfeuchtigkeit von 75.4% einstellen.

Im Schnitt lag meine Abweichung im Vergleich zum Referenzpunkt, bei 13 von 14 Sensoren, zwischen -0.1 °C und +0.1 °C. Ein Sensor hatte eine Abweichung von +0.3 °C. Also keine schlechten Werte. Die Luftfeuchtigkeit lag im Schnitt zwischen 0% und 8% daneben.

Stromverbrauch

Mode
Verbrauch
Deep Sleep
1.20mA (3,63mW)
Messung (min)
4.73mA (15.60mW)
Messung (max)
7,50mA (24.75mW)

Hier lässt sich noch etwas rausholen in dem man:
1. Die Steuerung der "Progress" LED im Sourcecode deaktiviert.
2. Die Power LED deaktiviert. Hierfür muss man allerdings die Leitung auf der Leiterbahn mit einem Cuttermesser durchtrennen.

Einbau


Im letzten Bild erkennt man gut den zusätzlichen Lüftungsschlitz um unterem Rand

Arduino Sourcecode

#include <Arduino.h>

#include <avr/sleep.h>
#include <KnxTpUart.h>
#include "DHT.h"

#define DHTPIN 4     
#define DHTTYPE DHT22 //DHT11, DHT21, DHT22

// Room: Livingroom, KNX address: 1.1.49, GroupTemperature: 0/7/1, GroupHumidity: 0/7/2
const String deviceAddress           = "1.1.49";
const String groupTemperatureAddress = "0/7/1";
const String groupHumidityAddress    = "0/7/2";

const int interval = 60;
const int ledpin = 13;

DHT dht(DHTPIN, DHTTYPE);

KnxTpUart knx(&Serial, deviceAddress);

void setup()
{
  Serial.begin(19200);
  UCSR0C = UCSR0C | B00100000; // Even Parity
  
  knx.uartReset();
  
  dht.begin();

  watchdogOn(); // Enable watchdog timer.

  // The following saves some extra power by disabling some peripherals I am not using.
  ADCSRA = ADCSRA & B01111111; // Disable ADC, ADEN bit7 to 0
  ACSR = B10000000; // Disable analog comparator, ACD bit7 to 1
  DIDR0 = DIDR0 | B00111111; // Disable digitale inputbuffer, set analoge input pins 0-5 to 1
}

void loop()
{
  float temperature = dht.readTemperature(); // Read temperature
  knx.groupWrite2ByteFloat(groupTemperatureAddress, temperature);

  delay(5000);

  float humidity = dht.readHumidity(); // Read humidity
  knx.groupWrite2ByteFloat(groupHumidityAddress, humidity);

  digitalWrite(ledpin, HIGH); // Set LED State to visualize progess  
  delay(1000);
  digitalWrite(ledpin, LOW);

  pwrDown(interval - 6); // Shutdown ATmega328 for "interval" seconds;
}

void pwrDown(int seconds)
{
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set deepest sleep mode PWR_DOWN
  for(int i=0; i < seconds; i++)
  {
    sleep_enable(); // Enable sleep mode
    sleep_mode(); // Start sleep mode
    sleep_disable(); // Disable sleep mode 
  }
}

void watchdogOn()
{
  MCUSR = MCUSR & B11110111; // Disable reset flag, WDRF bit3 of MCUSR.
  WDTCSR = WDTCSR | B00011000; // Set bit 3+4 to be able to set prescaler later
  WDTCSR = B00000110; // Set watchdog prescaler to 128K > is round about 1 second
  WDTCSR = WDTCSR | B01000000; // Enable watchdog interrupt
  MCUSR = MCUSR & B11110111;
}

ISR(WDT_vect)
{
  //sleepcounter ++; // count sleepcycles
}