Created
February 3, 2018 19:44
-
-
Save diplix/9b06bb0853e04a34e70afd81ac6ab796 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* The MySensors Arduino library handles the wireless radio link and protocol | |
* between your home built sensors/actuators and HA controller of choice. | |
* The sensors forms a self healing radio network with optional repeaters. Each | |
* repeater and gateway builds a routing tables in EEPROM which keeps track of the | |
* network topology allowing messages to be routed to nodes. | |
* | |
* Created by Henrik Ekblad <[email protected]> | |
* Copyright (C) 2013-2015 Sensnology AB | |
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors | |
* | |
* Documentation: http://www.mysensors.org | |
* Support Forum: http://forum.mysensors.org | |
* | |
* This program is free software; you can redistribute it and/or | |
* modify it under the terms of the GNU General Public License | |
* version 2 as published by the Free Software Foundation. | |
* | |
******************************* | |
* | |
* DESCRIPTION | |
* | |
* MH-Z19 CO2 sensor | |
* | |
* It communicates with your board over serial at 9600 speed. | |
* | |
* | |
* | |
*/ | |
//------------------------------------------------------------------------------ | |
// if you uncomment this, you can get test and debug updates about the sensor' wireless connection by using the serial monitor tool. | |
#define MY_DEBUG | |
// Enable and select radio type attached | |
#define MY_RADIO_NRF24 // A 2.4Ghz transmitter and receiver, often used with MySensors. | |
// #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. | |
// #define MY_RADIO_RFM69 // 433Mhz transmitter and reveiver. | |
// Choose if you want this sensor to also be a repeater. | |
// #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. | |
#define MY_TRANSPORT_WAIT_READY_MS 3000 | |
// Libraries | |
#include <MySensors.h> | |
#include <SoftwareSerial.h> | |
// This can be changed: | |
boolean switch_on = true; | |
#define RED_LED_PIN 6 // Arduino pin attached to MOSFET Gate pin | |
#define GREEN_LED_PIN 5 // Arduino pin attached to MOSFET Gate pin | |
long co2ppm = 400; | |
unsigned long co2MeasurementInterval = 30000; // Time to wait between reads (in milliseconds). | |
bool initialValueSent = false; | |
//SoftwareSerial mySerial(6, 7); // RX, TX . You can choose other pins if you prefer. | |
SoftwareSerial mySerial(2, 3); // RX, TX . You can choose other pins if you prefer. | |
//SoftwareSerial mySerial(2, 3, true); // RX, TX . You can choose other pins if you prefer. | |
// Mysensors settings | |
#define CHILD_ID_CO2 0 // The Co2 sensor' ID on this node. | |
#define CHILD_ID_SWITCH 1 // The Co2 sensor' ID on this node. | |
MyMessage msgCo2(CHILD_ID_CO2, V_LEVEL); | |
MyMessage msgCo2b(CHILD_ID_CO2, V_UNIT_PREFIX); | |
MyMessage switchMsg(CHILD_ID_SWITCH, V_STATUS); | |
void presentation() | |
{ | |
// Send the sketch version information to the gateway and Controller | |
sendSketchInfo("AIQ Sensor CO2 MH-Z19", "1.2"); | |
// Register attached sensor(s) to gateway | |
present(CHILD_ID_CO2, S_AIR_QUALITY); | |
send(msgCo2b.set("ppm")); | |
present(CHILD_ID_SWITCH, S_BINARY); | |
send(switchMsg.set(switch_on)); | |
} | |
void setup() | |
{ | |
pinMode(RED_LED_PIN, OUTPUT); // Tell Arduino that redLEDPin is an output pin | |
pinMode(GREEN_LED_PIN, OUTPUT); //Tell Arduino that yellowLEDPin is an output pin | |
analogWrite(GREEN_LED_PIN, 10); | |
analogWrite(RED_LED_PIN, 0); | |
delay(1000); | |
Serial.begin(115200); | |
delay(3000); | |
mySerial.begin(9600); | |
delay(3000); | |
while (mySerial.read()!=-1) {}; //clear Co2 buffer. | |
Serial.println("hello world, I am a sensor."); | |
} | |
void loop() | |
{ | |
if (!initialValueSent) { | |
Serial.println("Sending initial value"); | |
//send(msgCo2.set((long)ceil(400))); | |
send(msgCo2b.set("ppm")); | |
send(switchMsg.set(switch_on)); // send feedback, really? | |
initialValueSent = true; | |
} | |
// You should not change these variables: | |
static unsigned long previousCo2Millis = 0; // Used to remember the time of the last temperature measurement. | |
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. | |
if (currentMillis - previousCo2Millis >= co2MeasurementInterval) { // this only gets triggered when enough time has passed. | |
Serial.println("CO2 - Sending data request to sensor."); | |
previousCo2Millis = currentMillis; | |
//long co2ppm = readCO2(); | |
co2ppm = readCO2(); | |
Serial.println("Co2 - PPM = " + String(co2ppm)); | |
if (co2ppm != -1) { | |
send(msgCo2.set((long)ceil(co2ppm))); | |
set_lights(co2ppm); | |
} | |
Serial.print("Co2 - zzzzZZZZzzzzZZZZzzzz\n"); | |
} | |
} | |
// Main function that gets the Co2 data | |
int readCO2() | |
{ | |
while (mySerial.read()!=-1) {}; //clear serial buffer | |
char response[9]; // for answer | |
byte cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; | |
//byte cmd[]={0xff,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79}; //Befehl zum Auslesen der CO2 Konzentration | |
// The serial stream can get out of sync. The response starts with 0xff, try to resync. | |
while (mySerial.available() > 0 && (unsigned char)mySerial.peek() != 0xFF) { | |
mySerial.read(); | |
} | |
memset(response, 0, 9); | |
// command to ask for data | |
mySerial.write(cmd, 9); //request PPM CO2 | |
mySerial.readBytes(response, 9); | |
Serial.print(" - "); | |
Serial.print(response[0], HEX); | |
Serial.print(" - "); | |
Serial.print(response[1], HEX); | |
Serial.print(" - "); | |
Serial.print(response[2], HEX); | |
Serial.print(" - "); | |
Serial.print(response[3], HEX); | |
Serial.print(" - "); | |
Serial.print(response[4], HEX); | |
Serial.print(" - "); | |
Serial.print(response[5], HEX); | |
Serial.print(" - "); | |
Serial.print(response[6], HEX); | |
Serial.print(" - "); | |
Serial.print(response[7], HEX); | |
Serial.print(" - "); | |
Serial.print(response[8], HEX); | |
Serial.println(" - END"); | |
/* | |
Serial.print(" - "); | |
Serial.print(unsigned(response[0]), HEX); | |
Serial.print(" - "); | |
Serial.print(unsigned(response[1]), HEX); | |
Serial.print(" - "); | |
Serial.print(unsigned(response[2]), HEX); | |
Serial.print(" - "); | |
Serial.print(unsigned(response[3]), HEX); | |
Serial.print(" - "); | |
Serial.print(unsigned(response[4]), HEX); | |
Serial.print(" - "); | |
Serial.print(unsigned(response[5]), HEX); | |
Serial.print(" - "); | |
Serial.print(unsigned(response[6]), HEX); | |
Serial.print(" - "); | |
Serial.print(unsigned(response[7]), HEX); | |
Serial.print(" - "); | |
Serial.print(unsigned(response[8]), HEX); | |
Serial.println(" - END"); | |
*/ | |
if (response[0] != 0xFFFFFFFF) | |
{ | |
Serial.println("Wrong starting byte from co2 sensor! (should be FF)"); | |
return -1; | |
} | |
if (response[1] != 0xFFFFFF86) | |
{ | |
Serial.println("Wrong command from co2 sensor! (should be 86)"); | |
return -1; | |
} | |
int responseHigh = (int) response[2]; | |
int responseLow = (int) response[3]; | |
Serial.print("high: "); | |
Serial.print(responseHigh); | |
Serial.print(" low: "); | |
Serial.println(responseLow); | |
//if (responseLow >= 256) { int responseLow = responseLow - 256; } | |
if (responseLow < 0) { responseLow = responseLow + 256; } | |
if (responseLow == 0) { return -1; } | |
int ppm = (256 * responseHigh) + responseLow; | |
return ppm; | |
} | |
void receive(const MyMessage &message) | |
{ | |
// We only expect one type of message from controller. But we better check anyway. | |
if (message.type==V_STATUS) { | |
switch_on = message.getBool(); | |
set_lights(co2ppm); | |
// Store state in eeprom | |
//saveState(message.sensor, message.getBool()); | |
// Write some debug info | |
Serial.print("Incoming change for sensor:"); | |
Serial.print(message.sensor); | |
Serial.print(", New status: "); | |
Serial.println(message.getBool()); | |
send(switchMsg.set(switch_on)); // send feedback, really? | |
} | |
} | |
void set_lights(int co2ppm) | |
{ | |
if (switch_on) { | |
// do stuff to LEDs | |
/* | |
* < 1000 behaglich | |
* > 2000 deutlich unbehaglich | |
* 1500 grenzwert wohnräume | |
* > 5000 möglich | |
* < 1500 optimal | |
*/ | |
if (co2ppm <= 1000) { | |
analogWrite(RED_LED_PIN, 0); | |
analogWrite(GREEN_LED_PIN, 10); | |
} | |
if (co2ppm > 1000 && co2ppm <= 1500) { | |
analogWrite(RED_LED_PIN, 3); | |
analogWrite(GREEN_LED_PIN, 3); | |
} | |
if (co2ppm > 1500) { | |
analogWrite(RED_LED_PIN, 10); | |
analogWrite(GREEN_LED_PIN, 0); | |
} | |
} | |
else { | |
// turn off LEDs | |
analogWrite(RED_LED_PIN, 0); | |
analogWrite(GREEN_LED_PIN, 0); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment