IOT(사물인터넷) 시스템도 홈페이지 화가 가능하다. 사용자 ID 와 비밀번호 PW를 설정하고 Login 하여 들어가서 필요한 작업 후 다시 Login 화면으로 돌아올 수 있다.
LED가 설치된 아두이노 NodeMCU 보드에서 LED를 on OFF BLINK 할 수 있는 와이파이 사물인터넷(IOT) 시스템을 대상으로 Login 이 가능한 홈페이지를 코딩해 보자.
Login은 Administrator 가 단독으로 하나의 ID 와 password를 가지고 운영하도록 한다. ID는 arduino 로 설정하고password 는 nodemcu 로 둔다.
아두이노 NodeMCU 보드에서 LED는 별도 와이어링 없이 사진처럼 붙박이 LED를 사용하기로 하자. 붙박이 LED는 핀 번호가 즉 GPIO 2번으로 D4를 나타낸다.
홈페이지는 Login 화면과 LED Control 버튼 화면 2개로 구성하기로 한다.
아두이노 NodeMCU에서 와이파이 사용을 위해 라이브러리 ESP8266WiFi.h을 설치하고 스마트 폰 핫스팟이나 PC에 설치된 무선 공유기의 ID 와 비밀번호를 입력해 둔다.
붙박이 LED 번호는 2번으로 설정하며 클라스 명령 WiFiServer를 선언함과 아울러 포트 번호를 통상 80번으로 지정한다.
불리언 변수 Login을 도입하여 참(true) 으로 두자. Login 의 불리언 값이 참이면 웹서버가 실행되었을 때 웹 브라우저에Login 화면이 나타난다. Login 해서 홈페에지 내부로 들어가게 되면 Login 의 값이 거짓(false) 으로 설정해 두어야 한다.
setup() 문에서 아두이노 NodeMCU 의 통신속도를 115200 으로 설정한다.
WiFi 연결을 위한 루틴 구성은 본 블로그의 많은 예제에서 설정된 바와 동일하다. setup() 문 나머자 부분 및 loop()문에서 favicon 처리하는 부분까지는 거의 변동이 없다. favicon 에 대해서는 “초보자를 위한 아두이노 와이파이 코딩” 이나 “아두이노 와이어링 & 와이파이 코딩” 에 이미 상세한 설명 및 예제가 있으므로 참조하기 바란다.
Login 화면에서 IOT(사물인터넷) 페이지로 넘어가기 위한 전제 조건은 Login 화면에서 입력된 ID 와 password 정보를 확인할 필요가 있다.
if 문에서 request.indexOf(⚫⚫⚫) != -1 이 참이면 즉 –1이 아니라면 아두이노 NodeMCU 의 입력 버퍼에 클라이언트인 PC 나 스마트 폰 웹브라우저로부터 ⚫⚫⚫ 에 해당 하는 정보가 들어 왔다는 의미이다. 그렇다면 ID 인 arduino 와 password 인 nodemcu 가 함께 들어왔는지 확인해야 한다. 만일 그렇다면 Login 의 값을 거짓(false) 으로 바꾸어 둔다. 이 값은 이어지는 loop 문에서 Login 화면이 아닌 IOT 버튼 화면을 불러내기 위하여 사용된다.
만약 ID 인 arduino 와 password 인 nodemcu 가 동시에 참으로 확인되지 않을 경우는 Login 이 거짓 값인 상태 즉 IOT LED Control 상태이므로 on OFF BLINK를 따져서 붙박이 LED를 동작 시켜야 한다. 아울러 LED Control 상태 화면에서는 언제든지 Login 화면으로 넘어 갈 수 있도록 Logout 버튼 키도 함께 디스플레이 되어 있어야 한다. 즉 Logout 버튼을 누르면 이 단계에서 확인 후 Login 의 값을 참(true) 로
설정해야 loop 과정에서 Login 화면으로 전환된다.
홈페이지는 2개의 웹브라우저 화면으로 구성된다. 즉 Login 화면과 LED Control 버튼 키 화면이며 가각 배경색을 달ㄹ;하도록 한다. Login 화면은 연한 하늘색 LED Control 버튼 키 화면은 하얀색으로 설정하는데 현재 웹브라우저가 Login 화면 상태인지 LED Control 버튼 키 화면 상태인지 여부는 불리언인 Login 의 값을 if 문에 의해 체크해 보면 된다.
홈페이지 장식을 위한 style 태그 코드가 상당히 긴 편인데 대부분 Login 화면 설정을 위한 것이다. 하지만 하나의 HTML 코드에 2가지의 배경 색을 동시에 정의할 수는 없으므로 LED Control 버튼 키 화면에서 Login 화면과 다른 배경 색을 사용하기 위해서 if 문에서 불리언 Login 값을 체크하여 바꾸어 줄 필요가 있다.
LED Control 버튼 키 CSS 코드는 Login 화면 CSS 보다는 간략하지만 별도로 설정하고 style 태그를 종료한다. 이와 같이 별도의 CSS 로 코딩하더라도 CSS 자체가 실행 명령의 성격이 아니므로 굳이 if 문을 사용하여 Login 화면인지 LED Control 키 버튼 화면인지 체크 할 필요는 없다.
그 다음 단계는 불리언 Login 값을 체크하여 참이면 Login 화면에서 form 태그에 의해 ID 와 PW를 입력해야 할 것이며 입력 후 클릭하면 2개의 데이터를 GET 방식에 의해서 전송(Submit)하게 되는데 앞서 거론했던 if 문에서 request.indexOf(⚫⚫
⚫) != -1 여부를 체크하게 된다. 그림의 코드 화면에서는 client.println(“...에서 client.prin 부분이 생략되고 ⚫⚫⚫로 표시하였음에 유의하자.
Login 화면 form 태그가 끝나는 부분에서 일단 head 태그를 일단락 하도록 하며 그 다음에 이어서 LED Control 버튼 키 화면부터 body 태그를 열도록 한다.
불리언 Login 값이 참이면 그냥 skip 해서 다시 loop
문 초반으로 돌아가 무한 루프를 돌게 된다. 반면에 Login 값이 거짓이라면 버튼 키 화면에서 하얀색 배경 색 바탕에 앵커 태그에 의한 4개의 버튼 키 즉 on OFF BLINK Logout를 볼 수 있다. 이 중에서 on OFF BLINK 중의 하나를 클릭하면 Login 값이 거짓인 상태를 유지하면서 GET 방식에 의해 아두이노에 request를 보내고 request.indexOf(⚫⚫⚫) != -1 체크하여 LED를 제어할 수 있다. 반면에 Logout 버튼을 클릭할 경우에는 Login 의 값을 참으로 설정하게 되므로 Login 화면으로 전환하게 된다.
현재의 IOT(사물인터넷 ) 홈페이지 Login 시스템은 2개의 홈페이지 화면으로 구성되었으므로 불리언 Login 값의 참 거짓으로 처리가 가능하지만 홈페이지의 페이지 수 가 증가하게 되면 페이지 번호를 하이퍼링크가 가능한 변수로 설정하여 화면을 이동하여야 할 것이다.
Webserver_nodemcu_login_01
#include <ESP8266WiFi.h>
const char* ssid = "android1234";//자신의 스마트폰 핫스팟 ID
const char* password = "dddddddddd";//핫스팟 비밀번호 입력
int ledPin = 2; //붙박이 LED
WiFiServer server(80);
boolean Login = true;
void setup() {
Serial.begin(115200);
delay(10);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
// Set WiFi to station mode and disconnect from an AP if it was previously connected
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
Serial.println("Setup done");
// Connect to WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Start the server
server.begin();
Serial.println("Server started");
// Print the IP address
Serial.print("Use this URL to connect: ");
Serial.print("http://");
Serial.print(WiFi.localIP());
Serial.println("/");
}
void loop() {
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
// Wait until the client sends some data
Serial.println("new client");
while(!client.available()){
delay(1);
}
// Read the first line of the request
String request = client.readStringUntil('\r');
if( request.substring(5,16) != "favicon.ico") {//favicon.ico request 배제
Serial.println(request);
client.flush();
}//if( request.substring
if( request.substring(5,16) != "favicon.ico") {//favicon.ico request 배제
// Match the request
// on OFF BLINK 확인
if ( (request.indexOf("arduino") != -1)&& (request.indexOf("nodemcu") != -1) ) {
Login = false;
}
else {
if (request.indexOf(on H") != -1) {
digitalWrite(ledPin, LOW);
}
if (request.indexOf("OFF H") != -1) {
digitalWrite(ledPin, HIGH);
}
if (request.indexOf("BLINK H") != -1) {
for( int i = 0; i<19; i++) {
digitalWrite(ledPin, LOW);
delay(50);
digitalWrite(ledPin, HIGH);
delay(50);
}
}
if (request.indexOf("Logout") != -1) {
Login = true;
}
}
// Return the response
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println(""); // do not forget this one
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("<head>");
//배경 색 문자 색 사이즈 HTML CSS 설정
client.println("<style>");
//Login 버튼 배경 CSS
client.println("* {box-sizing: border-box;}");
client.println("*:focus { outline: none;}");
if( Login == true ) {
client.println("body {font-family: Arial;background-color: #3498DB;padding: 50px;}");
}
else {
client.println("body {font-family: Arial;background-color: white;padding: 50px;}");
}
client.println(".login {margin: 20px auto;width: 300px;}");
client.println(".login-screen {background-color: #FFF;padding: 20px;border-radius: 5px}");
client.println(".app-title {text-align: center;color: #777;} ");
client.println(".login-form {text-align: center;}");
client.println(".control-group {margin-bottom: 10px;}");
client.println("input {text-align: center;background-color: #ECF0F1;");
client.println("border: 2px solid transparent;border-radius: 3px;");
client.println("font-size: 16px;font-weight: 200;padding: 10px 0;");
client.println("width: 250px;transition: border .5s;}");
client.println("input:focus {border: 2px solid #3498DB;box-shadow: none;}");
client.println(".btn { border: 2px solid transparent; background: #3498DB;");
client.println(" color: #ffffff; font-size: 16px; line-height: 25px; padding: 10px 0;");
client.println(" text-decoration: none; text-shadow: none; border-radius: 3px;");
client.println(" box-shadow: none; transition: 0.25s; display: block; width: 250px;");
client.println(" margin: 0 auto;} ");
client.println(".btn:hover { background-color: #2980B9;} ");
client.println(".login-link {font-size: 12px;color: #444;display: block;margin-top: 12px;}");
//버튼 HTML CSS 설정
client.println(".button {");
client.println("background-color: green;");
client.println("border: 3px solid red;border-radius: 10px;");
client.println("color: white;");
client.println("padding: 15px 32px;");
client.println("text-align: center;");
client.println("text-decoration: none;");
client.println("display: inline-block;");
client.println("font-size: 30px;");
client.println("margin: 10px 15px;");
client.println("cursor: pointer;");
client.println("}");
client.println("</style>");
if( Login == true ) {
client.println("<form method='GET'>");
client.println("<div class='login'><div class='login-screen'><div class='app-title'>");
client.println("<h1>Arduino IOT Login</h1></div> <div class='login-form'><div class='control-group'>");
client.println("<input type='text' class='login-field' value='' placeholder='username' name='ID'>");
client.println("<label class='login-field-icon fui-user' for='login-name'></label>");
client.println("</div> <div class='control-group'>");
client.println("<input type='password' class='login-field' value='' placeholder='password' name='PW'>");
client.println("<label class='login-field-icon fui-lock' for='login-pass'></label></div> ");
client.println("<input type='submit' value='Log in' class='btn btn-primary btn-large btn-block' >");
client.println(" <br></div></div></div>");
client.println("</form>");
}
client.println("</head>");
client.println("<body>");
if( Login == true ) {
}
else {
client.println("<center>");
client.println("<div class='app-title'><h1>LED Control</h1></div>");
client.println("<br>");
client.println("<a href=\"/on\"\" class='button'> on </button></a>");
client.println("<a href=\"/OFF\"\" class='button'> OFF </button></a>");
client.println("<a href=\"/BLINK\"\" class='button'>BLINK</button></a>");
client.println("<a href=\"/Logout\"\" class='button'>Logout</button></a>");
client.println("</center>");
client.println("</body>");
client.println("</html>");
}
delay(1);
Serial.println("Client disonnected");
Serial.println("");
} //favicon.ico배제 if 문 닫기 괄호
}//프로그램 끝
'아두이노프로세싱 프로그래밍' 카테고리의 다른 글
초보자를 위한 “초음파 센서 SR-04 거리 측정” (0) | 2017.08.12 |
---|---|
아두이노 프로마이크로에 설치된 DHT11 온습도 시리얼 출력결과 USB 연결에 의해 라즈베리 파이 출력 (0) | 2017.08.09 |
라즈베리 파이 Flask 와이파이 마이크로 웹서버 IOT LOGIN 코딩 (0) | 2017.08.03 |
아두이노 프로마이크로 적외선 거리센서 (Sharp Ir GPY2Y0A21) 실험 (0) | 2017.08.03 |
라즈베리 파이 Flask 와이파이 마이크로 웹서버 LOGIN 시스템 코딩 (0) | 2017.08.01 |