Allegmein
Der Sketch stammt von Karl-Heinz Wind und wurde von mir angepasst. Er enthält die Berechnung und Anzeige der Sensoren für CO2 (MQ135), Feuchte, Temperatur und Bewegung. Es wurden ausschließlich typische MYSENSORS-Bauteile verwendet. Sollten bestimmte Bibliotheken fehlen, kann ich die gerne noch bereitstellen.
Sketch
#include <SPI.h>
 #include <MySensor.h>
#include <Wire.h>
#include <DHT.h>
 #include <MQ135.h>
#include „Timer.h“
//—————————————————————————-
 //unsigned long SLEEP_TIME = 10000; //Sleep time between reports (in milliseconds)
 #define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
 #define INTERRUPT DIGITAL_INPUT_SENSOR-3 // Usually the interrupt = pin -2 (on uno/nano anyway)
 #define CHILD_ID 1   // Id of the sensor child
//—————————————————————————–
 // Timer
 Timer timer;
 #define TEMP_UPDATE_INTERVAL 30000
//—————————————————————————–
 // DHT22
 #define CHILD_ID_TEMP 2
 #define CHILD_ID_HUM 3
 #define HUMIDITY_SENSOR_DIGITAL_PIN 4
DHT dht;
 float lastTemp;
 float lastHum;
 MyMessage msgHum(CHILD_ID_HUM, V_HUM);
 MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
//—————————————————————————–
 // MQ135
 #define CHILD_ID_CO2_CORRECTED 0
 #define CHILD_ID_CO2 1
 #define CHILD_ID_R0 4
 #define CO2_SENSOR_ANALOG_PIN 0
 #define CO2_SENSOR_BUFFER_SIZE 3
/// Calibration resistance at atmospheric CO2 level
 // Buero 21Grad Regen
 #define RZERO 300.0
 #define EEPROM_R0 0
MQ135 gasSensor = MQ135(CO2_SENSOR_ANALOG_PIN, RZERO);
 int lastC02;
 int lastCO2Corrected;
 float lastR0;
//RunningAverage lastCO2Values(CO2_SENSOR_BUFFER_SIZE);
//—————————————————————————–
 // MySensor
 MySensor gw;
 MyMessage msgCO2Corrected(CHILD_ID_CO2_CORRECTED, V_VAR1);
 MyMessage msgCO2(CHILD_ID_CO2, V_VAR1);
 MyMessage msgR0(CHILD_ID_R0, V_VAR1);
 MyMessage msg(CHILD_ID, V_TRIPPED);
//—————————————————————————–
 void setup()
 {
 Serial.begin(115200);
 dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
gw.begin(incomingMessage, AUTO, true);
 gw.sendSketchInfo(„CO2 Sensor MQ-135“, „1.3“);
 gw.present(CHILD_ID_CO2_CORRECTED, S_AIR_QUALITY);
 gw.present(CHILD_ID_CO2, S_AIR_QUALITY);
 gw.present(CHILD_ID_TEMP, S_TEMP);
 gw.present(CHILD_ID_HUM, S_HUM);
 gw.present(CHILD_ID_R0, S_CUSTOM);
gw.sendSketchInfo(„Motion Sensor“, „1.0“);
 pinMode(DIGITAL_INPUT_SENSOR, INPUT);
 gw.present(CHILD_ID, S_MOTION);
uint8_t R02 = gw.loadState(EEPROM_R0);
// get R0 from EEPROM
 float R0 = R02 * 2;
 if (R0 > 1.0 && R0 < 400.0)
 {
 Serial.print(F(„Setting R0 from EEPROM: „));
 }
 else
 {
 Serial.print(F(„Setting default R0: „));
 R0 = RZERO;
 }
Serial.print(R0);
 Serial.println(F(„“));
gasSensor.setR0(R0);
 //float ppm = gasSensor.getPPM();
 //lastCO2Values.fillValue(ppm, CO2_SENSOR_BUFFER_SIZE);
//int tickEvent1 =
 timer.every(TEMP_UPDATE_INTERVAL, timerHandler);
}
bool DHT22Changed(bool waitMinimumSamplingPeriod = true)
 {
 bool changed = false;
if (waitMinimumSamplingPeriod)
 {
 delay(dht.getMinimumSamplingPeriod());
 }
float temperature = dht.getTemperature();
 if (isnan(temperature))
 {
 Serial.println(F(„Failed reading temperature from DHT“));
 }
 else if (temperature != lastTemp)
 {
 lastTemp = temperature;
 Serial.print(„T: „);
 Serial.println(temperature);
 changed = true;
 }
float humidity = dht.getHumidity();
 if (isnan(humidity))
 {
 Serial.println(F(„Failed reading humidity from DHT“));
 }
 else if (humidity != lastHum)
 {
 lastHum = humidity;
 Serial.print(F(„H: „));
 Serial.println(humidity);
 changed = true;
 }
return changed;
 }
bool MQ135Changed(float t, float h)
 {
 bool changed = false;
lastR0 = gasSensor.getRZero();
 Serial.print(F(„R0: „));
 Serial.println(lastR0);
{
 float ppm = gasSensor.getPPM();
Serial.print(F(„CO2 ppm: „));
 Serial.print(ppm);
//lastCO2Values.addValue(ppm);
 //ppm = lastCO2Values.getAverage();
//Serial.print(“ average: „);
 //Serial.print(ppm);
int roundedPpm = (int)ppm;
 Serial.print(F(“ –> „));
 Serial.println(roundedPpm);
if (roundedPpm != lastC02)
 {
 lastC02 = roundedPpm;
 changed = true;
 }
 }
{
 float ppm = gasSensor.getCorrectedPPM(t, h);
Serial.print(F(„CO2 corrected ppm: „));
 Serial.print(ppm);
int roundedPpm = (int)ppm;
 Serial.print(F(“ –> „));
 Serial.println(roundedPpm);
if (roundedPpm != lastCO2Corrected)
 {
 lastCO2Corrected = roundedPpm;
 changed = true;
 }
 }
 // Read digital motion value
 boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
Serial.println(tripped);
 gw.send(msg.set(tripped?“1″:“0“));  // Send tripped value to gw
// Sleep until interrupt comes in on motion sensor. Send update every two minute.
 //gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME);
return changed;
 }
void timerHandler()
 {
 bool humidityChanged = DHT22Changed(false);
 bool airQualityChanged = MQ135Changed(lastTemp, lastHum);
if (humidityChanged || airQualityChanged)
 {
 gw.send(msgTemp.set(lastTemp, 1));
 gw.send(msgHum.set(lastHum, 1));
 gw.send(msgCO2Corrected.set(lastCO2Corrected));
 gw.send(msgCO2.set(lastC02));
 gw.send(msgR0.set(lastR0, 2));
 }
 }
void loop()
 {
 gw.process();
timer.update();
}
void incomingMessage(const MyMessage& message)
 {
 Serial.println(F(„Incoming Message:“));
if (message.isAck())
 {
 Serial.println(F(„This is an ack from gateway“));
 }
uint8_t sensor = message.sensor;
 if (sensor == CHILD_ID_R0)
 {
 float R0 = message.getFloat();
Serial.print(F(„Incoming R0: „));
 Serial.print(R0);
 Serial.println(F(„“));
gw.saveState(EEPROM_R0, (uint8_t)(R0/2));
 gasSensor.setR0(R0);
 gw.send(msgR0.set(R0, 2));
 }
 }

