Home Navigationspfeil Arduino Navigationspfeil Luftfeuchte Sensor HH10D

Die Messung von Umweltparametern ist immer wieder ein beliebtes Thema beim Experimentieren mit Mikrocontrollern. In dieser kurzen Anleitung möchte ich mein vorgehen bei der Messung der relativen Luftfeuchte mit dem recht preiswerten Sensor der Firma Hope RF beschreiben.

Der Luftfeuchte Sensor HHD10

Bei diesem Sensor handelt es sich um einen kapazitiven Luftfeuchte Sensor der die Relative Feuchte im Bereich von 1 … 99% Messen kann. Leider ist dieser Sensor für den Außeneinsatz auf Grund seines geringen Temperaturbereich von -10 … +60 °C nur bedingt verwendbar, hier erscheint die Verwendung des DHT22 mit einem Temperaturbereich von -40 … +123 °C die bessere Lösung. Der von der Firma Hope RF hergestellte Sensor, der z.B. bei der Firma Pollin bezogen werden konnte, besteht aus zwei voneinander unabhängigen Baugruppen, zum einen einem EEPROM und dem eigentlichen Sensor für die Luftfeuchtemessung (siehe Stromlaufplan des HH10D).

In dem EPPROM werden beim Herstellungsprozess Kalibrierungswerte gespeichert, die für die Ermittlung der relativen Luftfeuchte in die Berechnung einfließen müssen und für jedes Sensormodul individuell sind, dazu später mehr.

Die zweite Baugruppe für die Messung der relativen Luftfeuchte besteht lediglich aus dem kapazitiven Sensor und einem Timer IC 7555, damit wird in Abhängigkeit der Luftfeuchte ein Rechtecksignal mit einer Frequenz zwischen 5...10 KHz erzeugt.

Fout Signal des HH10D
Fout Signal des HH10D

Anschluss des Sensors

Der Anschluss des Sensors an den Mikrocontroller erfolgt über eine Stift- oder Buchsenleiste das Modul ist entsprechend vorbereitet. Da das Modul lediglich für einen Spannungsbereich von 2V7 .. 3V3 ausgelegt ist muss diese Spannung natürlich bereitgestellt werden. Bei meinen Versuchen war es Problemlos möglich das Modul mit der Maximalen Spannung von 3V3 zu betreiben. Höhere Spannung zerstören das Modul jedoch, obwohl ich schon gelesen habe das es auch mit 5V arbeitet möchte ich dies nicht empfehlen, es gilt wie immer das Motto, Bauteile sollten nie außerhalb ihrer Spezifikation betrieben werden.

Das Modul kann prinzipiell mit einer Drei-Draht-Verbindung betrieben werden, die Anschlüsse für den I2C-Bus (SCL, SDA) werden nicht zwingend benötigt. Sie dienen nur dem Zugriff auf das schon erwähnte EEPROM mit den Kalibrierungswerten. Ist davon auszugehen dass das Sensormodul innerhalb der Anwendung nicht getauscht wird, reicht es aus diese Werte einmal auszulesen und im Auswertprogramm zu hinterlegen. In den Fällen, in denen das Modul evtl. getauscht wird müssen zusätzlich auch noch die Leitungen SCL/SDA angeschlossen werden, um nach einem Sensorwechsel eine automatische Konfiguration des Auswertprogramms zu ermöglichen, somit sind also fünf Verbindungen zwischen dem Sensor und dem Mikrocontroller nötig. Für die Experimente mit diesem Sensormodul hab ich eine kleine Zusatzplatine entwickelt auf der sich eine Spannungsversorgung, eine Pegelwandlung für den I2C Bus sowie ein Steckplatz für das Sensormodul befindet.

Die Spannungsversorgung

Die Spannungsversorgung besteht lediglich aus eine Zener-Stabilisierung (Abbildung 2), diese reicht völlig aus da das Modul nach Herstellerangaben eine Maximale Stromaufnahme von 180 µA besitzt.

HH10D Spannungsversorgung mit Zener-Diode
Abbildung 2: HH10D Spannungsversorgung mit Zener-Diode

