diff --git a/NodeManager.cpp b/NodeManager.cpp
index 2f5f832f9649db440247993a2108ed17fea0b0ea..7336b5702b24819a86d7ed4dcb5b9324ef5c6399 100644
--- a/NodeManager.cpp
+++ b/NodeManager.cpp
@@ -2332,6 +2332,108 @@ int SensorMQ::_MQGetPercentage(float rs_ro_ratio, float *pcurve) {
 }
 #endif
 
+
+
+/*
+   SensorMHZ19
+*/
+#if MODULE_MHZ19 == 1
+// contructor
+SensorMHZ19::SensorMHZ19(NodeManager* node_manager, int child_id, int pin): Sensor(node_manager, child_id, pin) {
+  // set presentation, type and value type
+  setPresentation(S_AIR_QUALITY);
+  setType(V_LEVEL);
+  setRxTx(pin, pin+1);
+}
+
+void SensorMHZ19::setRxTx(int rxpin, int txpin) {
+  _rx_pin = rxpin;
+  _tx_pin = txpin;
+}
+
+
+// what to do during before
+void SensorMHZ19::onBefore() {
+}
+
+// what to do during setup
+void SensorMHZ19::onSetup() {
+  _ser = new SoftwareSerial(_rx_pin, _tx_pin);
+  _ser->begin(9600);
+  delay(2000);
+  while (_ser->read()!=-1) {};  // clear CO2 buffer.
+}
+
+// what to do during loop
+void SensorMHZ19::onLoop() {
+  // Read the ppm value
+  int co2ppm = readCO2(); // This is there the function gets called that talks to the Co2 sensor.
+  #if DEBUG == 1
+    Serial.print(F("CO2 I="));
+    Serial.print(_child_id);
+    Serial.print(F(" ppm="));
+    Serial.println(co2ppm);
+  #endif
+  // store the value
+  _value_int = co2ppm;
+}
+
+// Read out the CO2 data
+int SensorMHZ19::readCO2() {
+  while (_ser->read() != -1) {};  //clear serial buffer
+
+  unsigned char response[9]; // for answer
+  byte cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
+
+  // Command to ask for data.
+  _ser->write(cmd, 9); //request PPM CO2
+
+  // Then for 1 second listen for 9 bytes of data.
+  _ser->readBytes(response, 9);
+
+  #if DEBUG == 1
+  for (int i=0; i<9; i++) {
+    Serial.print(response[i], HEX);
+    Serial.print(F("-"));
+  }
+  Serial.println(F("END"));
+  #endif
+
+  if (response[0] != 0xFF) {
+    Serial.println(F("Wrong starting byte from co2 sensor! (should be FF)"));
+    return -1;
+  }
+
+  if (response[1] != 0x86) {
+    Serial.println(F("Wrong command from co2 sensor! (should be 86)"));
+    return -1;
+  }
+
+  int responseHigh = (int) response[2];
+  int responseLow = (int) response[3];
+  int ppm = (256 * responseHigh) + responseLow;
+  
+  return ppm;
+}
+
+
+// what to do as the main task when receiving a message
+void SensorMHZ19::onReceive(const MyMessage & message) {
+  if (message.getCommand() == C_REQ) onLoop();
+}
+
+// what to do when receiving a remote message
+void SensorMHZ19::onProcess(Request & request) {
+  int function = request.getFunction();
+  switch(function) {
+    default: return;
+  }
+  _send(_msg_service.set(function));
+}
+
+#endif
+
+
 /*******************************************
    NodeManager
 */
@@ -2624,6 +2726,11 @@ int NodeManager::registerSensor(int sensor_type, int pin, int child_id) {
       return registerSensor(new SensorMQ(this,child_id, pin));
     }
   #endif
