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));
}
}