Die Signalpegelumsetzung

Um die Signalpegelwandlung von z.B. 5V auf 3V3 durchzuführen gibt es unterschiedliche Ansätze. Es werden z.B. Integrierte Schaltungen angeboten die diese Aufgabe übernehmen, Nachteil dieser Lösung; sie sind teuer und auch nur schwer zu Handhaben da es sich dabei um SMD Bauteile handelt (Beispielhaft sei hier der PCA9306(1) von Texas Instruments genannt).

Die Standard Anwendung wurde vor Jahren schon von Philips in der „Application Note“ AN97055(2) und ebenso in der „Application Note“ AN10441(3) von 2007 beschrieben. Diese Schaltungsvariante kommt mit nur zwei N-MOSFET vom Typ BSS138 und vier Widerständen aus, somit hält sich hier der Schaltungsaufwand in Grenzen und es steht ein bidirektionaler I2C Bus mit 3V bzw. 3V3 und 5V zur Verfügung.
"Bild einfügen"

Eine weitere Alternative wurde in der EDN(4) vom 07.02.2002 im Artikel „Two-transistor circuit replaces IC“ von Jim Hagerman auf Seite 104 beschrieben.

Pegelwandler nach Jim Hagerman; EDN 07.02.2002
Pegelwandler nach Jim Hagerman; EDN 07.02.2002

Bei diesem Schaltungsdesign werden, für die beiden Signale SCL/SDA, vier Universal Bipolar NPN Transistoren (z.B. BC547) verwendet. Die Transistoren werden, bei diesem Schaltungsvorschlag, als Schalter in Sättigung betrieben und bilden ebenso wie die Schaltung aus den Philips „Application Note“ zwei unabhängig I2C Busse.

Ich habe mich bei meiner Experimentierschaltung für den Schaltungsvorschlag von Philips (Abbildung 3) entschieden, diesen habe ich etwas abgewandelt da ich keine BSS138 zur Hand hatte, in der Bastelkiste jedoch noch BS170 lagen.

Wer sich den zusätzlichen Aufwand des Selbstbaus, der zusätzlichen Hardware, sparen möchte kann auch eines der im Handel erhältlichen Pegelwandler-Boards(5) verwenden.

Anschluss an den Mikrocontroller

Für den Test stand mir ein Arduino Leonardo(6) zur Verfügung, die Verbindungen mit dem HH10D-Board wurden wie folgt gesteckt:

Messen und Berechnen der relativen Luftfeuchte

Nachdem die Anschlüsse zwischen Arduino und HH10D-Board hergestellt sind kann es nun mit der Programmierung des Arduino weitergehen. Da der I2C-Bus verwenden wird muss die Wire Bibliothek in das Programm eingefügt werden, für bessere Ergebnisse bei der Frequenzmessung kann noch die FreqCount Bibliothek verwendet werden.

Auslesen der EEProm Daten

Das auf dem HH10D Modul verbaute EEPROM, indem sich die zwei Koeffizienten für die Berechnung befinden, ist ein Standardtyp das kompatibel zum 24C02(7) ist. Laut Datenblatt ist dessen Adresse fest auf 0x01 (hex) gelegt, was ich aber für irreführend halte da ich im Datenblatt keinen Hinweis auf die Basisadresse des EEPROM finden konnte. Ich habe mir dann das Datenblatt zum X24C02 angeschaut und fand dort die folgende Angabe zur Basisadresse.

7 6 5 4 3 2 1 0
1 0 1 0 A2 A1 A0 R/W
Geräte Id. Geräte Adr.  

Mit diesen Informationen ergeben sich für das EEPROM des HH10D die folgenden Adressen

7 6 5 4 3 2 1 0 Funktion
1 0 1 0 0 0 1 x Basisadresse 81 (0x51)
1 0 1 0 0 0 1 1 Lesen 163 (0xA3)
1 0 1 0 0 0 1 0 Schreiben 162 (0xA2)
Geräte Id. Geräte Adr.  

Die Koeffizienten befinden im EEPROM an den folgenden Adressen

