Last active
March 30, 2019 20:58
-
-
Save dt/f730abebb7c212fe71288057bd50fa13 to your computer and use it in GitHub Desktop.
google logging co2 sensor
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 "HTTPSRedirect.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 = ""; | |
const char* password = ""; | |
ESP8266WebServer server ( 80 ); | |
const char* googleHost = "script.google.com"; | |
const char *GScriptId = "AKfycbzbWIhqi9Dd2ofP7-OA8i2xWcDNyjFbPUMKcaLIKP-XWrhTn_Mo"; | |
String googleUrl = String("/macros/s/") + GScriptId + "/exec"; | |
// echo | openssl s_client -connect script.google.com:443 |& openssl x509 -fingerprint -noout | |
const char* fingerprint = "C2:00:62:1D:F7:ED:AF:8B:D1:D5:1D:24:D6:F0:A1:3A:EB:F1:B4:92"; | |
// Write to Google Spreadsheet | |
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("co2"); | |
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 logToGoogle() { | |
int ppm = sendCmd(cmdRead); | |
Serial.print("CO2: "); | |
Serial.print(ppm); | |
Serial.println("ppm"); | |
if (ppm < 1) { | |
return; | |
} | |
HTTPSRedirect* client = new HTTPSRedirect(); | |
client->setPrintResponseBody(true); | |
client->setContentTypeHeader("application/json"); | |
client->connect(googleHost, 443); | |
client->POST(googleUrl, googleHost, String("{\"co2\": "+String(ppm)+"}"), true); | |
delete client; | |
} | |
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; | |
logToGoogle(); | |
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