+  #if MODULE_MHZ19 == 1
+    else if (sensor_type == SENSOR_MHZ19) {
+      return registerSensor(new SensorMHZ19(this, child_id, pin));
+    }
+  #endif
   else {
     #if DEBUG == 1
       Serial.print(F("INVALID "));
diff --git a/NodeManager.h b/NodeManager.h
index 46474ba1e6f25316b307d5ca18f3e59e9c959e21..5123a117cf335052c91492dc6f509926d5f4d5a7 100644
--- a/NodeManager.h
+++ b/NodeManager.h
@@ -171,6 +171,10 @@
 #ifndef MODULE_MQ
   #define MODULE_MQ 0
 #endif
+// Enable this module to use one of the following sensors: SENSOR_MHZ19
+#ifndef MODULE_MHZ19
+  #define MODULE_MHZ19 0
+#endif
 
 /***********************************
    Supported Sensors
@@ -260,6 +264,10 @@ enum supported_sensors {
     // MQ2 air quality sensor
     SENSOR_MQ,
   #endif
+  #if MODULE_MHZ19 == 1
+    // MH-Z19 CO2 sensor
+    SENSOR_MHZ19,
+  #endif
 };
 /***********************************
   Libraries
@@ -317,6 +325,9 @@ enum supported_sensors {
   #include <Wire.h>
   #include "Adafruit_MCP9808.h"
 #endif
+#if MODULE_MHZ19 == 1
+  #include <SoftwareSerial.h>
+#endif
 
 /*******************************************************************
    Classes
@@ -1120,6 +1131,30 @@ class SensorMQ: public Sensor {
 };
 #endif
 
+/*
+   SensorMHZ19
+*/
+#if MODULE_MHZ19 == 1
+class SensorMHZ19: public Sensor {
+  public:
+    SensorMHZ19(NodeManager* node_manager, int child_id, int pin);
+    // set the pins for RX and TX of the SoftwareSerial (default: Rx=6, Tx=7)
+    void setRxTx(int rxpin, int txpin);
+    // define what to do at each stage of the sketch
+    void onBefore();
+    void onSetup();
+    void onLoop();
+    void onReceive(const MyMessage & message);
+    void onProcess(Request & request);
+    int readCO2();
+  protected:
+    SoftwareSerial* _ser;
+    int _tx_pin = 6;
+    int _rx_pin = 7;
+};
+#endif
+
+
 /***************************************
    NodeManager: manages all the aspects of the node
 */
diff --git a/README.md b/README.md
index cca7ebe04a2db73f31bfb02d8453762d84816dc1..241491cb4953867521caab9f580acea13659d817 100644
--- a/README.md
+++ b/README.md
@@ -173,6 +173,8 @@ Those NodeManager's directives in the `config.h` file control which module/libra
 #define MODULE_MCP9808 0
 // Enable this module to use one of the following sensors: SENSOR_MQ
 #define MODULE_MQ 0
+// Enable this module to use one of the following sensors: SENSOR_MHZ19
+#define MODULE_MHZ19 0
 ~~~
 
 ### Installing the dependencies
@@ -333,6 +335,7 @@ SENSOR_MCP9808 | MCP9808 sensor, measure the temperature through the attached mo
 SENSOR_RAIN_GAUGE | Rain gauge sensor
 SENSOR_RAIN | Rain sensor, return the percentage of rain from an attached analog sensor
 SENSOR_SOIL_MOISTURE | Soil moisture sensor, return the percentage of moisture from an attached analog sensor
+SENSOR_MHZ19 | MH-Z19 CO2 sensor via UART (SoftwareSerial, default on pins 6(Rx) and 7(Tx)
 
 To register a sensor simply call the NodeManager instance with the sensory type and the pin the sensor is conncted to. For example:
 ~~~c
@@ -585,6 +588,12 @@ Each sensor class can expose additional methods.
     void setLedPin(int value);
 ~~~
 
+* SensorMHZ19
+~~~c
+    // set the RX and TX pins for the software serial port to talk to the sensor
+    void setRxTx(int rxpin, int txpin);
+~~~
+
 ### Upload your sketch
 
 Upload your sketch to your arduino board as you are used to.
@@ -1229,4 +1238,4 @@ v1.5:
 * ESP8266WiFi.h has to be included in the main sketch if MY_GATEWAY_ESP8266 is defined
 * Added receiveTime() wrapper in the main sketch
 * Fixed the logic for output sensors
-* Added common gateway settings in config.h
\ No newline at end of file
+* Added common gateway settings in config.h
diff --git a/config.h b/config.h
index 5fe1facf771e697ed6258b123fe063b0b102d562..0e8878eb2a2b32272c044c4b7dd9a88d74005c01 100644
--- a/config.h
+++ b/config.h
@@ -132,5 +132,7 @@
 #define MODULE_MCP9808 0
 // Enable this module to use one of the following sensors: SENSOR_MQ
 #define MODULE_MQ 0
+// Enable this module to use one of the following sensors: SENSOR_MHZ19
+#define MODULE_MHZ19 0
 #endif