Koeffizient Adresse Bezeichnung
sens (MSB:LSB) 0x0A:0x0B Sensitivity
off (MSB:LSB) 0x0C:0x0D Offset

Es müssen also je Koeffizient insgesamt 2 Byte gelesen werden. Das MSB ist das Most Significant Bit, das LSB das Least Significant Bit. Die Tatsächlichen Werte für Offset und Sensitivity ergeben sich erst nach einer Linksverschiebung des MSB und dem addieren des LSB, die Formeln 1.1 und 1.2 verdeutlichen die Vorgehensweise

`Offset = Offset_{MSB} cdot (1 <<<< 8) + Offset_{LSB}`

Formel 1.1

`Sensitivity = Sensitivity_{MSB} cdot (1 <<<< 8) + Sensitivity_{LSB}`

Formel 1.2

Für (1 << 8) kann auch gleich der Wert (0xFF) eingesetzt werden, da dies gleichbedeutend ist.

Messen der Frequenz und berechnen der relative Luftfeuchte

`RH_{"%"} = (offset - Soh) cdot {sens} / 2^12`

Formel 1.3 - Berechnung der Frequenz, Formel nach Datenblatt.

`RH_{"%"} = (Offset - F_{out}) cdot {Sensitivity} / 2^12`

Formel 1.4 - An dieses Dokument angepasste Formel.

Zur Verdeutlichung folgt noch eine Beispielberechnung. Die für das Beispiel verwendeten Werte sind keine realen, vom Sensor gelieferten, Werte.

Parameter Wert
Sensitivity 321
Offset 7231
Frequenz (FOut) 7134 Hz

Die in der Tabelle aufgeführten Werte eingesetzt in die Formel 1.4 ergibt dann

`RH_{"%"} = (7231 - 7134) cdot 321 / 4096 " = " 97 cdot 0,78369 " = " 7,6"%"`

Formel 1.5 - Beipiel Berechnung

einen Wert für die relative Luftfeuchte von 7,6%.

Umsetzen des gewonnen Wissen in ein Programm für den Arduino

In diesem Kapitel werde ich die Software beschreiben, wie ich sie bei meinen Experimenten verwendet habe. Zu beginn werde ich zwei Testprogramme vorstellen bevor dann eine praxistaugliche Anwendung folgt.

Auslesen der Koeffizienten

#include <Wire.h>

/*
   Auslesen des EEProms des Luftfeuchtesensor HH10D.

   (c) Frank A. Dullinger, 2015
*/


#define DEVICEADDRESS  0x51

int offset, sensitivity;

void setup() {
  Wire.begin();
  Serial.begin(9600);
  while (!Serial) ; // wait for Arduino Serial Monitor

  // Lesen der zwei Byte für die sensitivity
  sensitivity = i2cRead2bytes(DEVICEADDRESS, 0x0A);
  Serial.print("Sens: "); Serial.println(sensitivity);

  // Lesen der zwei Byte für den offset
  offset = i2cRead2bytes(DEVICEADDRESS, 0x0C);
  Serial.print("Offset: "); Serial.println(offset);

}

void loop() {
  // put your main code here, to run repeatedly:

}

// 2-Byte vom I²C Bus lesen
int i2cRead2bytes(int deviceaddress, byte address) {
  // SET ADDRESS
  Wire.beginTransmission(deviceaddress);
  Wire.write(address);       // address von der gelesen wird
  Wire.endTransmission();

  // REQUEST RETURN VALUE
  Wire.requestFrom(deviceaddress, 2);
  // COLLECT RETURN VALUE
  int rv = 0;
  for (int c = 0; c < 2; c++ )
    if (Wire.available()) rv = rv * 256 + Wire.read();
  return rv;
}

 
HH10D Koeffizenten lesen

Messung der Frequenz

/*
   Auslesen des EEProms des Luftfeuchtesensor HH10D.

   (c) Frank A. Dullinger, 2015
*/

#define FOUT  12    // Pin für die Frequenzmessung

unsigned long T;          // Periodendauer in us
double f;                 // Frequenz in MHz

