Moin,
ich möchte 8 Temperatur- und Luftfeuchtigkeitssensoren miteinander vergleichen (absolute Werte, Langzeitstabilität, Lebensdauer draußen).
Dazu habe ich mir jeweils einen DHT22, DHT20, AHT10, AHT20, AHT25, HTU21, HTU31 und einen GXHT30 besorgt.
Den DHT22 kann man mit einem digitalen Pin abfragen. Alle anderen habe eine I²C Schnittstelle. Um die sieben I²C Sensoren abfragen zu können werden diese Nacheinander mit einem Multiplexer angesteuert. Der Multiplexer ist an einem nodeMCU ESP82666 angeschlossen, damit wieder letztenendes per WLAN die Daten funken kann. Soweit so gut.
Dann habe ich mir für jeden Sensor Beispielsketche angesehen und ausprobiert, bis ich für jeden ein lauffähiges Sketch hatte. Dann habe ich den Multiplexer dazwischen geschaltet, und habe jedes einzelne Sketch so geändert, dass ich den jeweiligen Sensor durch den Multiplexer ansprechen kann. Danach wollte ich dann alle Sketche zusammenführen. Aber es ergeben sich schon bei dem Schritt davor Probleme.
Scheinbar funktioniert irgendwas mit dem Multiplexer nicht.
Der erste Sensor erschien mir zu funktionieren.
Als ich das gleiche mit dem zweiten und dritten Sensor gemacht habe, habe ich erkannt, die die Messwerte bis auf die zweite Nachkommastelle identisch sind. Ich hätte allerdings geringe Abweichungen (1-2 °C und ein paar Prozent in der Luftfeuchtigkeit erwartet). So ist es jedenfalls zwischen dem DHT22 und dem DHT20 Sensor, und auch bei meinen Einzeltests war das so.
Die ersten vier i²C Sensoren haben alle die gleiche Adresse 0x38.
Ich vermute, dass meine unterschiedlichen Sketche immer den gleichen Sensor abfragen, sonst würden da nicht die gleichen Ergebnisse bei rauskommen können.
Wo liegt der Fehler?
Hier meine drei Einzelsketche:
DHT20:
// Angeschlossen an:
// 3,3V, GND
// SDA+SCL am Multiplexer
#include "Wire.h"
#include "DHT20.h"
DHT20 DHT(&Wire);
#define I2CmultiADDR 0x70 // Multiplexeradresse
enum I2CDevice {
dht20 = 0,
aht10 = 1,
aht20 = 2,
aht25 = 3,
htu21 = 4,
htu31 = 5,
gxht30 = 6
};
void I2Cmulti(I2CDevice num) {
uint8_t i = (uint8_t) num;
if (i > 7) return;
Wire.beginTransmission(I2CmultiADDR);
Wire.write(1 << i);
Wire.endTransmission();
}
void setup()
{
#if defined(ESP8266) || defined(ESP32)
DHT.begin(4, 5); // select your pin numbers here
#else
DHT.begin();
#endif
Serial.begin(115200);
delay(200);
I2Cmulti(dht20);
delay(2000);
}
void loop()
{
// READ DATA
int status = DHT.read();
switch (status)
{
case DHT20_OK:
//Serial.println("OK,\t");
break;
case DHT20_ERROR_CHECKSUM:
Serial.println("Checksum error,\t");
break;
case DHT20_ERROR_CONNECT:
Serial.println("Connect error,\t");
break;
case DHT20_MISSING_BYTES:
Serial.println("Missing bytes,\t");
break;
case DHT20_ERROR_BYTES_ALL_ZERO:
Serial.println("All bytes read zero");
break;
case DHT20_ERROR_READ_TIMEOUT:
Serial.println("Read time out");
break;
case DHT20_ERROR_LASTREAD:
Serial.println("Error read too fast");
break;
default:
Serial.println("Unknown error,\t");
break;
}
// DISPLAY DATA, sensor has only one decimal.
Serial.print("DHT20 Luftfeuchtigkeit: ");
Serial.print(DHT.getHumidity(), 1);
Serial.print("\t");
Serial.print("DHT20 Temperatur: ");
Serial.println(DHT.getTemperature(), 1);
delay(2000);
}
AHT10:
#include "Wire.h"
#include <Adafruit_AHT10.h>
Adafruit_AHT10 aht;
#define I2CmultiADDR 0x70 // Multiplexeradresse
// Angeschlossen an:
// 3,3V, GND
// SDA+SCL am Multiplexer
enum I2CDevice {
dht20 = 0,
aht10 = 1,
aht20 = 2,
aht25 = 3,
htu21 = 4,
htu31 = 5,
gxht30 = 6
};
void I2Cmulti(I2CDevice num) {
uint8_t i = (uint8_t) num;
if (i > 7) return;
Wire.beginTransmission(I2CmultiADDR);
Wire.write(1 << i);
Wire.endTransmission();
}
void setup() {
Serial.begin(115200);
delay(200);
I2Cmulti(aht10);
if (! aht.begin()) {
Serial.println("Could not find AHT10? Check wiring");
while (1) delay(10);
}
//Serial.println("AHT10 found");
}
void loop() {
sensors_event_t humidity, temp;
aht.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
Serial.print("AHT10 Luftfeuchtigkeit: ");
Serial.print(humidity.relative_humidity);
Serial.print("\t");
Serial.print("AHT10 Temperatur: ");
Serial.println(temp.temperature);
delay(2000);
}
AHT20:
#include "Wire.h"
#include <Adafruit_AHTX0.h>
Adafruit_AHTX0 aht;
#define I2CmultiADDR 0x70 // Multiplexeradresse
// Angeschlossen an:
// 3,3V, GND
// SDA+SCL am Multiplexer
enum I2CDevice {
dht20 = 0,
aht10 = 1,
aht20 = 2,
aht25 = 3,
htu21 = 4,
htu31 = 5,
gxht30 = 6
};
void I2Cmulti(I2CDevice num) {
uint8_t i = (uint8_t) num;
if (i > 7) return;
Wire.beginTransmission(I2CmultiADDR);
Wire.write(1 << i);
Wire.endTransmission();
}
void setup() {
Serial.begin(115200);
delay(200);
I2Cmulti(aht20);
if (! aht.begin()) {
Serial.println("Could not find AHT? Check wiring");
while (1) delay(10);
}
//Serial.println("AHT20 found");
}
void loop() {
sensors_event_t humidity, temp;
aht.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
Serial.print("AHT20 Luftfeuchtigkeit: ");
Serial.print(humidity.relative_humidity);
Serial.print("\t");
Serial.print("AHT20 Temperatur: ");
Serial.println(temp.temperature);
delay(2000);
}
AHT25:
// Angeschlossen an:
// 3,3V, GND
// SDA+SCL am Multiplexer
#define I2CmultiADDR 0x70 // Multiplexeradresse
#include <Wire.h>
#include <AHTxx.h>
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#endif
float ahtValue; //to store T/RH result
AHTxx aht_25(AHTXX_ADDRESS_X38, AHT2x_SENSOR); //sensor address, sensor type
enum I2CDevice {
dht20 = 0,
aht10 = 1,
aht20 = 2,
aht25 = 3,
htu21 = 4,
htu31 = 5,
gxht30 = 6
};
void I2Cmulti(I2CDevice num) {
uint8_t i = (uint8_t) num;
if (i > 7) return;
Wire.beginTransmission(I2CmultiADDR);
Wire.write(1 << i);
Wire.endTransmission();
}
/**************************************************************************/
/*
setup()
Main setup
*/
/**************************************************************************/
void setup()
{
#if defined(ESP8266)
WiFi.persistent(false); //disable saving wifi config into SDK flash area
WiFi.forceSleepBegin(); //disable AP & station by calling "WiFi.mode(WIFI_OFF)" & put modem to sleep
#endif
Serial.begin(115200);
delay(200);
I2Cmulti(aht25);
Serial.println();
while (aht_25.begin() != true) //for ESP-01 use aht_25.begin(0, 2);
{
Serial.println(F("AHT2x not connected or fail to load calibration coefficient")); //(F()) save string to flash & keeps dynamic memory free
delay(5000);
}
Serial.println(F("AHT25 OK"));
//Wire.setClock(400000); //experimental I2C speed! 400KHz, default 100KHz
}
/**************************************************************************/
/*
loop()
Main loop
*/
/**************************************************************************/
void loop()
{
/* DEMO - 1, every temperature or humidity call will read 6-bytes over I2C, total 12-bytes */
Serial.println();
Serial.println(F("DEMO 1: read 12-bytes"));
ahtValue = aht_25.readTemperature(); //read 6-bytes via I2C, takes 80 milliseconds
Serial.print(F("Temperature...: "));
if (ahtValue != AHTXX_ERROR) //AHTXX_ERROR = 255, library returns 255 if error occurs
{
Serial.print(ahtValue);
Serial.println(F(" +-0.3C"));
}
else
{
printStatus(); //print temperature command status
if (aht_25.softReset() == true) Serial.println(F("reset success")); //as the last chance to make it alive
else Serial.println(F("reset failed"));
}
delay(2000); //measurement with high frequency leads to heating of the sensor, see NOTE
ahtValue = aht_25.readHumidity(); //read another 6-bytes via I2C, takes 80 milliseconds
Serial.print(F("Humidity......: "));
if (ahtValue != AHTXX_ERROR) //AHTXX_ERROR = 255, library returns 255 if error occurs
{
Serial.print(ahtValue);
Serial.println(F(" +-2%"));
}
else
{
printStatus(); //print humidity command status
}
delay(2000); //measurement with high frequency leads to heating of the sensor, see NOTE
/* DEMO - 2, temperature call will read 6-bytes via I2C, humidity will use same 6-bytes */
Serial.println();
Serial.println(F("DEMO 2: read 6-byte"));
ahtValue = aht_25.readTemperature(); //read 6-bytes via I2C, takes 80 milliseconds
Serial.print(F("Temperature: "));
if (ahtValue != AHTXX_ERROR) //AHTXX_ERROR = 255, library returns 255 if error occurs
{
Serial.print(ahtValue);
Serial.println(F(" +-0.3C"));
}
else
{
printStatus(); //print temperature command status
}
ahtValue = aht_25.readHumidity(AHTXX_USE_READ_DATA); //use 6-bytes from temperature reading, takes zero milliseconds!!!
Serial.print(F("Humidity...: "));
if (ahtValue != AHTXX_ERROR) //AHTXX_ERROR = 255, library returns 255 if error occurs
{
Serial.print(ahtValue);
Serial.println(F(" +-2%"));
}
else
{
printStatus(); //print temperature command status not humidity!!! RH measurement use same 6-bytes from T measurement
}
delay(10000); //recomended polling frequency 8sec..30sec
}
/**************************************************************************/
/*
printStatus()
Print last command status
*/
/**************************************************************************/
void printStatus()
{
switch (aht_25.getStatus())
{
case AHTXX_NO_ERROR:
Serial.println(F("no error"));
break;
case AHTXX_BUSY_ERROR:
Serial.println(F("sensor busy, increase polling time"));
break;
case AHTXX_ACK_ERROR:
Serial.println(F("sensor didn't return ACK, not connected, broken, long wires (reduce speed), bus locked by slave (increase stretch limit)"));
break;
case AHTXX_DATA_ERROR:
Serial.println(F("received data smaller than expected, not connected, broken, long wires (reduce speed), bus locked by slave (increase stretch limit)"));
break;
case AHTXX_CRC8_ERROR:
Serial.println(F("computed CRC8 not match received CRC8, this feature supported only by AHT2x sensors"));
break;
default:
Serial.println(F("unknown status"));
break;
}
}
Beste Grüße,
Chris