Last active
March 22, 2018 13:52
-
-
Save hbcruoma/3ac65ff6985f3081c17271ce7b21b7ac to your computer and use it in GitHub Desktop.
Mkr1000-pohjaisen lämpötilaa, ilmankosteutta (DHT22) ja hiilidioksidipitoisuutta (MH-Z19) mittaavan, proprietary-APIa käyttävän noodin koodi
This file contains 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
/* | |
* MHZ-19 wiring | |
* | |
* Connections: | |
* MH-Z19 MKR1000 | |
* 2(Rx)----D14(Tx) | |
* 3(Tx)----D13(Rx) | |
* 6(Vin)---5V | |
* 7(GND)---GND | |
*/ | |
#include <WiFi101.h> | |
#include <SPI.h> | |
#include <ArduinoHttpClient.h> // https://github.com/arduino-libraries/ArduinoHttpClient | |
#include <SimpleDHT.h> // https://github.com/winlinvip/SimpleDHT | |
#include <jled.h> // https://github.com/jandelgado/jled | |
#include <Adafruit_SleepyDog.h> // https://github.com/adafruit/Adafruit_SleepyDog, requires https://github.com/adafruit/Adafruit_ASFcore | |
//#define TESTENV2 | |
#include "config.h" | |
// WLAN configuration | |
char ssid[] = SSIDNAME; // defined in config.h | |
char pass[] = PASSWORD; // defined in config.h | |
// Node configuration | |
char sensorId[] = SENSORID; // defined in config.h | |
char area[] = AREA; // defined in config.h | |
unsigned long samplingInterval = SAMPLING_INTERVAL; // defined in config.h | |
// DHT22 global definitions | |
#define DHT22PIN 7 | |
SimpleDHT22 dht22; | |
// API configuration | |
char server[] = "api.ruonavaara.fi"; | |
int port = 80; | |
WiFiClient wifi; | |
HttpClient client = HttpClient(wifi, server, port); | |
JLed led = JLed(LED_BUILTIN); | |
void setup() { | |
Serial.begin(9600); | |
delay(1000); // wait for serial port to initialize | |
pinMode(LED_BUILTIN, OUTPUT); | |
// Wifi connection setup | |
wifiConnect(ssid, pass); | |
// MZH-19B setup | |
Serial1.begin(9600); //Initialisierung der seriellen Schnittstelle für den ersten Sensor | |
} | |
int failureCount = 0; | |
void loop() { | |
static unsigned long nextSample = 0; // assigned only the first time! | |
/* | |
// wait for next sample | |
if (millis() < nextSample) { | |
led.Update(); | |
return; | |
} | |
*/ | |
Serial.println("***************************************************************************************************"); | |
Serial.println("Get new sample..."); | |
// stop breathing indicator | |
led.Off().Update(); | |
// Read DHT22 | |
Serial.println("Read DHT22..."); | |
float temperature = 0; | |
float humidity = 0; | |
int err = SimpleDHTErrSuccess; | |
if ((err = dht22.read2(DHT22PIN, &temperature, &humidity, NULL)) != SimpleDHTErrSuccess) { | |
Serial.print("Read DHT22 failed, err="); Serial.println(err); delay(2000); | |
} else { | |
Serial.print("DHT22 sample OK: "); | |
Serial.print((float)temperature); Serial.print(" *C, "); | |
Serial.print((float)humidity); Serial.println(" RH%"); | |
} | |
// Read MH-Z19B | |
Serial.println("Read MH-Z19..."); | |
byte com[] = {0xff, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; //Befehl zum Auslesen der CO2 Konzentration | |
byte return1[9]; //hier kommt der zurückgegeben Wert des ersten Sensors rein | |
while (Serial1.available() > 0) { //Hier wird der Buffer der Seriellen Schnittstelle gelehrt | |
Serial1.read(); | |
} | |
Serial1.write(com, 9); //Befehl zum Auslesen der CO2 Konzentration | |
Serial1.readBytes(return1, 9); //Auslesen der Antwort | |
int concentration = 0; //CO2-Konzentration des Sensors | |
if (getCheckSum(return1) != return1[8]) { | |
Serial.println("Checksum error"); | |
} else { | |
concentration = return1[2] * 256 + return1[3]; //Berechnung der Konzentration | |
Serial.print("MH-Z19 sample OK: "); | |
Serial.print(concentration); ; Serial.println(" ppm"); | |
} | |
// send to API | |
led.On().Update(); | |
Serial.println("Sending..."); | |
/* | |
if (WiFi.status() != WL_CONNECTED) { | |
Serial.print("WiFi connection lost, status: "); Serial.println(WiFi.status()); | |
Serial.println("Reconnecting..."); | |
WiFi.end(); | |
wifiConnect(ssid, pass); | |
} | |
*/ | |
String data = apiFormat(sensorId, temperature, humidity, concentration); | |
String endpoint = String("/iot/area/") + area + String("/"); | |
String contentType = "application/json"; | |
Serial.print("Data: "); Serial.println(data); | |
Serial.print("Endpoint: "); Serial.println(endpoint); | |
Watchdog.enable(30000); | |
client.post(endpoint, contentType, data); | |
Watchdog.disable(); | |
// read the status code and body of the response | |
int statusCode = client.responseStatusCode(); | |
String response = client.responseBody(); | |
Serial.print("Status code: "); Serial.println(statusCode); | |
Serial.print("Response: "); Serial.println(response); | |
led.Off().Update(); | |
delay(500); | |
// success indication | |
if (statusCode > 0) { | |
led.On().Update(); | |
delay(1000); | |
led.Off().Update(); | |
failureCount = 0; | |
} else { | |
Serial.println("Connection failure"); | |
failureCount++; | |
if (failureCount >= 3) { // force reset after three failed requests | |
Serial.println("Reboot to revive connection"); | |
Watchdog.enable(); | |
led.Blink(100, 100).Forever(); | |
while(true) { | |
led.Update(); | |
} | |
} | |
} | |
/* | |
// time for next update | |
nextSample = nextSample + (((millis() - nextSample) / samplingInterval) + 1) * samplingInterval; | |
*/ | |
nextSample = millis() + samplingInterval; | |
Serial.print("Time now "); Serial.print(millis()); Serial.print(", next sample at "); Serial.println(nextSample); | |
Serial.flush(); | |
// close connections to force reconnection | |
client.stop(); | |
WiFi.end(); | |
// setup breathing indicator | |
led.Breathe(5000).Forever(); | |
while (millis() < nextSample) { | |
led.Update(); | |
} | |
Watchdog.enable(10); | |
delay(1000); | |
} | |
void wifiConnect(char ssid[], char pass[]) { | |
Serial.print("Connecting to network "); | |
Serial.println(ssid); | |
int status = WL_IDLE_STATUS; | |
unsigned long retry = millis(); | |
while (status != WL_CONNECTED) { | |
if (millis() > retry) { | |
led.Blink(100, 100).Forever().Update(); | |
retry += 20000; | |
status = WiFi.begin(ssid, pass); | |
Serial.print("."); | |
} | |
led.Update(); | |
} | |
Serial.println(); | |
led.Off().Update(); | |
printCurrentNet(); | |
printWifiData(); | |
} | |
byte getCheckSum(byte *packet) | |
{ | |
byte checksum = 0; | |
for ( int i = 1; i < 8; i++) | |
{ | |
checksum += packet[i]; | |
} | |
checksum = 0xFF - checksum; | |
checksum += 1; | |
return checksum; | |
} | |
void printCurrentNet() { | |
Serial.print("Connected to network "); | |
Serial.println(WiFi.SSID()); | |
} | |
void printWifiData() { | |
IPAddress ip = WiFi.localIP(); | |
Serial.print("IP address: "); | |
Serial.println(ip); | |
byte mac[6]; | |
WiFi.macAddress(mac); | |
Serial.print("MAC address: "); | |
Serial.print(mac[5], HEX); | |
Serial.print(":"); | |
Serial.print(mac[4], HEX); | |
Serial.print(":"); | |
Serial.print(mac[3], HEX); | |
Serial.print(":"); | |
Serial.print(mac[2], HEX); | |
Serial.print(":"); | |
Serial.print(mac[1], HEX); | |
Serial.print(":"); | |
Serial.println(mac[0], HEX); | |
} | |
String apiFormat (String sensorId, float temp, float hum, int co2) { | |
String json = "{ \"sensorId\": \""; | |
json += sensorId; | |
json += "\", \"data\": { \"temperature\": "; | |
json += temp; | |
json += ", \"humidity\": "; | |
json += hum; | |
json += ", \"CO2\": "; | |
json += co2; | |
json += " }}"; | |
return json; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Mkr1000:n WLAN-puolella on jokin bugi, jonka takia requestit lakkaavat jossain vaiheessa kulkemasta. Siksi tässä ohjelmassa on niin monin paikoin watchdog-resettejä.