아두이노와 Processing

esp32 아두이노 OTA(Over The Air, arduinoOTA)에 의한 DHT11온습도 측정 결과 ThinSpeak 데이터 전송

coding art 2021. 2. 12. 17:39
728x90

와이파이 무선에 의해 아두이노 코드를 업로딩 시킬 수 있는 OTA 기법에 의해서 esp32 보드 상에서 DHT11 온습도 데이터 측정 결과를 ThinSpeak에 전송해 보자. OTA 기법에 의해서 DHT11 온습도 측정 코드를 esp32 보드에 무선으로 업로딩 시키기 위해서는 항상 아두이노 예제(examples)에 포함되어 있는 ArduinoOTA ArduinoWebUpdater 코드를 사용하자. 이 코드를 USB 케이블을 통해 esp32 보드에 업로딩하고 시리얼 모니터에서 local IP를 확인할 필요가 있다.

그 다음 이 ArduinoWebUpdater 코드를 골격으로 삼아서 사이사이에 즉 헤더 영역, setup loop 에 사용자가 작성한 예를 들자면 DHT11 온습도 코드를 넣도록 하자. 헤더 영역에는 라이브러리 #include <DHT11.h> , pin = 22, 및 클라스 명령 DHT11 dht(pin); 명령들이 될 것이다. setup 에서는 ThingSpeak 데이터 전송 코드에서 사용했던 내역을 그대로 가져와 업데이트 입력하자. 이 부분에 클라스 명령인 WiFi.xxx 가 들어 있는데 이미 ArduinoWebUpdater에서도 WiFi.zzz가 사용되고 있지만 xxxzzz 가 다르다면 아무런 상관이 없음에 유의하자. 아울러 loop 에서는 DHT11 온습도 측정 코드 및 ThingSpeak 데이터 전송을 위한 코드 전체를 가져다 업데이트 입력하면 된다. 아울러 USB 케이블을 제거하고 esp32 보드에 건전지와 같은 독립전원을 부가하자.

 

한편 ArduinoWebUpdater 코드에 사용자 코드를 업데이트 시킨 후 이 파일을 스케치 탭에서 binary 파일로 저장하도록 하자. 크롬 웹을 열어서 local IPURL에 입력하면 Login 웹 화면이 나타난다. html 코드에서 이미 정해둔 ID 와 비밀번호를 입력하여 웹 화면이 파일선택으로 넘어가면 앞 단계에서 준비한 Bonary 파일을 선택하여 Update 버튼을 누르자. 100% 에 도달했으면 ThinsSpeak 으로 이동하여 온습도 데이터 전송 결과를 확인하도록 하자. OTA 기법을 검증함에 있어 ThingSpeak을 사용하는 이유는 무선이기 때문에 측정 결과를 보려면 I2C 인터페이스에 의한 lcd 디스플레이를 설치해야 하므로 상당히 번거로울 수 있어 간편하게 사물인터넷 ThingSpeak을 사용하는 것이 대단히 편리하다.

첨부된 코드에서 ArduinoWebUpdater 코드에 어던 내용을 추가로 업데이트 하였는지 조사해 보자. 코드 길이가 제법 길어 보이지만 OTAWebUpdater 코드에 해당하는 부분을 찾아서 삭제하면 업데이트 사용자 코드를 쉽게 확인이 가능하다.

 

//ThingSpeakDHT11_OTAUpdater

#include <WiFi.h>

#include <WiFiClient.h>

#include <WebServer.h>

#include <ESPmDNS.h>

#include <Update.h>

 

const char* host = "esp32";

const char* ssid = "droidan1234";

const char* password = "dddddddddd";

 

WebServer server(80);

 

#include <ThingSpeak.h>

#include <DHT11.h>

int pin = 22;

DHT11 dht11(pin);

 

WiFiClient client;

unsigned long myChannelNumber = 899023;//Your channel ID

const char * myWriteAPIKey = "Y7RAJNWH7QRXV2UD";//Your channel API write key

unsigned long sampling_time = 60000;

 

//Login page

 

const char* loginIndex =

"<form name='loginForm'>"

"<table width='20%' bgcolor='A09F9F' align='center'>"

"<tr>"

"<td colspan=2>"

"<center><font size=4><b>ESP32 Login Page</b></font></center>"

"<br>"

"</td>"

"<br>"

"<br>"

"</tr>"

"<td>Username:</td>"

"<td><input type='text' size=25 name='userid'><br></td>"

"</tr>"

"<br>"

"<br>"

"<tr>"

"<td>Password:</td>"

"<td><input type='Password' size=25 name='pwd'><br></td>"

"<br>"

"<br>"

"</tr>"

"<tr>"

"<td><input type='submit' onclick='check(this.form)' value='Login'></td>"

"</tr>"

"</table>"

"</form>"

"<script>"

"function check(form)"

"{"

"if(form.userid.value=='admin' && form.pwd.value=='admin')"

"{"

"window.open('/serverIndex')"

"}"

"else"

"{"

" alert('Error Password or Username')/*displays error message*/"

"}"

"}"

"</script>";

 

/*

* Server Index Page

*/

 

const char* serverIndex =

" "

"<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>"

"<input type='file' name='update'>"

"<input type='submit' value='Update'>"

"</form>"

"<div id='prg'>progress: 0%</div>"

"<script>"

"$('form').submit(function(e){"

"e.preventDefault();"

"var form = $('#upload_form')[0];"

"var data = new FormData(form);"

" $.ajax({"

"url: '/update',"

"type: 'POST',"

"data: data,"

"contentType: false,"

"processData:false,"

"xhr: function() {"

"var xhr = new window.XMLHttpRequest();"

"xhr.upload.addEventListener('progress', function(evt) {"

"if (evt.lengthComputable) {"

"var per = evt.loaded / evt.total;"

"$('#prg').html('progress: ' + Math.round(per*100) + '%');"

"}"

"}, false);"

"return xhr;"

"},"

"success:function(d, s) {"

"console.log('success!')"

"},"

"error: function (a, b, c) {"

"}"

"});"

"});"

"</script>";

 

/*

* setup function

*/

void setup(void) {

Serial.begin(115200);

WiFi.mode(WIFI_STA);

ThingSpeak.begin(client); // Initialize ThingSpeak

delay(2000);

// Connect to WiFi network

WiFi.begin(ssid, password);

Serial.println("");

 

// Wait for connection

while (WiFi.status() != WL_CONNECTED) {

delay(500);

Serial.print(".");

}

Serial.println("");

Serial.print("Connected to ");

Serial.println(ssid);

Serial.print("IP address: ");

Serial.println(WiFi.localIP());

 

/*use mdns for host name resolution*/

if (!MDNS.begin(host)) { //http://esp32.local

Serial.println("Error setting up MDNS responder!");

while (1) {

delay(1000);

}

}

Serial.println("mDNS responder started");

/*return index page which is stored in serverIndex */

server.on("/", HTTP_GET, []() {

server.sendHeader("Connection", "close");

server.send(200, "text/html", loginIndex);

});

server.on("/serverIndex", HTTP_GET, []() {

server.sendHeader("Connection", "close");

server.send(200, "text/html", serverIndex);

});

/*handling uploading firmware file */

server.on("/update", HTTP_POST, []() {

server.sendHeader("Connection", "close");

server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");

ESP.restart();

}, []() {

HTTPUpload& upload = server.upload();

if (upload.status == UPLOAD_FILE_START) {

Serial.printf("Update: %s\n", upload.filename.c_str());

if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size

Update.printError(Serial);

}

} else if (upload.status == UPLOAD_FILE_WRITE) {

/* flashing firmware to ESP*/

if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {

Update.printError(Serial);

}

} else if (upload.status == UPLOAD_FILE_END) {

if (Update.end(true)) { //true to set the size to the current progress

Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);

} else {

Update.printError(Serial);

}

}

});

server.begin();

}

 

void loop(void) {

server.handleClient();

delay(1);

 

 

 

if(WiFi.status() != WL_CONNECTED) {

Serial.print("Attempting to connect to SSID: ");

while(WiFi.status() != WL_CONNECTED) {

WiFi.begin(ssid,password); // Connect to WPA/WPA2 network

Serial.print(".");

delay(1000);

}

Serial.println("\nConnected.");

}

 

int err;

float temp, humi;

if((err=dht11.read(humi, temp))==0) {

//Serial.print("temperature:");

Serial.print(temp, 0);

//Serial.print(" humidity:");

Serial.print(humi, 0);

Serial.println();

}

else {

Serial.println();

Serial.print("Error No :");

Serial.print(err);

Serial.println();

}

 

// Write to ThingSpeak. There are up to 8 fields in a channel

// set the fields with the values

ThingSpeak.setField(1, temp);

ThingSpeak.setField(2, humi);

int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);

client.stop();

delay(sampling_time); //

}//End