-
-
Save ma2shita/8089f4e418e322ff47a1454b3bb53ceb to your computer and use it in GitHub Desktop.
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
#define __VERSION__ "1.0.6" | |
#define _LOOP_INTERVAL (1000) /* ms / using in `delay()` in `loop()` */ | |
#define _EXEC_INTERVAL (3 * 60) /* sec */ | |
#define _O2_SENSOR_PIN (WIOLTE_A6) | |
#define _INTERRUPT_BUTTON_PIN (WIOLTE_D38) | |
#define ARDUINOJSON_USE_DOUBLE 1 /* for high precision float */ | |
#include <ArduinoJson.h> /* 5.13.2 (don't use 6.x) */ | |
StaticJsonBuffer<1024> jsonBuffer; | |
#include <WioLTEforArduino.h> | |
WioLTE Wio; | |
#include "Seeed_BME280.h" | |
#include <Wire.h> | |
BME280 bme280; | |
HardwareSerial* GpsSerial; | |
#include "TinyGPS++.h" | |
TinyGPSPlus TinyGPS; | |
void pin_interrupt(); | |
void add_tmpr_humd_pres_alt_by_bme280(JsonObject &payload); | |
void add_geo_timestamp_by_gps(JsonObject &payload); | |
void add_o2_by_o2(JsonObject &json); | |
void send_to_soracom_with_ondemand(const char *payload); | |
void main_line(const char *event_src); | |
void setup() { | |
delay(500); | |
SerialUSB.println(); | |
SerialUSB.println(__VERSION__); | |
/* for Wio LTE */ | |
Wio.Init(); | |
Wio.PowerSupplyGrove(true); | |
delay(500); | |
/* for Grove BME280 */ | |
if(!bme280.init()){ | |
SerialUSB.println("BME280 error!"); | |
Wio.SystemReset(); | |
return; | |
} | |
SerialUSB.println("BEM280 ready"); | |
/* for Grove GPS */ | |
GpsSerial = &Serial; | |
GpsSerial->begin(9600); | |
while(!GpsSerial->available()); | |
SerialUSB.println("GPS ready"); | |
/* for Grove O2 Gas */ | |
pinMode(_O2_SENSOR_PIN, INPUT_ANALOG); | |
/* for Working check */ | |
pinMode(_INTERRUPT_BUTTON_PIN, INPUT); | |
attachInterrupt(_INTERRUPT_BUTTON_PIN, pin_interrupt, RISING); | |
} | |
volatile unsigned long perfome_counter = 0; | |
volatile int loop_counter = 0; | |
void loop() { | |
SerialUSB.print("."); | |
if (loop_counter > _EXEC_INTERVAL - 1) { | |
SerialUSB.println(); | |
main_line("loop"); | |
loop_counter = 0; | |
} | |
loop_counter++; | |
delay(_LOOP_INTERVAL); | |
} | |
void main_line(const char *event_src) { | |
/* required ArduinoJson */ | |
SerialUSB.println("main_line()"); | |
detachInterrupt(_INTERRUPT_BUTTON_PIN); /* avoiding other interrupt */ | |
JsonObject& json = jsonBuffer.createObject(); | |
perfome_counter++; | |
json["perfome_counter"] = perfome_counter; | |
json["event_src"] = event_src; | |
add_tmpr_humd_pres_alt_by_bme280(json); | |
add_geo_timestamp_by_gps(json); | |
add_o2_by_o2(json); | |
char payload[1024]; | |
json.printTo(payload, sizeof(payload)); | |
jsonBuffer.clear(); | |
SerialUSB.println(payload); | |
send_to_soracom_with_ondemand(payload); | |
attachInterrupt(_INTERRUPT_BUTTON_PIN, pin_interrupt, RISING); /* resume */ | |
} | |
void pin_interrupt() { | |
SerialUSB.println("pin_interrupt()"); | |
main_line("pin_interrupt"); | |
loop_counter = 0; | |
} | |
void send_to_soracom_with_ondemand(const char *payload) { | |
SerialUSB.println("send_to_soracom_with_ondemand()"); | |
/* required WioLTEforArduino */ | |
const char *host = "http://harvest.soracom.io"; | |
Wio.PowerSupplyLTE(true); | |
delay(500); | |
if (!Wio.TurnOnOrReset()) { SerialUSB.println("TurnOnOrReset Error"); goto comm_error; } | |
if (!Wio.Activate("soracom.io", "sora", "sora")) { SerialUSB.println("Activate Error"); goto comm_error; } | |
int status; | |
if (!Wio.HttpPost(host, payload, &status)) { SerialUSB.println("### ERROR! ###"); goto comm_error; } | |
SerialUSB.println(status); | |
Wio.Deactivate(); | |
comm_error: | |
Wio.PowerSupplyLTE(false); | |
} | |
void add_tmpr_humd_pres_alt_by_bme280(JsonObject &json) { | |
/* required ArduinoJson, Seeed_BME280 */ | |
json["tmpr_c"] = bme280.getTemperature(); // C | |
json["humd_percent"] = bme280.getHumidity(); // % | |
json["pres_hpa"] = bme280.getPressure() / 100.0; // hPa | |
} | |
void add_geo_timestamp_by_gps(JsonObject &json) { | |
/* required ArduinoJson, TinyGPS++ */ | |
int retry_cnt = 0; | |
gps_parse_retry: | |
while(GpsSerial->available()) TinyGPS.encode(GpsSerial->read()); | |
if (!TinyGPS.location.isValid()) { | |
if (retry_cnt > 1000) { | |
json["geo_src"] = "NONE"; | |
return; | |
} | |
retry_cnt++; | |
goto gps_parse_retry; | |
} | |
json["geo_src"] = "GPS"; | |
json["lat"] = TinyGPS.location.lat(); | |
json["lng"] = TinyGPS.location.lng(); | |
json["alt_m"] = TinyGPS.altitude.meters(); | |
struct tm t; | |
t.tm_year = TinyGPS.date.year() - 1900; | |
t.tm_mon = TinyGPS.date.month() - 1; | |
t.tm_mday = TinyGPS.date.day(); | |
t.tm_hour = TinyGPS.time.hour(); | |
t.tm_min = TinyGPS.time.minute(); | |
t.tm_sec = TinyGPS.time.second(); | |
t.tm_isdst= -1; | |
time_t epoch = mktime(&t); | |
json["timestamp"] = epoch; | |
} | |
void add_o2_by_o2(JsonObject &json) { | |
/* required ArduinoJson */ | |
long sum = 0; | |
for(int i=0; i < 32; i++) { | |
sum += analogRead(_O2_SENSOR_PIN); | |
} | |
sum >>= 5; /* Average 32 times of analogRead */ | |
float MeasuredVout = map(sum, 0, 4095, 0, 3300) / 1000.0; /* Wio LTE ADC is 12 bit, ref V is 3.3 */ | |
float Concentration = MeasuredVout * 0.21 / 2.0; /* https://www.seeedstudio.com/Grove-Oxygen-Sensor%28ME2-O2-%D0%A420%29-p-1541.html 25%--2.38V 20%---1.90V 15%---1.42V */ | |
float Concentration_Percentage = Concentration * 100; | |
json["o2_percent"] = Concentration_Percentage; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment