Last active
December 8, 2020 06:26
-
-
Save j3tm0t0/69cc2c5fa087b1ac818d54bfc15b6cec to your computer and use it in GitHub Desktop.
room-monitor for dragino w/Air Quality Sensor
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
/* | |
* send_multiple_sensor_data_with_soracom.ino | |
* Multiple sensor value send to Cloud via Unified Endpoint of SORACOM | |
* | |
* Copyright (c) 2020 SORACOM, INC. | |
* This software is released under the MIT License. | |
* http://opensource.org/licenses/mit-license.php | |
*/ | |
#define CONSOLE Serial | |
#define INTERVAL_MS (60000) | |
#define ENDPOINT "uni.soracom.io" | |
#define SKETCH_NAME "send_multiple_sensor_data_with_soracom" | |
#define VERSION "1.0" | |
/* for LTE-M Shield for Arduino */ | |
#define RX 10 | |
#define TX 11 | |
#define BAUDRATE 9600 | |
#define TINY_GSM_MODEM_BG96 | |
#include <TinyGsmClient.h> | |
#include <SoftwareSerial.h> | |
SoftwareSerial LTE_M_shieldUART(RX, TX); | |
TinyGsm modem(LTE_M_shieldUART); | |
TinyGsmClient ctx(modem); | |
#include <U8x8lib.h> | |
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); | |
#define U8X8_ENABLE_180_DEGREE_ROTATION 1 | |
#include <DHT.h> | |
#define dht11Pin 3 | |
DHT dht(dht11Pin, DHT11); | |
#define OLED_MAX_CHAR_LENGTH 16 | |
void drawText(U8X8* u8x8, const char* in_str, int width = OLED_MAX_CHAR_LENGTH); | |
void drawText_P(U8X8* u8x8, const char* pgm_s, int width = OLED_MAX_CHAR_LENGTH); | |
#include <Seeed_BMP280.h> | |
BMP280 bmp280; | |
#include <Wire.h> | |
#define AQS_ADDRESS 0x32 | |
#define AQS_DATA_LEN 16 | |
#define AQS_ID 0x43 | |
void setup() { | |
CONSOLE.begin(9600); | |
LTE_M_shieldUART.begin(BAUDRATE); | |
u8x8.begin(); | |
u8x8.setFlipMode(U8X8_ENABLE_180_DEGREE_ROTATION); | |
u8x8.setFont(u8x8_font_victoriamedium8_r); | |
CONSOLE.print(F("Welcome to ")); CONSOLE.print(SKETCH_NAME); CONSOLE.print(F(" ")); CONSOLE.println(VERSION); | |
u8x8.clear(); | |
drawText_P(&u8x8, PSTR("Welcome to ")); drawText(&u8x8, SKETCH_NAME); drawText_P(&u8x8, PSTR(" ")); drawText(&u8x8, VERSION); | |
delay(3000); | |
u8x8.clear(); | |
drawText_P(&u8x8, PSTR("modem.restart()...")); | |
modem.restart(); | |
drawText_P(&u8x8, PSTR("done.")); | |
delay(500); | |
u8x8.clear(); | |
drawText_P(&u8x8, PSTR("modem.getModemInfo():")); | |
String modemInfo = modem.getModemInfo(); | |
u8x8.println(); | |
int modem_info_len = modemInfo.length() + 1; | |
char modem_info_buf[modem_info_len]; | |
modemInfo.toCharArray(modem_info_buf, modem_info_len); | |
drawText(&u8x8, modem_info_buf); | |
delay(2000); | |
u8x8.clear(); | |
drawText_P(&u8x8, PSTR("waitForNetwork()...")); | |
while (!modem.waitForNetwork()); | |
drawText_P(&u8x8, PSTR("Ok.")); | |
delay(500); | |
u8x8.clear(); | |
drawText_P(&u8x8, PSTR("gprsConnect(soracom.io)...")); | |
modem.gprsConnect("soracom.io", "sora", "sora"); | |
drawText_P(&u8x8, PSTR("done.")); | |
delay(500); | |
u8x8.clear(); | |
drawText_P(&u8x8, PSTR("isNetworkConnected()...")); | |
while (!modem.isNetworkConnected()); | |
drawText_P(&u8x8, PSTR("Ok.")); | |
delay(500); | |
u8x8.clear(); | |
drawText_P(&u8x8, PSTR("My IP addr: ")); | |
u8x8.println(); | |
IPAddress ipaddr = modem.localIP(); | |
CONSOLE.println(ipaddr); | |
char ip_addr_buf[20]; | |
sprintf_P(ip_addr_buf, PSTR("%d.%d.%d.%d"), ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]); | |
drawText(&u8x8, ip_addr_buf); | |
delay(2000); | |
dht.begin(); | |
bmp280.init(); | |
Wire.begin(); | |
} | |
#define lightSensorPin A6 | |
#define soundSensorPin A2 | |
#define sountSamplingCount 3 | |
void loop() { | |
uint8_t rdata[AQS_DATA_LEN]; | |
int16_t int_eco2,int_iaq; | |
float eco2,iaq; | |
char buf_eco2[7],buf_iaq[5]; | |
Wire.requestFrom(AQS_ADDRESS, AQS_DATA_LEN); | |
for(int i=0;i<AQS_DATA_LEN;i++) | |
{ | |
rdata[i]=Wire.read(); | |
} | |
Wire.endTransmission(); | |
if(rdata[0]==AQS_ID) Serial.print("Sensor is Found! "); | |
else Serial.print("Sensor is Not Found! "); | |
if(rdata[1]==1) Serial.println("Sensor is Ready! "); | |
else Serial.println("Sensor is Not Ready! "); | |
int_eco2 = ((rdata[10]&0xFF)<<8) +(rdata[11]&0xFF); | |
int_iaq = ((rdata[12]&0xFF)<<8) +(rdata[13]&0xFF); | |
eco2 = int_eco2/10.0; | |
iaq = int_iaq/100.0; | |
dtostrf(eco2, 0, 2, buf_eco2); | |
dtostrf(iaq, 0, 2, buf_iaq); | |
int light_raw_value = analogRead(lightSensorPin); | |
int light_mapped_value = map(light_raw_value, 0, 1023, 0, 100); | |
long sound_raw_value_sum = 0; | |
for (int i = 0; i < sountSamplingCount; i++) { | |
sound_raw_value_sum += analogRead(soundSensorPin); | |
} | |
int sound_mapped_value = map(sound_raw_value_sum / sountSamplingCount, 0, 1023, 0, 100); | |
float temp = dht.readTemperature(); | |
char temp_buf[10]; | |
dtostrf(temp, 5, 1, temp_buf); /* format to "999.9" */ | |
int humi = (int) dht.readHumidity(); | |
float hPa = bmp280.getPressure() / 100.0; | |
char hPa_buf[10]; | |
dtostrf(hPa, 6, 1, hPa_buf); /* format to "9999.9" */ | |
u8x8.clear(); | |
u8x8.setInverseFont(1); | |
u8x8.drawString(0, 0, " Ambient Monitor"); | |
u8x8.println(); | |
u8x8.setInverseFont(0); | |
char line_buf[18]; | |
sprintf_P(line_buf, PSTR("lgt: %3d"), light_mapped_value); | |
drawText(&u8x8, line_buf); | |
u8x8.println(); | |
sprintf_P(line_buf, PSTR("snd: %3d"), sound_mapped_value); | |
drawText(&u8x8, line_buf); | |
u8x8.println(); | |
sprintf_P(line_buf, PSTR("tmp: %s"), temp_buf); | |
drawText(&u8x8, line_buf); | |
u8x8.println(); | |
sprintf_P(line_buf, PSTR("hmd: %3d"), humi); | |
drawText(&u8x8, line_buf); | |
u8x8.println(); | |
sprintf_P(line_buf, PSTR("hPa:%s"), hPa_buf); | |
drawText(&u8x8, line_buf); | |
u8x8.println(); | |
char payload[128]; | |
sprintf_P(payload, PSTR("{\"light\":%d,\"sound\":%d,\"temp_c\":%s,\"humi\":%d,\"air_pressure_hpa\":%s,\"co2\":%s,\"iaq\":%s}"), | |
light_mapped_value, sound_mapped_value, temp_buf, humi, hPa_buf, buf_eco2, buf_iaq); | |
/* example: | |
* {"light":48,"sound":60,"temp_c": 25.0,"humi":34,"air_pressure_hpa":1015.5} | |
*/ | |
CONSOLE.println(payload); | |
CONSOLE.print(F("Send...")); | |
drawText_P(&u8x8, PSTR("Send...")); | |
/* connect */ | |
if (!ctx.connect(ENDPOINT, 80)) { | |
CONSOLE.println(F("failed.")); | |
drawText_P(&u8x8, PSTR("failed.")); | |
delay(3000); | |
return; | |
} | |
/* send request */ | |
char hdr_buf[40]; | |
ctx.println(F("POST / HTTP/1.1")); | |
sprintf_P(hdr_buf, PSTR("Host: %s"), ENDPOINT); | |
ctx.println(hdr_buf); | |
ctx.println(F("Content-Type: application/json")); | |
sprintf_P(hdr_buf, PSTR("Content-Length: %d"), strlen(payload)); | |
ctx.println(hdr_buf); | |
ctx.println(); | |
ctx.println(payload); | |
/* receive response */ | |
// NOTE: response header and body are ignore due to saving for memory | |
ctx.stop(); | |
CONSOLE.println(F("done.")); | |
u8x8.clearLine(6); | |
delay(INTERVAL_MS); | |
} | |
void drawText(U8X8* u8x8, const char* in_str, int width = OLED_MAX_CHAR_LENGTH) { | |
size_t len = strlen(in_str); | |
for (int i = 0 ; i < len ; i++) { | |
if (u8x8->tx > width - 1) { | |
u8x8->tx = 0; // CR | |
u8x8->ty++; // LF | |
} | |
u8x8->print(in_str[i]); | |
} | |
} | |
void drawText_P(U8X8* u8x8, const char* pgm_s, int width = OLED_MAX_CHAR_LENGTH) { | |
size_t len = strlen_P(pgm_s); | |
for (int i = 0 ; i < len ; i++) { | |
if (u8x8->tx > width - 1) { | |
u8x8->tx = 0; // CR | |
u8x8->ty++; // LF | |
} | |
char c = pgm_read_byte(pgm_s++); | |
u8x8->print(c); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment