MYSENSORS Zählermodul für Gaszähler API 2.0

Gaszähler mit Impulsgeber

Hier schon einmal der Sketch. Mit ihm erzeuge ich die Zählimpulse in MYSENSORS. In FHEM verwende ich dann das Modul Gascalculator zur weiteren Berechnung. Als Kontakt verwende ich einen einfach Reedkontakt.

/**
 * The MySensors Arduino library handles the wireless radio link and protocol
 * between your home built sensors/actuators and HA controller of choice.
 * The sensors forms a self healing radio network with optional repeaters. Each
 * repeater and gateway builds a routing tables in EEPROM which keeps track of the
 * network topology allowing messages to be routed to nodes.
 *
 * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
 * Copyright (C) 2013-2015 Sensnology AB
 * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
 *
 * Documentation: http://www.mysensors.org
 * Support Forum: http://forum.mysensors.org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 *******************************
 *
 * DESCRIPTION
 *
 * Simple binary switch example 
 * Connect button or door/window reed switch between 
 * digitial I/O pin 3 (BUTTON_PIN below) and GND.
 * http://www.mysensors.org/build/binary
 */
#define MY_RADIO_NRF24

#include <MySensors.h>
#include <SPI.h>
#include <Bounce2.h>

#define CHILD_ID 3
#define BUTTON_PIN  3  // Arduino Digital I/O pin for button/reed switch

 Bounce debouncer = Bounce(); 
int oldValue=-1;

// Change to V_LIGHT if you use S_LIGHT in presentation below
MyMessage msg(CHILD_ID,V_TRIPPED);

void setup()  
{  

  
  // Setup the button
  pinMode(BUTTON_PIN,INPUT);
  // Activate internal pull-up
  digitalWrite(BUTTON_PIN,HIGH);
  
  // After setting up the button, setup debouncer
  debouncer.attach(BUTTON_PIN);
  debouncer.interval(5);
}
void presentation(){
sendSketchInfo("DOOR", "v0.1");
  // Register binary input sensor to gw (they will be created as child devices)
  // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage. 
  // If S_LIGHT is used, remember to update variable type you send in. See "msg" above.
 present(CHILD_ID, S_DOOR);  
}


//  Check if digital input has changed and send in new value
void loop() 
{
 
  debouncer.update();
  // Get the update value
  int value = debouncer.read();
 
  if (value != oldValue) {
     // Send in the new value
     send(msg.set(value==HIGH ? 1 : 0));
     oldValue = value;
  }
} 

https://smarthome.gleisnetze.de

Sensoren4Sketch

Fertiges Sensormodul
  • 0.8 Verwendung der korrigierten Lib von RSTOIKA
  • Der R0 Wert kann automatisch zum Setzen in FHEM verwendet werde. Hiermit wird ein Button oben angezeigt. attr CO2_SZ setReading_R0 textField<br>
  • Einbrennzeit und Stabilisierung abwarten
  • Kalibrierung im Freien bei Windstille
  • Redesign MySensors 2.0
  • Grundwert R0Cor wird gesetzt, wenn CO2 < 390
  • Spezielle Lib ist für den Kalibierung – Button notwendig
  • EEPROM Speicherung R0Cor

MQ135lib.tar

//Sens4Sketch (Motion, Temperature, Humidity, CO2)

//v0.8 Corr. Lib von rstoica (set r0, correction) impl
//v0.7 set r0 to eeprom
//v0.6 SetR0-Button
//v0.5 Motion
//v0.4 autosetr0 if co2<400
//v0.3 api 2.0, redesign
//v0.2 CorrectedRZero basis for calculating r0
//G. Krocker K.-H. Wind et. al. ++++JH
//Caution: The Sketch erorder an amended mq135.h Library

