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