Skip to content

Commit ed03cf5

Browse files
authored
Merge pull request mysensors#26 from flatsiedatsie/patch-4
MH-Z19 CO2 sensor example
2 parents 124c03c + 3ba2629 commit ed03cf5

File tree

1 file changed

+149
-0
lines changed

1 file changed

+149
-0
lines changed

examples/MH-Z19 CO2 sensor

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/*
2+
* The MySensors Arduino library handles the wireless radio link and protocol
3+
* between your home built sensors/actuators and HA controller of choice.
4+
* The sensors forms a self healing radio network with optional repeaters. Each
5+
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
6+
* network topology allowing messages to be routed to nodes.
7+
*
8+
* Created by Henrik Ekblad <[email protected]>
9+
* Copyright (C) 2013-2015 Sensnology AB
10+
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
11+
*
12+
* Documentation: http://www.mysensors.org
13+
* Support Forum: http://forum.mysensors.org
14+
*
15+
* This program is free software; you can redistribute it and/or
16+
* modify it under the terms of the GNU General Public License
17+
* version 2 as published by the Free Software Foundation.
18+
*
19+
*******************************
20+
*
21+
* DESCRIPTION
22+
*
23+
* MH-Z19 CO2 sensor
24+
*
25+
* This sensor measures Co2 levels. It's pretty good for the price.
26+
*
27+
*/
28+
29+
30+
//------------------------------------------------------------------------------
31+
32+
// if you uncomment this, you can get test and debug updates about the sensor' wireless connection by using the serial monitor tool.
33+
#define MY_DEBUG
34+
35+
// Enable and select radio type attached
36+
#define MY_RADIO_NRF24 // A 2.4Ghz transmitter and receiver, often used with MySensors.
37+
// #define MY_RF24_PA_LEVEL RF24_PA_MIN // This sets a low-power mode for the radio. Useful if you use the verison with the bigger antenna, but don't want to power that from a separate power source. It can also fix problems with fake Chinese versions of the radio.
38+
// #define MY_RADIO_RFM69 // 433Mhz transmitter and reveiver.
39+
40+
// Choose if you want this sensor to also be a repeater.
41+
// #define MY_REPEATER_FEATURE // Just remove the two slashes at the beginning of this line to also enable this sensor to act as a repeater for other sensors. If this node is on battery power, you probably shouldn't enable this.
42+
43+
44+
// Libraries
45+
#include <MySensors.h>
46+
#include <SoftwareSerial.h>
47+
48+
49+
// Feel free to change this:
50+
unsigned long co2MeasurementInterval = 30000; // Time to wait between reads (in milliseconds).
51+
SoftwareSerial mySerial(10, 11); // RX, TX . You can choose other pins if you prefer.
52+
53+
54+
// Mysensors settings
55+
#define CHILD_ID_CO2 0 // The Co2 sensor' ID on this node.
56+
MyMessage msgCo2(CHILD_ID_CO2, V_LEVEL);
57+
MyMessage msgCo2b(CHILD_ID_CO2, V_UNIT_PREFIX);
58+
59+
60+
void presentation()
61+
{
62+
// Send the sketch version information to the gateway and Controller
63+
sendSketchInfo("AIQ Sensor CO2 MH-Z19", "1.1");
64+
65+
// Register attached sensor(s) to gateway
66+
present(CHILD_ID_CO2, S_AIR_QUALITY);
67+
send(msgCo2b.set("ppm"));
68+
}
69+
70+
71+
void setup()
72+
{
73+
delay(1000);
74+
Serial.begin(115200);
75+
delay(1000);
76+
77+
mySerial.begin(9600);
78+
delay(2000);
79+
while (mySerial.read()!=-1) {}; //clear Co2 buffer.
80+
Serial.println("hello world, I am a sensor.");
81+
}
82+
83+
84+
void loop()
85+
{
86+
// You should not change these variables:
87+
static unsigned long previousCo2Millis = 0; // Used to remember the time of the last temperature measurement.
88+
unsigned long currentMillis = millis(); // The time since the sensor started, counted in milliseconds. This script tries to avoid using the Sleep function, so that it could at the same time be a MySensors repeater.
89+
90+
if (currentMillis - previousCo2Millis >= co2MeasurementInterval) { // this only gets triggered when enough time has passed.
91+
Serial.println("CO2 - Sending data request to sensor.");
92+
previousCo2Millis = currentMillis;
93+
long co2ppm = readCO2(); // This is there the function gets called that talks to the Co2 sensor.
94+
Serial.println("Co2 - PPM = " + String(co2ppm));
95+
send(msgCo2.set((long)ceil(co2ppm)));
96+
Serial.print("Co2 - zzzzZZZZzzzzZZZZzzzz\n");
97+
}
98+
}
99+
100+
101+
// Main function that gets the Co2 data
102+
int readCO2()
103+
{
104+
while (mySerial.read()!=-1) {}; //clear serial buffer
105+
106+
char response[9]; // for answer
107+
byte cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
108+
109+
// Command to ask for data.
110+
mySerial.write(cmd, 9); //request PPM CO2
111+
112+
// Then for 1 second listen for 9 bytes of data.
113+
mySerial.readBytes(response, 9);
114+
115+
Serial.print(response[0], HEX);
116+
Serial.print(" - ");
117+
Serial.print(response[1], HEX);
118+
Serial.print(" - ");
119+
Serial.print(response[2], HEX);
120+
Serial.print(" - ");
121+
Serial.print(response[3], HEX);
122+
Serial.print(" - ");
123+
Serial.print(response[4], HEX);
124+
Serial.print(" - ");
125+
Serial.print(response[5], HEX);
126+
Serial.print(" - ");
127+
Serial.print(response[6], HEX);
128+
Serial.print(" - ");
129+
Serial.print(response[7], HEX);
130+
Serial.print(" - ");
131+
Serial.print(response[8], HEX);
132+
Serial.println(" - END");
133+
134+
if (response[0] != 0xFF) {
135+
Serial.println("Wrong starting byte from co2 sensor! (should be FF)");
136+
return -1;
137+
}
138+
139+
if (response[1] != 0x86) {
140+
Serial.println("Wrong command from co2 sensor! (should be 86)");
141+
return -1;
142+
}
143+
144+
int responseHigh = (int) response[2];
145+
int responseLow = (int) response[3];
146+
int ppm = (256 * responseHigh) + responseLow;
147+
148+
return ppm;
149+
}

0 commit comments

Comments
 (0)