아두이노 웹서버 또는 아두이노 NodeMCU 웹서버 LED on OFF 프로그램을 실행시킨 후 스마트폰 웹 브라우저 주소창에서 가상 ip를 입력하고 엔터 키를 누르면 웹 브라우저에서 2가지 종류의 request 신호가 아두이노 웹서버 프로그램에 전달되는데, 이는 시리얼 모니터의 출력 결과로 확인할 수 있다.
이 문제를 확인해 보기 위해서 아두이노 NodeMCU 웹서버 프로그램 중 loop() 프로그램 // Read the first line of the request 부분에서 2 줄의 명령을 추가하여 수정하기로 한다. 아래의 빨간색 부분이 추가된 명령들이다.
// Read the first line of the request
String request = client.readStringUntil('\r');
Serial.println(request);
Serial.print("String.length(request)=");
Serial.println(request.length());
client.flush();
시리얼 모니터에서 처음에 가상 ip 출력과 함께 와이파이 연결 상황을 확인할 수 있다.
여기서 출력된 가상 ip를 스마트 폰 주소창에 입력하고 엔터를 누르면 스마트 폰 웹 브라우저가 클라이언트로서 와이파이를 통해서 request를 아두이노 NodeMCU에게 전달하게 되는 것이다.
그 다음 주의할 사항은 스마트폰 사용자가 더 이상의 아무런 request를 아두이노 NodeMCU에 하지 않았음에도 불구하고 웹브라우저가 자동적으로 favion.ico request를 자동적으로 발송했다는 점이다.
문제는 아두이노 웹서버 프로그램은 request 종류에 상관없이 한 번씩 반응하여 loop() 프로그램을 실행 시킨다는 점이다. 즉 사용자가 준 request 외의 다른 request에도 반응한다는 점이다. 즉 제어되지 않은 입력 request들에 의해서 의도되지 않은 위험한 스위치 on OFF 가 추가로 발생할 수 있다는 점이다.
따라서 추가된 2줄의 명렬 실행에 의해 스마트폰 웹브라우저에서 발송되는 request를 점검하여 특히 문자 길이가 25인 favicon.ico request를 철저히 찾아내어 if 문을 써서 아두이노 제어 프로그램이 반응하지 않도록 건어 뛰게끔 프로그램 할 필요가 있다.
특히 대부분의 웹브라우저가 favico.ico request를 송출하기 때문에 아직까지는 와이파이를 사용하는 아두이노 NodeMCU 웹서버 나 또는 유선 방식의 아두이노 이더넷 웹서버 수준에서 이 favicon 문제를 해결하는 것은 구조적으로 해답이 없어 보인다.
favicon 이라함은 인터넷 주소창 앞부분에 놓여 있는 16X16 저해상도 수준의 그래픽 아이콘으로서 정규적인 웹서버의 루트 디렉토리에 favicon 이미지를 저장해 놓고 HTML의 link 명령에 의해 호출하게끔 프로그램 되어 있다. 하지만 아시다시피 아두이노 NodeMCU 급의 웹브라우저에 루트 디렉토리라는 개념이 아예 없다는 점을 지적한다.
이전 블로그에서도 지적했듯이 사적인 그림이나 사진 또는 스케치를 불러 오기 위해서는 공인인 ip를 사용하는 블로그에 저장한 후 img 태그를 사용하여 호출해서 사용해야 했던 불가피성을 생각하면 될 것이다.
아래의 프로그램은 아두이노 NodeMCU의 built-in LED 2번(GPIO 2, D4)을 on OFF 하는 프로그램으로 이전에도 한번 소개를 했던 프로그램을 약간 수정하였다. 이 프로그램으로는 favicon request 효과를 명확하게 관찰 못할 수도 있으므로 별도의 색상이 서로 다른 LED 2개 이상을 배선해서 각 LED 별로 delay를 5초 정도 주고 관찰해 볼 것을 권장한다. favicon request에 따른 반응이 확실하다면 의도치 않는 바이므로 아래 프로그램에서처럼 if 문을 사용하여 배제하도록 한다.
별도로 3색 LED on OFF 스마트폰 프로그램 예제를 올릴 계획이다.
Webserver_acrowifi_request_01
#include <ESP8266WiFi.h>
const char* ssid = "AndroidHotspot1234";//본인 스마트폰 핫스팟 ID 입력
const char* password = "00000000";// 보인 스마트폰 비밀번호 입력
int ledPin = 2; //
WiFiServer server(80);
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');
Serial.println(request);
Serial.print("String.length(request)=");
Serial.println(request.length());
client.flush();
//14: 정식 request, 20: LED on request 21: LED OFF request 아니면 건너뛸 것.
if( request.length() == 14 || request.length() == 20 || request.length() == 21 ) {
// Match the request
int value = LOW;
if (request.indexOf("/LED=ON") != -1) {
digitalWrite(ledPin, LOW);
value = HIGH;
}
if (request.indexOf("/LED=OFF") != -1) {
digitalWrite(ledPin, HIGH);
value = LOW;
}
// Set ledPin according to the request
//digitalWrite(ledPin, value);
// 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("<body>");
client.print("Led pin is now: ");
if(value == HIGH) {
client.print(" on");
} else {
client.print("Off");
}
client.println("<br><br>");
client.println("<a href=\"/LED=ON\"\"><button>Turn on </button></a>");
client.println("<a href=\"/LED=OFF\"\"><button>Turn Off </button></a><br />");
// client.println("</body>");
client.println("</html>");
delay(1);
Serial.println("Client disonnected");
Serial.println("");
} //if 문 닫기 괄호
}//프로그램 끝
'아두이노프로세싱 프로그래밍' 카테고리의 다른 글
아두이노 NodeMCU 웹서버용 스마트폰 HTML 웹 버튼 키보드:I (0) | 2017.02.22 |
---|---|
아두이노 NodeMCU 웹서버에 의한 삼색 LED 스마트폰 제어 및 웹화면 출력 (0) | 2017.02.22 |
아두이노 NodeMCU에서 그림파일 불러오는 HTML img 태그 사용법 (0) | 2017.02.20 |
삼색 LED에 의한 아두이노 NodeMCU에서 인터럽트 가능한 핀 확인 실험 (0) | 2017.02.18 |
NodeMCU 1.0 WiFi Webserver에 의한 스마트폰 다음지도 마커표시 보완 (0) | 2017.02.16 |