아두이노프로세싱 프로그래밍

아두이노 ESP8266 NodeMCU IOT(사물인터넷 ) 홈페이지 Login 시스템

coding art 2017. 8. 4. 21:02
728x90

 

 

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 문 닫기 괄호
 }//프로그램 끝