Created
November 22, 2018 00:22
-
-
Save dt/76f1b7ffaee59af9f70a949ec0365eb5 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
#include <ESP8266WiFi.h> | |
#include <WiFiClient.h> | |
#include <ESP8266mDNS.h> | |
#include <ESP8266HTTPClient.h> | |
#include <ESP8266WebServer.h> | |
#include <ArduinoOTA.h> | |
#include <SoftwareSerial.h> | |
byte cmdRead[2] = {0x86, 0x00}; | |
byte cmdCalibrateZero[2] = {0x87, 0x00}; | |
byte cmdEnableABC[2] = {0x79, 0xA0}; | |
byte cmdDisableABC[2] = {0x79, 0x00}; | |
byte cmdReset[2] = {0x8d, 0x00}; | |
const int rx_pin = 4; | |
const int tx_pin = 5; | |
SoftwareSerial sensor(rx_pin, tx_pin, false, 256); | |
const char* ssid = "<my-wifi-ssid>"; | |
const char* password = "<my-wifi-password>"; | |
ESP8266WebServer server ( 80 ); | |
HTTPClient http; | |
void setup(void) | |
{ | |
Serial.begin(115200); | |
delay(100); | |
sensor.begin(9600); // init CO2 sensor serial port | |
WiFi.mode(WIFI_STA); | |
WiFi.begin(ssid, password); | |
Serial.println(""); | |
while (WiFi.status() != WL_CONNECTED) { | |
delay(500); | |
Serial.print("."); | |
} | |
Serial.println(""); | |
Serial.print("Connected to "); | |
Serial.println(ssid); | |
Serial.print("IP address: "); | |
Serial.println(WiFi.localIP()); | |
server.on ( "/", handleRoot ); | |
server.begin(); | |
Serial.println("webserver started"); | |
MDNS.addService("http", "tcp", 80); | |
ArduinoOTA.setHostname("sniffer"); | |
ArduinoOTA.begin(); | |
delay(5000); | |
sendCmd(cmdDisableABC); | |
} | |
void handleRoot() { | |
String page = String( | |
"<html><head><meta charset='utf-8'/>" | |
"<meta http-equiv=\"refresh\" content=\"60\" />" | |
"<title>Sniffer</title>" | |
"<link href='https://fonts.googleapis.com/icon?family=Material+Icons' rel='stylesheet'/>" | |
"<style>" | |
"body { font-family: Helvetica, Arial, Sans-Serif; background-color: #eee; }" | |
"</style>" | |
"<meta name='viewport' content='width = device-width, initial-scale = 1.0, maximum-scale = 1.0, user-scalable=0'>" | |
"</head>" | |
"<body>\n" | |
"<div class='sniffer'>\n" | |
"<p>CO2: "+String(sendCmd(cmdRead)) +" ppm </p>" | |
"</div>" // /stc | |
"</body></html>" | |
); | |
server.send(200, "text/html", page); | |
} | |
void logToInflux() { | |
int ppm = sendCmd(cmdRead); | |
Serial.print("CO2: "); | |
Serial.print(ppm); | |
Serial.println("ppm"); | |
if (ppm < 1) { | |
return; | |
} | |
http.begin("<my-logging-service>"); | |
int httpCode = http.POST(String("co2 ppm="+String(ppm))); | |
if(httpCode > 299) { | |
Serial.print("Reply("); | |
Serial.print(httpCode); | |
Serial.print("): "); | |
Serial.print(http.getString()); | |
} | |
http.end(); | |
} | |
unsigned long lastReport; | |
unsigned long nextReport; | |
uint32 ticks; | |
void loop() { | |
ArduinoOTA.handle(); | |
server.handleClient(); | |
ticks++; | |
if (ticks > 10000) { | |
ticks = 0; | |
unsigned long now = millis(); | |
if (now > nextReport || now < lastReport) { | |
nextReport = now + 1000 * 30; | |
logToInflux(); | |
lastReport = now; | |
} | |
} | |
} | |
byte checksum(byte *array) | |
{ | |
byte checksum = 0; | |
for (byte i = 1; i < 8; i++) | |
checksum+=array[i]; | |
checksum = 0xFF - checksum; | |
return (checksum+1); | |
} | |
unsigned int sendCmd(byte* cmd) { | |
byte req[9]; | |
memset(req, 0, 9); | |
req[0] = 0xFF; | |
req[1] = 0x01; | |
req[2] = cmd[0]; | |
req[3] = cmd[1]; | |
req[8] = checksum(req); | |
bool header_found = false; | |
sensor.write(req, 9); | |
if (cmd[0] != cmdRead[0]) { | |
return 0; | |
} | |
// read until we see the first two bytes of the reply. | |
while (sensor.available() && (!header_found)) { | |
if (sensor.read() == 0xff ) { | |
if (sensor.read() == 0x86 ) { | |
header_found = true; | |
} | |
} | |
} | |
if (!header_found) { | |
Serial.println("conn closed before header not found"); | |
return 0; | |
} | |
// already read first two bytes while looking for the beginning so | |
// a) put those in the buffer so the checksum matches | |
// b) read the remaining 9-2=7 bytes into the buffer. | |
unsigned char resp[9]; | |
memset(resp, 0, 9); | |
resp[0] = 0xff; | |
resp[1] = 0x86; | |
sensor.readBytes(&resp[2], 7); | |
// Check that the checksum matches. | |
byte crc = checksum(resp); | |
if ( !(resp[8] == crc) ) { | |
Serial.println(String("CO2: CRC error: ") + String(crc) + String(" vs ") + String(resp[8])); | |
return 0; | |
} | |
// Compute the result. | |
unsigned int ppmHigh = (unsigned int) resp[2]; | |
unsigned int ppmLow = (unsigned int) resp[3]; | |
unsigned int ppm = (256 * ppmHigh) + ppmLow; | |
return ppm; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment