From 17f53c083bc912df40113ca1a9481e0daba0cb8a Mon Sep 17 00:00:00 2001
From: user2684 <you@example.com>
Date: Tue, 4 Apr 2017 18:39:03 +0200
Subject: [PATCH] Add support for MQ gas sensor #36

---
 NodeManager.cpp | 225 +++++++++++++++++++++++++++++++++++++++++++++---
 NodeManager.h   |  76 +++++++++++++++-
 NodeManager.ino |   2 +-
 README.md       |  33 ++++++-
 config.h        |   8 +-
 5 files changed, 323 insertions(+), 21 deletions(-)

diff --git a/NodeManager.cpp b/NodeManager.cpp
index 4d218df..32a1225 100644
--- a/NodeManager.cpp
+++ b/NodeManager.cpp
@@ -154,6 +154,12 @@ void Sensor::before() {
   onBefore();
 }
 
+// call the sensor-specific implementation of setup
+void Sensor::setup() {
+  if (_pin == -1) return;
+  onSetup();
+}
+
 // call the sensor-specific implementation of loop
 void Sensor::loop(const MyMessage & message) {
   if (_pin == -1) return;
@@ -278,12 +284,16 @@ void SensorAnalogInput::setRangeMax(int value) {
   _range_max = value;
 }
 
-// what do to during setup
+// what do to during before
 void SensorAnalogInput::onBefore() {
   // prepare the pin for input
   pinMode(_pin, INPUT);
 }
 
+// what do to during setup
+void SensorAnalogInput::onSetup() {
+}
+
 // what do to during loop
 void SensorAnalogInput::onLoop() {
   // read the input
@@ -375,12 +385,16 @@ void SensorThermistor::setOffset(float value) {
   _offset = value;
 }
 
-// what do to during setup
+// what do to during before
 void SensorThermistor::onBefore() {
   // set the pin as input
   pinMode(_pin, INPUT);
 }
 
+// what do to during setup
+void SensorThermistor::onSetup() {
+}
+
 // what do to during loop
 void SensorThermistor::onLoop() {
   // read the voltage across the thermistor
@@ -423,12 +437,16 @@ void SensorThermistor::onReceive(const MyMessage & message) {
 SensorDigitalInput::SensorDigitalInput(int child_id, int pin): Sensor(child_id, pin) {
 }
 
-// what do to during setup
+// what do to during before
 void SensorDigitalInput::onBefore() {
   // set the pin for input
   pinMode(_pin, INPUT);
 }
 
+// what do to during setup
+void SensorDigitalInput::onSetup() {
+}
+
 // what do to during loop
 void SensorDigitalInput::onLoop() {
   // read the value
@@ -459,6 +477,7 @@ void SensorDigitalInput::onReceive(const MyMessage & message) {
 SensorDigitalOutput::SensorDigitalOutput(int child_id, int pin): Sensor(child_id, pin) {
 }
 
+// what do to during before
 void SensorDigitalOutput::onBefore() {
   // set the pin as output and initialize it accordingly
   pinMode(_pin, OUTPUT);
@@ -467,6 +486,10 @@ void SensorDigitalOutput::onBefore() {
   _value_int = _initial_value;
 }
 
+// what do to during setup
+void SensorDigitalOutput::onSetup() {
+}
+
 // setter/getter
 void SensorDigitalOutput::setInitialValue(int value) {
   _initial_value = value;
@@ -560,12 +583,16 @@ SensorDHT::SensorDHT(int child_id, int pin, DHT* dht, int sensor_type, int dht_t
   }
 }
 
-// what do to during setup
+// what do to during before
 void SensorDHT::onBefore() {
     // initialize the dht library
     _dht->begin();
 }
 
+// what do to during setup
+void SensorDHT::onSetup() {
+}
+
 // what do to during loop
 void SensorDHT::onLoop() {
   // temperature sensor
@@ -627,12 +654,16 @@ SensorSHT21::SensorSHT21(int child_id, int sensor_type): Sensor(child_id,A2) {
   }
 }
 
-// what do to during setup
+// what do to during before
 void SensorSHT21::onBefore() {
   // initialize the library
   Wire.begin();
 }
 
+// what do to during setup
+void SensorSHT21::onSetup() {
+}
+
 // what do to during loop
 void SensorSHT21::onLoop() {
   // temperature sensor
@@ -708,13 +739,17 @@ int SensorSwitch::getInitial() {
   return _initial;
 }
 
-// what do to during setup
+// what do to during before
 void SensorSwitch::onBefore() {
   // initialize the value
   if (_mode == RISING) _value_int = LOW;
   else if (_mode == FALLING) _value_int = HIGH;
 }
 
+// what do to during setup
+void SensorSwitch::onSetup() {
+}
+
 // what do to during loop
 void SensorSwitch::onLoop() {
   // wait to ensure the the input is not floating
@@ -775,10 +810,14 @@ SensorDs18b20::SensorDs18b20(int child_id, int pin, DallasTemperature* sensors,
   _sensors = sensors;
 }
 
-// what do to during setup
+// what do to during before
 void SensorDs18b20::onBefore() {
 }
 
+// what do to during setup
+void SensorDs18b20::onSetup() {
+}
+
 // what do to during loop
 void SensorDs18b20::onLoop() {
   // request the temperature
@@ -814,11 +853,15 @@ SensorBH1750::SensorBH1750(int child_id): Sensor(child_id,A4) {
   _lightSensor = new BH1750();
 }
 
-// what do to during setup
+// what do to during before
 void SensorBH1750::onBefore() {
   _lightSensor->begin();
 }
 
+// what do to during setup
+void SensorBH1750::onSetup() {
+}
+
 // what do to during loop
 void SensorBH1750::onLoop() {
   // request the light level
@@ -852,12 +895,16 @@ SensorMLX90614::SensorMLX90614(int child_id, Adafruit_MLX90614* mlx, int sensor_
   setValueType(TYPE_FLOAT);
 }
 
-// what do to during setup
+// what do to during before
 void SensorMLX90614::onBefore() {
   // initialize the library
   _mlx->begin();
 }
 
+// what do to during setup
+void SensorMLX90614::onSetup() {
+}
+
 // what do to during loop
 void SensorMLX90614::onLoop() {
   float temperature = _sensor_type == 0 ? _mlx->readAmbientTempC() : _mlx->readObjectTempC();
@@ -907,9 +954,12 @@ SensorBME280::SensorBME280(int child_id, Adafruit_BME280* bme, int sensor_type):
   }
 }
 
-// what do to during setup
+// what do to during before
 void SensorBME280::onBefore() {
-  // initialize the library
+}
+
+// what do to during setup
+void SensorBME280::onSetup() {
 }
 
 // what do to during loop
@@ -965,6 +1015,152 @@ void SensorBME280::onReceive(const MyMessage & message) {
 }
 #endif
 
+/*
+ * SensorMQ
+ */
+SensorMQ::SensorMQ(int child_id, int pin): Sensor(child_id,pin) {
+  setPresentation(S_AIR_QUALITY);
+  setType(V_LEVEL);
+}
+
+//setter/getter
+void SensorMQ::setRlValue(float value) {
+  _rl_value = value;
+}
+void SensorMQ::setRoValue(float value) {
+  _ro = value;
+}
+void SensorMQ::setCleanAirFactor(float value) {
+  _ro_clean_air_factor = value;
+}
+void SensorMQ::setCalibrationSampleTimes(int value) {
+  _calibration_sample_times = value;
+}
+void SensorMQ::setCalibrationSampleInterval(int value){
+  _calibration_sample_interval = value;
+}
+void SensorMQ::setReadSampleTimes(int value) {
+  _read_sample_times = value;
+}
+void SensorMQ::setReadSampleInterval(int value) {
+  _read_sample_interval = value;
+}
+void SensorMQ::setLPGCurve(float *value) {
+  _LPGCurve[0] = value[0];
+  _LPGCurve[2] = value[1];
+  _LPGCurve[2] = value[2];
+}
+void SensorMQ::setCOCurve(float *value) {
+  _COCurve[0] = value[0];
+  _COCurve[2] = value[1];
+  _COCurve[2] = value[2];
+}
+void SensorMQ::setSmokeCurve(float *value) {
+  _SmokeCurve[0] = value[0];
+  _SmokeCurve[2] = value[1];
+  _SmokeCurve[2] = value[2];
+}
+
+// what do to during before
+void SensorMQ::onBefore() {
+  // prepare the pin for input
+  pinMode(_pin, INPUT);
+}
+
+// what do to during setup
+void SensorMQ::onSetup() {
+  _ro = _MQCalibration();
+  onLoop();
+}
+
+// what do to during loop
+void SensorMQ::onLoop() {
+  if (_pin == -1) return;
+  // calculate rs/ro
+  float mq = _MQRead()/_ro;
+  // calculate the ppm
+  float lpg = _MQGetGasPercentage(mq,_gas_lpg);
+  float co = _MQGetGasPercentage(mq,_gas_co);
+  float smoke = _MQGetGasPercentage(mq,_gas_smoke);
+  // assign to the value the requested gas
+  uint16_t value;
+  if (_target_gas == _gas_lpg) value = lpg;
+  if (_target_gas == _gas_co) value = co;
+  if (_target_gas == _gas_smoke) value = smoke;
+  #if DEBUG == 1
+    Serial.print(F("MQ I="));
+    Serial.print(_child_id);
+    Serial.print(F(" V="));
+    Serial.print(value);
+    Serial.print(F(" LPG="));
+    Serial.print(lpg);
+    Serial.print(F(" CO="));
+    Serial.print(co);
+    Serial.print(F(" SMOKE="));
+    Serial.println(smoke);
+  #endif
+  // store the value
+  _value_int = (int16_t)ceil(value);
+}
+
+// what do to as the main task when receiving a message
+void SensorMQ::onReceive(const MyMessage & message) {
+  onLoop();
+}
+
+// returns the calculated sensor resistance
+float SensorMQ::_MQResistanceCalculation(int raw_adc) {
+  return ( ((float)_rl_value*(1023-raw_adc)/raw_adc));
+}
+
+//  This function assumes that the sensor is in clean air
+float SensorMQ::_MQCalibration() {
+  int i;
+  float val=0;
+  //take multiple samples
+  for (i=0; i< _calibration_sample_times; i++) {  
+    val += _MQResistanceCalculation(analogRead(_pin));
+    delay(_calibration_sample_interval);
+  }
+  //calculate the average value
+  val = val/_calibration_sample_times;                   
+  //divided by RO_CLEAN_AIR_FACTOR yields the Ro
+  val = val/_ro_clean_air_factor;
+  //according to the chart in the datasheet
+  return val;
+}
+
+// This function use MQResistanceCalculation to caculate the sensor resistenc (Rs).
+float SensorMQ::_MQRead() {
+  int i;
+  float rs=0;
+  for (i=0; i<_read_sample_times; i++) {
+    rs += _MQResistanceCalculation(analogRead(_pin));
+    delay(_read_sample_interval);
+  }
+  rs = rs/_read_sample_times;
+  return rs;
+}
+
+
+// This function passes different curves to the MQGetPercentage function which calculates the ppm (parts per million) of the target gas.
+int SensorMQ::_MQGetGasPercentage(float rs_ro_ratio, int gas_id) {
+  if ( gas_id == _gas_lpg ) {
+    return _MQGetPercentage(rs_ro_ratio,_LPGCurve);
+  } else if ( gas_id == _gas_co) {
+    return _MQGetPercentage(rs_ro_ratio,_COCurve);
+  } else if ( gas_id == _gas_smoke) {
+    return _MQGetPercentage(rs_ro_ratio,_SmokeCurve);
+  }
+  return 0;
+}
+
+// returns ppm of the target gas
+int SensorMQ::_MQGetPercentage(float rs_ro_ratio, float *pcurve) {
+  return (pow(10,( ((log10(rs_ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0])));
+}
+
+
 /*******************************************
    NodeManager
 */
@@ -1059,6 +1255,7 @@ int NodeManager::registerSensor(int sensor_type, int pin, int child_id) {
     else if (sensor_type == SENSOR_ANALOG_INPUT) return registerSensor(new SensorAnalogInput(child_id, pin));
     else if (sensor_type == SENSOR_LDR) return registerSensor(new SensorLDR(child_id, pin));
     else if (sensor_type == SENSOR_THERMISTOR) return registerSensor(new SensorThermistor(child_id, pin));
+    else if (sensor_type == SENSOR_MQ) return registerSensor(new SensorMQ(child_id, pin));
   #endif
   #if MODULE_DIGITAL_INPUT == 1
     else if (sensor_type == SENSOR_DIGITAL_INPUT) return registerSensor(new SensorDigitalInput(child_id, pin));
@@ -1305,6 +1502,12 @@ void NodeManager::setup() {
   #if SERVICE_MESSAGES == 1
     _send(_msg.set("STARTED"));
   #endif
+  // run setup for all the registered sensors
+  for (int i = 0; i < 255; i++) {
+    if (_sensors[i] == 0) continue;
+    // call each sensor's setup()
+    _sensors[i]->setup();
+  }
 }
 
 // run the main function for all the register sensors
diff --git a/NodeManager.h b/NodeManager.h
index da3ca44..fff34de 100644
--- a/NodeManager.h
+++ b/NodeManager.h
@@ -41,7 +41,7 @@
 #define EEPROM_SLEEP_UNIT 4
 
 // define NodeManager version
-#define VERSION 1.3
+#define VERSION 1.4
 
 /************************************
  * Include user defined configuration settings
@@ -97,7 +97,7 @@
   #define BATTERY_CHILD_ID 201
 #endif
 
-// Enable this module to use one of the following sensors: SENSOR_ANALOG_INPUT, SENSOR_LDR, SENSOR_THERMISTOR
+// Enable this module to use one of the following sensors: SENSOR_ANALOG_INPUT, SENSOR_LDR, SENSOR_THERMISTOR, SENSOR_MQ
 #ifndef MODULE_ANALOG_INPUT
   #define MODULE_ANALOG_INPUT 0
 #endif
@@ -147,6 +147,8 @@
   #define SENSOR_LDR 2
   // Thermistor sensor, return the temperature based on the attached thermistor
   #define SENSOR_THERMISTOR 3
+  // MQ2 air quality sensor
+  #define SENSOR_MQ 19
 #endif
 #if MODULE_DIGITAL_INPUT == 1
   // Generic digital sensor, return a pin's digital value
@@ -194,7 +196,7 @@
   // MLX90614 sensor, contactless temperature sensor
   #define SENSOR_BME280 18
 #endif
-// last Id: 18
+// last Id: 19
 /***********************************
   Libraries
 */
@@ -301,10 +303,12 @@ class Sensor {
     // define what to do at each stage of the sketch
     virtual void before();
     virtual void presentation();
+    virtual void setup();
     virtual void loop(const MyMessage & message);
     virtual void receive(const MyMessage & message);
     // abstract functions, subclasses need to implement
     virtual void onBefore() = 0;
+    virtual void onSetup() = 0;
     virtual void onLoop() = 0;
     virtual void onReceive(const MyMessage & message) = 0;
   protected:
@@ -353,6 +357,7 @@ class SensorAnalogInput: public Sensor {
     void setRangeMax(int value);
     // define what to do at each stage of the sketch
     void onBefore();
+    void onSetup();
     void onLoop();
     void onReceive(const MyMessage & message);
   protected:
@@ -391,6 +396,7 @@ class SensorThermistor: public Sensor {
     void setOffset(float value);
     // define what to do at each stage of the sketch
     void onBefore();
+    void onSetup();
     void onLoop();
     void onReceive(const MyMessage & message);
   protected:
@@ -409,6 +415,7 @@ class SensorDigitalInput: public Sensor {
     SensorDigitalInput(int child_id, int pin);
     // define what to do at each stage of the sketch
     void onBefore();
+    void onSetup();
     void onLoop();
     void onReceive(const MyMessage & message);
 };
@@ -425,6 +432,7 @@ class SensorDigitalOutput: public Sensor {
     void setPulseWidth(int value);
     // define what to do at each stage of the sketch
     void onBefore();
+    void onSetup();
     void onLoop();
     void onReceive(const MyMessage & message);
   protected:
@@ -460,6 +468,7 @@ class SensorDHT: public Sensor {
     SensorDHT(int child_id, int pin, DHT* dht, int sensor_type, int dht_type);
     // define what to do at each stage of the sketch
     void onBefore();
+    void onSetup();
     void onLoop();
     void onReceive(const MyMessage & message);
   protected:
@@ -479,6 +488,7 @@ class SensorSHT21: public Sensor {
     SensorSHT21(int child_id, int sensor_type);
     // define what to do at each stage of the sketch
     void onBefore();
+    void onSetup();
     void onLoop();
     void onReceive(const MyMessage & message);
   protected:
@@ -514,6 +524,7 @@ class SensorSwitch: public Sensor {
     int getInitial();
     // define what to do at each stage of the sketch
     void onBefore();
+    void onSetup();
     void onLoop();
     void onReceive(const MyMessage & message);
   protected:
@@ -548,6 +559,7 @@ class SensorDs18b20: public Sensor {
     SensorDs18b20(int child_id, int pin, DallasTemperature* sensors, int index);
     // define what to do at each stage of the sketch
     void onBefore();
+    void onSetup();
     void onLoop();
     void onReceive(const MyMessage & message);
   protected:
@@ -566,6 +578,7 @@ class SensorBH1750: public Sensor {
     SensorBH1750(int child_id);
     // define what to do at each stage of the sketch
     void onBefore();
+    void onSetup();
     void onLoop();
     void onReceive(const MyMessage & message);
   protected:
@@ -582,6 +595,7 @@ class SensorMLX90614: public Sensor {
     SensorMLX90614(int child_id, Adafruit_MLX90614* mlx, int sensor_type);
     // define what to do at each stage of the sketch
     void onBefore();
+    void onSetup();
     void onLoop();
     void onReceive(const MyMessage & message);
   protected:
@@ -599,6 +613,7 @@ class SensorBME280: public Sensor {
     SensorBME280(int child_id, Adafruit_BME280* bme, int sensor_type);
     // define what to do at each stage of the sketch
     void onBefore();
+    void onSetup();
     void onLoop();
     void onReceive(const MyMessage & message);
   protected:
@@ -607,6 +622,61 @@ class SensorBME280: public Sensor {
 };
 #endif
 
+/*
+    SensorMQ
+ */
+class SensorMQ: public Sensor {
+  public:
+    SensorMQ(int child_id, int pin);
+    // define the target gas whose ppm has to be returned. 0: LPG, 1: CO, 2: Smoke (default: 1);
+    void setTargetGas(int value);
+    // define the load resistance on the board, in kilo ohms (default: 1);
+    void setRlValue(float value);
+    // define the Ro resistance on the board (default: 10000);
+    void setRoValue(float value);
+    // Sensor resistance in clean air (default: 9.83);
+    void setCleanAirFactor(float value);
+    // define how many samples you are going to take in the calibration phase (default: 50);
+    void setCalibrationSampleTimes(int value);
+    // define the time interal(in milisecond) between each samples in the cablibration phase (default: 500);
+    void setCalibrationSampleInterval(int value);
+    // define how many samples you are going to take in normal operation (default: 50);
+    void setReadSampleTimes(int value);
+    // define the time interal(in milisecond) between each samples in the normal operations (default: 5);
+    void setReadSampleInterval(int value);
+    // set the LPGCurve array (default: {2.3,0.21,-0.47})
+    void setLPGCurve(float *value);
+    // set the COCurve array (default: {2.3,0.72,-0.34})
+    void setCOCurve(float *value);
+    // set the SmokeCurve array (default: {2.3,0.53,-0.44})
+    void setSmokeCurve(float *value);
+    // define what to do at each stage of the sketch
+    void onBefore();
+    void onSetup();
+    void onLoop();
+    void onReceive(const MyMessage & message);
+  protected:
+    float _rl_value = 1.0;
+    float _ro_clean_air_factor = 9.83;
+    int _calibration_sample_times = 50;
+    int _calibration_sample_interval = 500;
+    int _read_sample_interval = 50;
+    int _read_sample_times = 5;
+    float _ro = 10000.0;
+    float _LPGCurve[3] = {2.3,0.21,-0.47};
+    float _COCurve[3] = {2.3,0.72,-0.34};
+    float _SmokeCurve[3] = {2.3,0.53,-0.44};
+    float _MQResistanceCalculation(int raw_adc);
+    float _MQCalibration();
+    float _MQRead();
+    int _MQGetGasPercentage(float rs_ro_ratio, int gas_id);
+    int  _MQGetPercentage(float rs_ro_ratio, float *pcurve);
+    int _gas_lpg = 0;
+    int _gas_co = 1;
+    int _gas_smoke = 2;
+    int _target_gas = _gas_co;
+};
+
 /***************************************
    NodeManager: manages all the aspects of the node
 */
diff --git a/NodeManager.ino b/NodeManager.ino
index fead15d..4d224b4 100644
--- a/NodeManager.ino
+++ b/NodeManager.ino
@@ -29,7 +29,7 @@ void before() {
   /*
    * Register below your sensors
   */
-
+  nodeManager.registerSensor(SENSOR_MQ,A1);
 
   /*
    * Register above your sensors
diff --git a/README.md b/README.md
index d5a7892..0a92d2e 100644
--- a/README.md
+++ b/README.md
@@ -76,7 +76,7 @@ Those NodeManager's directives in the `config.h` file control which module/libra
 // if enabled, a battery sensor will be created at BATTERY_CHILD_ID and will report vcc voltage together with the battery level percentage
 #define BATTERY_SENSOR 1
 
-// Enable this module to use one of the following sensors: SENSOR_ANALOG_INPUT, SENSOR_LDR, SENSOR_THERMISTOR
+// Enable this module to use one of the following sensors: SENSOR_ANALOG_INPUT, SENSOR_LDR, SENSOR_THERMISTOR, SENSOR_MQ
 #define MODULE_ANALOG_INPUT 1
 // Enable this module to use one of the following sensors: SENSOR_DIGITAL_INPUT
 #define MODULE_DIGITAL_INPUT 1
@@ -196,6 +196,7 @@ SENSOR_HTU21D | HTU21D sensor, return temperature/humidity based on the attached
 SENSOR_BH1750 | BH1750 sensor, return light level in lux
 SENSOR_MLX90614 | MLX90614 contactless temperature sensor, return ambient and object temperature
 SENSOR_BME280 | BME280 sensor, return temperature/humidity/pressure based on the attached BME280 sensor
+SENSOR_MQ | MQ sensor, return ppm of the target gas
 
 To register a sensor simply call the NodeManager instance with the sensory type and the pin the sensor is conncted to. For example:
 ~~~c
@@ -213,6 +214,8 @@ If you want to create a custom sensor and register it with NodeManager so it can
 ~~~c
     // define what to do during before() to setup the sensor
     void onBefore();
+	// define what to do during setup() by executing the sensor's main task
+    void onSetup();
     // define what to do during loop() by executing the sensor's main task
     void onLoop();
     // define what to do during receive() when the sensor receives a message
@@ -258,7 +261,7 @@ The following methods are available for all the sensors:
     void setForceUpdate(int value);
     // the value type of this sensor (default: TYPE_INTEGER)
     void setValueType(int value);
-// for float values, set the float precision (default: 2)
+	// for float values, set the float precision (default: 2)
     void setFloatPrecision(int value);
     // optionally sleep interval in milliseconds before sending each message to the radio network (default: 0)
     void setSleepBetweenSend(int value);
@@ -306,6 +309,32 @@ Each sensor class can expose additional methods.
     void setOffset(float value);
 ~~~
 
+#### SensorMQ
+~~~c
+    // define the target gas whose ppm has to be returned. 0: LPG, 1: CO, 2: Smoke (default: 1);
+    void setTargetGas(int value);
+    // define the load resistance on the board, in kilo ohms (default: 1);
+    void setRlValue(float value);
+    // define the Ro resistance on the board (default: 10000);
+    void setRoValue(float value);
+    // Sensor resistance in clean air (default: 9.83);
+    void setCleanAirFactor(float value);
+    // define how many samples you are going to take in the calibration phase (default: 50);
+    void setCalibrationSampleTimes(int value);
+    // define the time interal(in milisecond) between each samples in the cablibration phase (default: 500);
+    void setCalibrationSampleInterval(int value);
+    // define how many samples you are going to take in normal operation (default: 50);
+    void setReadSampleTimes(int value);
+    // define the time interal(in milisecond) between each samples in the normal operations (default: 5);
+    void setReadSampleInterval(int value);
+    // set the LPGCurve array (default: {2.3,0.21,-0.47})
+    void setLPGCurve(float *value);
+    // set the COCurve array (default: {2.3,0.72,-0.34})
+    void setCOCurve(float *value);
+    // set the SmokeCurve array (default: {2.3,0.53,-0.44})
+    void setSmokeCurve(float *value);
+~~~
+
 #### SensorDigitalOutput / SensorRelay / SensorLatchingRelay
 ~~~c
     // set how to initialize the output (default: LOW)
diff --git a/config.h b/config.h
index e160b1c..70ce7ad 100644
--- a/config.h
+++ b/config.h
@@ -5,8 +5,8 @@
  * Sketch configuration
  */
 
-#define SKETCH_NAME "NodeManagerTemplate"
-#define SKETCH_VERSION "1.3"
+#define SKETCH_NAME "NodeManager"
+#define SKETCH_VERSION "1.4"
 
 /**********************************
  * MySensors configuration
@@ -16,7 +16,7 @@
 //#define MY_NODE_ID 100
 
 #define MY_RADIO_NRF24
-#define MY_RF24_ENABLE_ENCRYPTION
+//#define MY_RF24_ENABLE_ENCRYPTION
 //#define MY_RF24_CHANNEL 76
 
 //#define MY_RADIO_RFM69
@@ -48,7 +48,7 @@
 // if enabled, a battery sensor will be created at BATTERY_CHILD_ID and will report vcc voltage together with the battery level percentage
 #define BATTERY_SENSOR 1
 
-// Enable this module to use one of the following sensors: SENSOR_ANALOG_INPUT, SENSOR_LDR, SENSOR_THERMISTOR
+// Enable this module to use one of the following sensors: SENSOR_ANALOG_INPUT, SENSOR_LDR, SENSOR_THERMISTOR, SENSOR_MQ
 #define MODULE_ANALOG_INPUT 1
 // Enable this module to use one of the following sensors: SENSOR_DIGITAL_INPUT
 #define MODULE_DIGITAL_INPUT 1
-- 
GitLab