Commit 1087ba0c authored by Reinhold Kainhofer's avatar Reinhold Kainhofer Committed by user2684
Browse files

Added support for the MH-Z19 CO2 sensor (#161)

parent 15a199c9
......@@ -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 "));
......
......@@ -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
*/
......
......@@ -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
......@@ -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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment