/*
5v - vin
scl - d1
sda - d2
VOCs Sensor(GSBT11-p11)
vcc - 5v
vvolt-a0
*/
// includes
#include "ESP8266WiFi.h"
#include "WiFiClientSecure.h"
#include <ArduinoOTA.h>
#include "SSD1306Wire.h" // oled 라이브러리, 아두이노 우노 사용시는 #include "SSD1306.h"
#define DEBUG true
#include <Wire.h>
#include "SparkFunBME280.h"
BME280 mySensor;
//SSD1306 display(0x3c, 4, 5);//0x3C being the usual address of the OLED sda d2-4, sck d1-5
SSD1306Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL - SDA and SCL usually populate automatically based on //your board's pins_arduino.h e.g. https://github.com/esp8266/Arduino/blob/master/variants/nodemcu/pins_arduino.h
// user config:
const char* wifi_ssid = ""; // replace MySSID with your WiFi network name
const char* wifi_password = ""; // replace MyPassword with your WiFi password
// thingspeak config.
//자신의 thingspeak 채널의 Read API key 입력
String apiKey = "";
String response1 = "";
String ip = "";
String cmd = "";
const char* https_host = "api.thingspeak.com"; // thingspeak host name
const int https_port = 443; // https port
// create thingspeak client
WiFiClientSecure client;
//oled update interval
unsigned long starttime_lcd = 0;
unsigned long sampletime_lcd = 3000; // 30초 TIME BETWEEN MEASURES AND UPDATES
//temp, humid update interval
int err;
float temp, humi, hpa, pa;
unsigned long starttime_temp = 0;
unsigned long sampletime_temp = 60000; // 1분 TIME BETWEEN MEASURES AND UPDATES
// thingspeak update interval
unsigned long starttime_bl = 0;
unsigned long sampletime_bl = 600000; // 10분 600,000 TIME BETWEEN MEASURES AND UPDATES
//voc
int data;
float voc;
unsigned long starttime_voc = 0;
unsigned long sampletime_voc = 600000; // 10분 GSBT11-P110 TIME BETWEEN MEASURES AND UPDATES
#define DEBUG
#ifdef DEBUG
#define Serial_p(x) Serial.println(x)
#define Serial_p2(x,y) Serial.println(x,y)
#define Serial_b(x) Serial.begin(x)
#define Serial_f(x,y) Serial.printf (x,y)
#else
#define Serial_p(x)
#define Serial_f(x)
#define Serial_b(x)
#define Serial_p2(x)
#endif
void setup() {
Serial.begin(115200);
Serial.println("init....");
// Initialising the UI will init the display too.
display.init();
display.flipScreenVertically();
display.setFont(ArialMT_Plain_16);
dis_oled2("init ... ", "", "", "", "");
delay(100);
//sparkfun bme280
Wire.begin();
mySensor.setI2CAddress(0x76); //Connect to a second sensor
if (mySensor.beginI2C() == false) //Begin communication over I2C
{
Serial.println("The sensor did not respond. Please check wiring.");
dis_oled2("BME280 ERROR!", "Failed to start", "Check the wiring", "", "");
while (1); //Freeze
}
else
{
dis_oled2("BME280 OK~", "", "", "", "");
}
Serial.println("connecting wifi...");
dis_oled2("wifi connecting ...", "", "", "", "");
WiFi.begin(wifi_ssid, wifi_password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
Serial.println("wifi connected~");
// Set Client to insecure
client.setInsecure();
ip = WiFi.localIP().toString();
Serial.println("ip:" + ip);
dis_oled2(ip, "", "", "", "");
ArduinoOTA.setHostname("voc"); // ota 이름 설정
ArduinoOTA.setPassword("1234"); //ota 접속 비번 설정
ArduinoOTA.onStart([]() {
Serial_p("Start");
});
ArduinoOTA.onEnd([]() {
Serial_p("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial_f("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial_f("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial_p("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial_p("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial_p("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial_p("Receive Failed");
else if (error == OTA_END_ERROR) Serial_p("End Failed");
});
ArduinoOTA.begin();
Serial_p("OTA ready");
}
void loop() {
if ((millis() - starttime_temp) > sampletime_temp) {
//sparkfun bme280
Serial.print("Humidity: ");
humi = mySensor.readFloatHumidity();
Serial.print(humi, 0);
Serial.print(" Pressure: ");
pa = mySensor.readFloatPressure();
hpa = pa / 100;
Serial.print(pa, 0);
Serial.print(" Alt: ");
Serial.print(mySensor.readFloatAltitudeMeters(), 1);
//Serial.print(mySensor.readFloatAltitudeFeet(), 1);
Serial.print(" Temp: ");
temp = mySensor.readTempC() - 2; //slightly higher than dht22 about 2 degree
Serial.print(temp, 2);
//Serial.print(mySensor.readTempF(), 2);
Serial.println();
starttime_temp = millis();
}
if ((millis() - starttime_voc) > sampletime_voc) {
data = analogRead(A0); // 실제로 측정된 ppm에 따른 ADC값
Serial.println(data);
voc = (float(data) * 5) / 1024; //analogRead 코드로 읽히는 A0 값의 범위는 0 ~ 3.3V(5v) 전압에 대해 nodemcu 기기
//내부의 Analog-Digtal-Converter에 의해 0 ~ 1023 범위로 변환된 값
Serial.println(voc );
starttime_voc = millis();
}
if ((millis() - starttime_lcd) > sampletime_lcd) {
dis_oled2("tmp:" + String(temp), "hum:" + String(humi), "voc:" + String(voc), "hPa:" + String(hpa), ip);
starttime_lcd = millis();
}
if ((millis() - starttime_bl) > sampletime_bl) {
// GET 방식으로 보내기 위한 String, Data 설정
String getStr = "";
getStr += "&field1=";
getStr += String(temp);
getStr += "&field2=";
getStr += String(humi);
getStr += "&field3=";
getStr += String(voc);
getStr += "&field6=";
getStr += String(hpa, 1);
// Send Data
send_data(getStr);
Serial.println(getStr);
starttime_bl = millis();
}
}
void dis_oled2(String msg1, String msg2, String msg3, String msg4, String msg5) {
display.clear();
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.setFont(ArialMT_Plain_16);
int idx[] = {0, 13, 26, 39, 52};
String str[5];
str[0] = msg1;
str[1] = msg2;
str[2] = msg3;
str[3] = msg4;
str[4] = msg5;
for (int i = 0; i < 5; i++) {
display.drawString(0, idx[i], str[i]);//
}
display.display();
}
void send_data(String msg)
{
if (!client.connect(https_host, https_port)) {
delay(200);
Serial.println("client connection error !");
return;
}
Serial.println("client connection success !");
// Create a URL for the request
String url = "/update?api_key=";
url += apiKey;
url += msg;
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + https_host + "\r\n" +
"Connection: close\r\n\r\n");
client.connected();
}
GSBT11-P110의 datasheet로 볼 때 1볼트 미만으로 관리하는 게 톨루엔과 포름알데히드의 영향을 최소화 가능할 듯함
관리기준은 아래 국토부 신규 제작자동차 실내공기질 관리기준 자료 참고
http://www.molit.go.kr/USR/policyTarget/dtl.jsp?idx=518
'diy > esp8266' 카테고리의 다른 글
esp-12 gpio핀 정리 (1) | 2023.11.13 |
---|---|
esp8266과 안드로이드 서버 통신하기 (0) | 2022.12.01 |
esp-01 릴레이를 이용한 도어락 열기 2 (0) | 2022.11.25 |
esp-01 릴레이를 이용한 도어락 열기 1 (0) | 2022.11.22 |
voc센서(GSBT11-P110, 공기질 측정기) 만들기 1 (0) | 2022.09.27 |