#include "SoftwareSerial.h"
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);
const int pwmPin = 6; // digital pin //mh-z14 결과값을 가져올 핀 지정
const int OUTPUT_PIN = 8;//reset
const long samplePeriod = 10000L;
long lastSampleTime = 0;
unsigned long starttime_esp = 0;
unsigned long sampletime_esp = 600000; // 10분 600,000 TIME BETWEEN MEASURES AND UPDATES
unsigned long starttime_reset = 0;
unsigned long sampletime_reset = 43200000; // 12시간 마다 reset
String apiKey = "";//자신의 thingspeak 채널의 Read API key 입력
String response1 = "";
String ip = "";
String cmd = "";
SoftwareSerial esp8266(2, 3); //TX/RX 설정, esp8266 객체생성
#define DEBUG true
String sendData(String command, const int timeout, boolean debug) {
String response = "";
esp8266.print(command);
long int time = millis();
while ((time + timeout) > millis()) {
while (esp8266.available()) {
char c = esp8266.read();
response += c;
}
}
if (debug) {
Serial.print(response);
response;
}
return response;
}
void dis_oled2(String msg1, String msg2 = "", String msg3 = "", String msg4 = "", String msg5 = "") {
int idx[] = {10, 23, 36, 49, 62};
String str[5];
str[0] = msg1;
str[1] = msg2;
str[2] = msg3;
str[3] = msg4;
str[4] = msg5;
u8g.firstPage();
do {
u8g.setFont(u8g_font_unifont);
for (int i = 0; i < 5; i++) {
u8g.setPrintPos(0, idx[i]);
u8g.print(str[i]);
}
} while (u8g.nextPage());
}
void setup() {
dis_oled2("init ... ", "", "", "", "");
Serial.begin(9600);
pinMode(pwmPin, INPUT_PULLUP);
//reset 설정
digitalWrite(OUTPUT_PIN, HIGH);
pinMode(OUTPUT_PIN, OUTPUT);
/*소프트웨어 시리얼 시작*/
esp8266.begin(9600);
/*AT Command 이용*/
dis_oled2("esp reset", "", "", "", "");
sendData("AT+RST\r\n", 2000, DEBUG); //reset module
dis_oled2("esp dual mode", "", "", "", "");
sendData("AT+CWMODE=1\r\n", 1000, DEBUG); //dual mode로 설정
dis_oled2("esp connecting", "", "", "", "");
sendData("AT+CWJAP=\"router_name\",\"password\"\r\n", 5000, DEBUG); //사용할 공유기 설정
delay(5000);
ip = sendData("AT+CIFSR\r\n", 2000, DEBUG);
ip.replace("AT+CIFSR", "");
ip.replace("\r", "");
ip.replace("\n", "");
ip.replace("OK", "");
dis_oled2(ip);
delay(300);
}
}
void loop() {
long now = millis();
int ppmPWM;
if (Serial.available()) {
String inString = Serial.readString();
Serial.print(inString);
esp8266.print(inString);
}
if (esp8266.available()) {
char instr2 = esp8266.read();
Serial.write(instr2);
Serial.print(instr2);
}
if (now > lastSampleTime + samplePeriod) {
lastSampleTime = now;
ppmPWM = readPPMPWM();
//Serial.print(ppmV);
//Serial.print("\t");
Serial.println(ppmPWM);
dis_oled2("CO2 PPM(800)", "now : " + String(ppmPWM) + "PPM", "", "", ip);
}
if ((millis() - starttime_esp) > sampletime_esp) {
sendthings(ppmPWM);
starttime_esp = millis();
}
//reset every 12hr
if ((millis() - starttime_reset) > sampletime_reset) {
digitalWrite(OUTPUT_PIN, LOW);
starttime_reset = millis();
}
}
int readPPMPWM() {
while (digitalRead(pwmPin) == LOW) {}; // wait for pulse to go high
long t0 = millis();
while (digitalRead(pwmPin) == HIGH) {}; // wait for pulse to go low
long t1 = millis();
while (digitalRead(pwmPin) == LOW) {}; // wait for pulse to go high again
long t2 = millis();
long th = t1 - t0;
long tl = t2 - t1;
long ppm = 5000L * (th - 2) / (th + tl - 4);
while (digitalRead(pwmPin) == HIGH) {}; // wait for pulse to go low
delay(10); // allow output to settle.
return int(ppm);
}
void sendthings(int pwm) {
// TCP 연결
Serial.println("send data to thingspeak");
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += "184.106.153.149"; // api.thingspeak.com 접속 IP
cmd += "\",80"; // api.thingspeak.com 접속 포트, 80
esp8266.println(cmd);
if (esp8266.find("Error")) {
Serial.println("AT+CIPSTART error");
return;
}
// GET 방식으로 보내기 위한 String, Data 설정
String getStr = "GET /update?api_key=";
getStr += apiKey;
getStr += "&field4="; //필드명 지정
getStr += String(pwm);
getStr += "\r\n\r\n";
// Send Data
cmd = "AT+CIPSEND=";
cmd += String(getStr.length());
esp8266.println(cmd);
Serial.println(getStr);
if (esp8266.find(">")) {
esp8266.print(getStr);
}
else {
esp8266.println("AT+CIPCLOSE");
// alert uesp8266
Serial.println("AT+CIPCLOSE");
}
}