void setup() {
  Serial.begin(9600);
  while (!Serial) ; // wait for Arduino Serial Monitor
  pinMode(FOUT, INPUT);
}

void loop() {
  T = pulseIn(FOUT, HIGH) + pulseIn(FOUT, LOW);
  if (T == 0)
    Serial.println("Timeout.");
  else {
    f = 1 / (double)T;        // f=1/T
    Serial.println(f * 1e6);  // Ausgabe in Hertz
  }
}
 
HH10D Frequenz messen

Messung der relative Luftfeuchte

#include <Wire.h>

/*
   Auslesen der Luffeuchte mit dem HH10D.

   (c) Frank A. Dullinger, 2015

   Board: Leonardo
   2 = SDA = grün
   3 = SCL = gelb
*/


int DEVICEADDRESS = 0x51; // Geräteadresse des Sensor
int fout = 12;            // Pin für die Frequenzmessung
// double f;                 // Frequenz in MHz
int sensitivity;
int offset;

void setup() {
  Wire.begin();
  Serial.begin(9600);
  while (!Serial) ; // wait for Arduino Serial Monitor

  // Lesen der zwei Byte für die sensitivity
  sensitivity = i2cRead2bytes(DEVICEADDRESS, 0x0A);
  Serial.print("Sens: "); Serial.println(sensitivity);

  // Lesen der zwei Byte für den offset
  offset = i2cRead2bytes(DEVICEADDRESS, 0x0C);
  Serial.print("Offset: "); Serial.println(offset);
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.print("RH (%): "); Serial.println(readFrequency(2048), 2);
}

// 2-Byte vom I²C Bus lesen
int i2cRead2bytes(int deviceaddress, byte address) {
  // SET ADDRESS
  Wire.beginTransmission(deviceaddress);
  Wire.write(address);       // address von der gelesen wird
  Wire.endTransmission();

  // REQUEST RETURN VALUE
  Wire.requestFrom(deviceaddress, 2);
  // COLLECT RETURN VALUE
  int rv = 0;
  for (int c = 0; c < 2; c++ )
    if (Wire.available()) rv = rv * 256 + Wire.read();
  return rv;
}

long readFrequency(int samples) {
  long freq = 0;
  for (int j = 0; j < samples; j++) freq += 500000 / pulseIn(fout, HIGH, 250000);
  return freq / samples;
}

float getRH(int samples) {
  long freq = readFrequency(samples);
  float RH = float((offset - freq) * sensitivity) / float(4096);
  return RH;
}

 
HH10D Luftfeuchte messen

Besonderheiten

Bei der Verwendung des Sensor gibt es einige Besonderheiten zu beachten. Dem Datenblatt kann leider nicht ungeprüft vertraut werden das sich einige Fehler eingeschlichen haben und einige Information schlichtweg fehlen.

Auflistung der gefunden Fehler

Stromlaufplan des Sensors

Stromlaufplan des Sensors
Stromlaufplan HH10D

Links

  1. Hope RF (Link zum Sensor)
  2. PCA9306
  3. Philips „Application Note“ AN97055
  4. Philips „Application Note“ AN10441
  5. EDN 07.02.2002 „Two-transistor circuit replaces IC
  6. Pegelwandler-Board
  7. Arduino Leonardo
  8. EEProm 24C02
  9. Neuhold Elektronik; Graz, Österreich (Link zum Bauteil)

 

Da die dargestellten Schaltungen und Programme nur dem Grundverständnis dienen sollen, kann ich für die Funktion keine Gewähr übernehmen.
Wie üblich kann ich für Schäden die durch die Verwendung der hier veröffentlichten Schaltungen und Programme entstehen keine Haftung übernehmen.

Alle genannten und durch Dritte geschützten Marken- und Warenzeichen unterliegen uneingeschränkt den Bestimmungen des jeweils gültigen Kennzeichenrechts und den Besitzrechten der jeweiligen eingetragenen Eigentümer. Allein aufgrund der bloßen Nennung ist nicht der Schluss zu ziehen, dass Markenzeichen nicht durch Rechte Dritter geschützt sind!