//#define MY_DEBUG    // Enables debug messages in the serial log
#define MY_RADIO_NRF24
#include <SPI.h>
#include <MySensors.h>
#include <DHT.h>
#include <MQ135.h>
//----------------------------------------------------------------------------
// Timer
unsigned long SLEEP_TIME = 15*1000; // Sleep time between reads (in milliseconds)
//-----------------------------------------------------------------------------
//MOTION
#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_MOTION 8   // Id of the sensor child
MyMessage msgMotion(CHILD_ID_MOTION, S_MOTION);
//-----------------------------------------------------------------------------
// DHT22
#define CHILD_ID_HUM 0
#define CHILD_ID_TEMP 1
#define HUMIDITY_SENSOR_DIGITAL_PIN 4
DHT dht;
float lastTemp;
float lastHum;
boolean metric = true; 
MyMessage msgHum(CHILD_ID_HUM, V_HUM);
MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
//-----------------------------------------------------------------------------
// MQ135
#define CHILD_ID_CO2C 24
#define CHILD_ID_CO2 25
#define CHILD_ID_R0C 26
#define CHILD_ID_R0 27
#define EEPROM_R0C 0
int C02;
int CO2C;
float R0;
float R0C;
float R02;
MQ135 gasSensor = MQ135(0);//PIN0 
MyMessage msgCO2C(CHILD_ID_CO2C, V_VAR1);
MyMessage msgCO2(CHILD_ID_CO2, V_VAR1);
MyMessage msgR0C(CHILD_ID_R0C, V_VAR1);
MyMessage msgR0(CHILD_ID_R0, V_VAR1);
//-----------------------------------------------------------------------------
void setup() {
//--------------------------------------------------------------------- 
 //R0C aus EEPROM sonst 55
dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
pinMode(DIGITAL_INPUT_SENSOR, INPUT);
uint8_t R02 = loadState(EEPROM_R0C);
// get R0C from EEPROM
float R0C = R02 * 2;
if (R0C > 1.0 && R0C < 500.0)
{
Serial.print(F("Setting R0 from EEPROM: "));
}
else
{
Serial.print(F("Setting default R0C: "));
R0C = 50;
}
Serial.print(R0C);
Serial.println(F(""));
gasSensor.setRZero(R0C);
}
//-----------------------------------------------------------------------------
void presentation(){
sendSketchInfo("Sens4", "v0.7");
present(CHILD_ID_TEMP, S_TEMP);
present(CHILD_ID_HUM, S_HUM);
present(CHILD_ID_CO2C, S_CUSTOM);
present(CHILD_ID_CO2, S_CUSTOM);
present(CHILD_ID_R0C, S_CUSTOM);
present(CHILD_ID_R0, S_CUSTOM);
present(CHILD_ID_MOTION, S_MOTION);
}
//-----------------------------------------------------------------------------



void loop(){



//-----------------------------------------------------------------------------
//TEMP_FEUCHTE 

wait(dht.getMinimumSamplingPeriod());// TheoL
  float temperature = dht.getTemperature();
  if (isnan(temperature)) {
      Serial.println("Failed reading temperature from DHT");
  } else if (temperature != lastTemp) {
    lastTemp = temperature;
    if (!metric) {
      temperature = dht.toFahrenheit(temperature);
    }
   send(msgTemp.set(temperature, 1));
    Serial.print("T: ");
    Serial.println(temperature);
  }
  
  float humidity = dht.getHumidity();
  if (isnan(humidity)) {
      Serial.println("Failed reading humidity from DHT");
  } else if (humidity != lastHum) {
      lastHum = humidity;
      send(msgHum.set(humidity, 1));
      Serial.print("H: ");
      Serial.println(humidity);
  }
//-----------------------------------------------------------------------------  
//CO2
  float R0 = gasSensor.getRZero();
  float R0C = gasSensor.getCorrectedRZero(temperature, humidity);
  float CO2 = gasSensor.getPPM();
  float CO2C = gasSensor.getCorrectedPPM(temperature, humidity);
  
  Serial.print("R0: "); 
  Serial.println(R0);
  send(msgR0.set(R0,1));

  Serial.print("R0C: ");
  Serial.println(R0C);
  send(msgR0C.set(R0C,1));

  Serial.print("CO2: ");
  Serial.println(CO2);
  send(msgCO2.set(CO2,1));

  Serial.print("CO2C: ");
  Serial.println(CO2C);
  send(msgCO2C.set(CO2C,1));
  
  Serial.println();
// Grundwert CO2 < 400 ppm dann setze R0C in Lib
if (CO2C < 420)
{
  saveState(EEPROM_R0C, (uint8_t)(R0C/2));
  gasSensor.setRZero(R0C);
  send(msgR0C.set(R0C, 2));
  Serial.print(F("CO2 < 420: R0 gesetzt "));
}
//-----------------------------------------------------------------------------
//Read digital motion value
boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
Serial.println(tripped);
send(msgMotion.set(tripped?"1":"0"));  
//-----------------------------------------------------------------------------
wait(SLEEP_TIME); //sleep for: sleepTime // byTheo: Changed
}
//-----------------------------------------------------------------------------
//incomingMessage
void receive(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_R0C)
{
float R0C = message.getFloat();

Serial.print(F("Incoming R0C: "));
Serial.print(R0C);
Serial.println(F(""));

saveState(EEPROM_R0C, (uint8_t)(R0C/2));
gasSensor.setRZero(R0C);
send(msgR0.set(R0C, 2));
}
}
//-----------------------------------------------------------------------------