Skip to contentESP8266 – ARDUINO IDE 예제 (WiFi 통신) Show Home/통신 모듈/ESP8266 – ARDUINO IDE 예제 (WiFi 통신) ESP8266 – ARDUINO IDE 예제 (WiFi 통신)본 문서는 아두이노 개발환경(IDE)를 이용해서 ESP8266 모듈을 다루는 예제들을 포함하고 있습니다.
. ESP8266을 위한 다양한 예제가 이미 갖추어져 있습니다. [Arduino IDE – File – Examples – ESP8266xxx] 예제들을 보면 다양한 기능들을 구현하는 방법이 나옵니다. 여기서 소개하는 예제는 NodeMCU V1 (ESP12E 기반) 보드에서 동작 테스트를 한 예제들입니다. 그리고 소개를 위해 예제 코드에 약간의 변형이 가해졌습니다. NodeMCU 보드는 아래와 같이 핀이 배치되어 있으며, 펌웨어 업로드를 위해 필요한 FTDI 모듈을 내장하고 있어서 PC에 USB 연결만 하면 사용할 수 있습니다. . WiFi 통신 기본WiFi 통신을 위한 기초 예제입니다. 아래에서 소스코드를 구하실 수 있습니다.
이 소스코드는 단순히 ESP8266 모듈을 공유기에 연결만 시킵니다. 그리고 그 과정에서 발생되는 WiFi 이벤트를 받아서 처리하는 방법을 설명합니다. 테스트를 위해서는 파일 상단에 공유기(AP)의 SSID, 비밀번호를 지정해줘야 합니다. const char *ssid = "your_ssid"; const char *password = "your_pass";소스코드의 setup() 초기화 함수를 보겠습니다. void setup() { Serial.begin(115200); // delete old config WiFi.disconnect(true); delay(1000); WiFi.onEvent(WiFiEvent); WiFi.begin(ssid, password); Serial.println("Wait for WiFi... "); }WiFi 가 ESP8266 core에서 제공하는 통신 기능들에 접근할 수 있는 인스턴스입니다. WiFi.onEvent() 함수를 이용해 이벤트가 발생했을 때 실행될 콜백함수를 지정할 수 있습니다. 위 처럼 지정되어 있으므로 이벤트가 발생하면 WiFiEvent() 함수가 호출됩니다. 이벤트가 발생했을 때 하고 싶은 작업을 WiFiEvent() 함수에 구현하면 됩니다. 사용가능한 함수는 ESP8266WiFiType.h 에서 확인하실 수 있습니다. typedef enum { WIFI_EVENT_STAMODE_CONNECTED = 0, WIFI_EVENT_STAMODE_DISCONNECTED, WIFI_EVENT_STAMODE_AUTHMODE_CHANGE, WIFI_EVENT_STAMODE_GOT_IP, WIFI_EVENT_STAMODE_DHCP_TIMEOUT, WIFI_EVENT_SOFTAPMODE_STACONNECTED, WIFI_EVENT_SOFTAPMODE_STADISCONNECTED, WIFI_EVENT_SOFTAPMODE_PROBEREQRECVED, WIFI_EVENT_MAX } WiFiEvent_t;보시다시피 AP에 연결된 후 IP를 받아오는 과정까지 이벤트를 발생합니다. SSID, 패스워드를 이용해 AP에 연결하는 함수는 setup() 안에 있는 WiFi.begin() 입니다.
. WiFi Client (HTTP Request)이번 예제는 ESP8266 모듈을 공유기에 연결하고, 외부의 HTTP 서버에 요청을 보내서 결과(HTML 또는 파일)를 받아오는 예제입니다.
이 문서의 예제들은 모두 아래 SSID, 패스워드를 자신의 환경에 맞게 지정해줘야 동작합니다. const char *ssid = "your_ssid"; const char *password = "your_pass";이번 예제에서 HTTP 통신을 통해 받아올 서버도 미리 지정해주세요. const char* host = "hardcopyworld.com";먼저 setup() 함수의 내용부터 보겠습니다. 주요 내용만 뽑아내면 아래와 같습니다. void setup() { ...... WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } ...... Serial.println("IP address: "); Serial.println(WiFi.localIP()); }WiFi.begin(ssid, password) 함수를 이용해서 공유기에 연결합니다. 이후 이어지는 while() 반복문은 공유기에 접속할 때까지 기다리기 위해 사용했습니다. 공유기에 접속되면 아래 코드처럼 Serial 통신으로 할당받은 IP를 출력해 주는 것이 편리합니다.
loop() 반복함수에서 주기적으로(약 5초 간격) HTTP 요청을 서버로 보냅니다. 그리고 받은 결과를 Serial 통신으로 출력해줍니다. 주요 코드만 발췌하면 아래와 같습니다. void loop() { delay(5000); ...... // Use WiFiClient class to create TCP connections WiFiClient client; const int httpPort = 80; if (!client.connect(host, httpPort)) { Serial.println("connection failed"); return; } // We now create a URI for the request String url = "/"; // This will send the request to the server client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"); int timeout = millis() + 5000; while (client.available() == 0) { if (timeout - millis() < 0) { Serial.println(">>> Client Timeout !"); client.stop(); return; } } // Read all the lines of the reply from server and print them to Serial while(client.available()){ String line = client.readStringUntil('\r'); Serial.print(line); } }가장 먼저 나오는 WiFiClient 클래스는 TCP 연결을 만들기 위해 사용합니다. host와 port 를 지정하면 해당 서버에 TCP 연결을 만듭니다. 이때 사용되는 host 변수에는 도메인 이름 [hardcopyworld.com] 이 사용되어야 합니다. WiFiClient client; const int httpPort = 80; if (!client.connect(host, httpPort)) { Serial.println("connection failed"); return; }TCP 연결이 성공하면 HTTP Request 형식에 맞게 내용을 작성해서 전송하면 됩니다. client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n");여기서 url 변수는 host 도메인 내부에서 내가 원하는 리소스까지의 경로입니다. 만약 [http://www.google.com/my/resource.html] 에 요청을 보내고 싶다면 host는 [http://www.google.com] 이 됩니다. url 은 [/my/resource.html] 로 지정해줘야 합니다. 만약 http://google.com 메인 페이지의 내용을 얻고 싶다면 host는 [http://google.com], url은 [/] 로 지정해주면 됩니다. client.print() 함수를 이용해서 요청이 전송되면 일정 시간 후 응답이 옵니다. while (client.available() == 0) { if (timeout - millis() < 0) { Serial.println(">>> Client Timeout !"); client.stop(); return; } }client 의 상태를 체크해서 응답이 왔는지 확인한 코드입니다. HTTP Response가 도착하면 아래 코드로 한 라인씩 읽어 Serial 통신으로 출력할 수 있습니다. 특별한 기능을 만들고 싶을 때 이 부분을 적절히 수정하면 됩니다. while(client.available()){ String line = client.readStringUntil('\r'); Serial.print(line); }. Web server이번에는 ESP8266 모듈을 웹 서버로 만드는 방법입니다. 이 방법을 사용하면 외부 장치에서 브라우저로 ESP8266 모듈에 접속해서 HTML 페이지를 볼 수 있습니다. 소스코드는 아래에서…
테스트 전 GPIO13 (D7) 핀에 LED를 하나 연결해두세요. 외부에서 접속 요청이 오면 LED가 켜지도록 만들겁니다. 파일 상단에서 공유기 설정을 해줘야 합니다. const char *ssid = "your_ssid"; const char *password = "your_pass"; ESP8266WebServer server ( 80 ); const int led = 13;ESP8266WebServer 클래스에 웹 서버로 동작하기 위한 기능들이 들어 있습니다. 80번 포트로 HTTP 통신을 하도록 지정되어 있습니다. 일반적인 웹 서버의 통신 포트로 브라우저에서 특별히 지정하지 않으면 80번 포트를 사용합니다. setup 함수의 주요 코드부터 보겠습니다. void setup ( void ) { ...... WiFi.begin ( ssid, password ); ...... server.on ( "/", handleRoot ); server.on ( "/test.svg", drawGraph ); server.on ( "/inline", []() { server.send ( 200, "text/plain", "this works as well" ); } ); server.onNotFound ( handleNotFound ); ...... server.begin(); ...... }WiFi.begin() 함수로 공유기에 접속합니다. 이후 공유기 접속을 기다리고 할당받은 IP 주소를 Serial 통신으로 출력해줍니다. sever.on() 함수부터 본격적인 서버설정 코드입니다. 코드에서는 3개의 URL에 대한 콜백함수를 지정해 줬습니다.
만약 위 경로에 해당되지 않는 요청이 올 경우는 handleNotFound() 콜백함수가 처리하도록 지정되어 있습니다. 이상 서버 설정이 끝나면 아래 코드로 서버를 시작합니다.
loop() 함수에서는 외부에서 접속 요청이 오는지 모니터링 하는 코드가 들어 있을 뿐입니다. 요청이 들어오면 해당되는 콜백함수가 실행됩니다. handleRoot() 함수를 보시면 HTML 문자열을 client에게 전송하는 방법을 알 수 있습니다. 조금 특이한게 drawGraph() 콜백함수인데, [/test.svg] 파일에 대한 요청이 오면 처리해주는 함수입니다. svg 는 벡터 이미지를 생성하기 위한 XML 파일입니다. svg 파일은 이미지 파일이 아니라 벡터 이미지를 그리기 위한 정보를 XML 텍스트로 담고 있습니다. 이 파일을 브라우저가 받으면 해당 정보대로 이미지를 그려 보여주기 때문에 마치 이미지 파일처럼 쓸 수 있습니다. 그래서 drawGraph() 콜백함수는 일련의 XML 데이터를 문자열로 만들어 전송해줍니다. 브라우저에서 [http://x.x.x.x/test.svg] 경로에 접속해보면 이미지가 보일껍니다. 앞서 handleRoot() 콜백함수가 생성하는 HTML 코드에도 [/test.svg] 이미지가 포함되어 있습니다. 따라서 브라우저는 [/test.svg] 에 대한 요청도 추가로 해서 벡터 이미지가 포함된 화면을 그려줍니다. . Web Socket (server)앞선 예제처럼 웹 서버는 외부에서의 요청이 있을때마다 HTML 페이지를 응답으로 보내줍니다. 그럼 브라우저는 HTML 페이지를 화면에 그려줍니다. 이 방식은 전통적인 웹의 동작 방식이지만 화면 혹은 서버에 데이터 변화가 있는지 확인하기 위해 주기적으로 웹 서버에 (같은 URL 주소에) 요청을 다시 보내고 화면을 다시 그려야 합니다. 그보다는 백그라운드로 서버와 브라우저가 연결되어 양방향으로 통신을 할 수 있다면 불필요한 HTTP 요청을 없애고 화면 일부만 업데이트가 가능할 것입니다. Web Socket 이 이런 자유로운 통신 방식을 제공해줍니다. HTML5에 포함된 Web Socket은 웹 서버와 클라이언트(브라우저의 JavaScript) 간 TCP/IP 연결을 유지하게 해 줌으로써 양방향 데이터 전송도 지원합니다. 브라우저가 업데이트를 확인하기위해 계속 서버를 체크하지 않고도 서버에서 오는 알림에 반응할 수 있는 push가 가능합니다. 다만, 이 기능을 사용하기 위해서는 비교적 최신의 브라우저를 사용해야 하는 제약이 있습니다. 그리고 당연히 서버에는 WebSocket 통신을 위한 준비가 되어 있어야 합니다. 이번 예제는 ESP8266 모듈에 웹 서버 + 웹 소켓 기능을 심을겁니다. 웹 소켓 사용을 위해서는 라이브러리를 추가로 설치해줘야 합니다.
그리고 불행히도, 현재(2016, 01 기준) 아두이노 IDE – 패키지 매니저로 배포되는 ESP8266 core 에는 라이브러리 지원에 필요한 코드가 일부 빠져있어서 에러가 발생합니다. 따라서 이번 예제를 테스트하기 위해서는 최신 ESP8266 core for Arduino 코드를 받아 수동으로 업데이트 해줘야 합니다.
웹 소켓 테스트 예제는 아래 링크에 있습니다.
ino 스케치 파일의 상단에 보면 웹 서버, 웹 소켓을 위한 인스턴스가 선언되어 있습니다. 코드를 보면 아실 수 있듯 웹 서버와 웹소켓은 각각 80번, 81번 포트를 사용합니다. ESP8266WebServer server = ESP8266WebServer(80); WebSocketsServer webSocket = WebSocketsServer(81);setup() 함수부터 보겠습니다. void setup() { ...... WiFiMulti.addAP("your_ssid", "your_pass"); ...... webSocket.begin(); webSocket.onEvent(webSocketEvent); ...... // handle index server.on("/", []() { // send index.html server.send(200, "text/html", html_string); }); server.begin(); ...... }앞선 예제와는 조금 다르게 WiFiMulti.addAP() 함수로 공유기엔 연결 했습니다. 별 차이 없습니다만, 여러개의 AP를 등록해서 자동 연결되도록 관리해주는 방법입니다. 이어서 웹 소켓을 초기화하고 웹 소켓 관련 이벤트(연결, 데이터수신, 종료)가 발생하면 처래해 줄 콜백 함수 webSocketEvent()를 등록 했습니다. 웹 서버는 [http://192.168.x.x] 처럼 루트[/] 경로에 대한 요청이 올 때 html_string 텍스트를 전달하도록 해뒀습니다. html_string은 html.h 파일에 들어있는 HTML 코드입니다. HTML 코드에는 같은 서버의 81번 포트에 웹 소켓으로 연결하도록 자바스크립트 코드가 들어가 있습니다. 그리고 웹 소켓으로 RGB LED 밝기를 조절하기 위한 코드가 들어가 있습니다. 즉, 브라우저로 ESP8266 모듈에 [http://192.168.x.x] 경로로 접속하면 HTML 코드를 다운로드 받아 브라우저가 화면을 그려줍니다. 그리고 백그라운드로 웹 소켓을 ESP8266 모듈과 연결해둡니다. 브라우저 화면에는 3개의 슬라이드 바가 있는데, 바를 움직이면 웹 소켓으로 ESP8266 모듈에 데이터를 전송합니다. 그럼 ESP8266 모듈이 데이터를 받아 RGB LED 색상을 조절합니다. ESP8266 모듈이 데이터를 받으면 앞서 등록한 webSocketEvent() 콜백 함수가 호출됩니다. void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) { switch(type) { case WStype_DISCONNECTED: break; case WStype_CONNECTED: { ...... webSocket.sendTXT(num, "Connected"); } break; case WStype_TEXT: USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); if(payload[0] == '#') { // decode rgb data uint32_t rgb = (uint32_t) strtol((const char *) &payload[1], NULL, 16); analogWrite(LED_RED, ((rgb >> 16) & 0xFF)); analogWrite(LED_GREEN, ((rgb >> 8) & 0xFF)); analogWrite(LED_BLUE, ((rgb >> 0) & 0xFF)); } break; } }웹 소켓 연결 요청이 와서 연결되면 case WStype_CONNECTED: 부분이 실행됩니다. 여기 코드를 보시면 웹 소켓으로 데이터를 보내는 방법을 알 수 있습니다. 아래 함수를 이용해서 상대방(브라우저)에게 데이터를 보냅니다.
위 함수는 특정 상대방에게 데이터를 보내는 방법입니다. 연결된 장치들 모두에게 데이터를 보낼 때는 아래 함수를 사용하면 됩니다.
case WStype_CONNECTED: 여기에 적힌 코드들은 웹 소켓으로 데이터를 받았을 때를 위한 것입니다. 데이터를 분석해서 RGB 색상값을 얻은 뒤, RGB LED 색을 조절하겠죠. 이 외에도 2대의 ESP8266 모듈을 이용해 재밌는 실험을 해볼 수 있습니다. 하나의 ESP8266 모듈은 웹 소켓 서버로 만들고, 다른 한 대는 웹 소켓 클라이언트로 만들어서 두 대의 ESP8266 모듈이 웹 소켓 통신을 하도록 하는겁니다. 이 방법은 아래의 두 예제 파일을 참고해서 직접 만들어 보시길 바랍니다.
HTTP 서버, 클라이언트 기능을 모두 활용하는 아래 예제도 참고하세요.
PS.
Share This Story! |