NodeMCU 설정
NodeMCU는 WIFI 기능의 장점 때문에 많이 쓰이는 보드이다. 이런 종류의 보드는 태생이 불분명한 여러 버전이 잔뜩있어 사람을 헷갈리게 하는 경향이 있다. 이를테면 별 생각없이 여러 개 구입했던 아래 사진의 NodeMCU도 얼핏보기엔 오리지날 NodeMCU랑 비슷해 보이지만 여러가지 다른 점이 많았다.
뒷면을 보면 LoLin new NodeMCU V3라고 되어있다.
그런데 이 버전은 PCB 폭이 넓어 일반 브레드보드에서 쓸 수가 없다. NodeMCU 오리지날은 브레드 보드에 끼우면 양쪽으로 핀을 끼울 공간이 생기는데, 이 보드는 그 공간까지 다 잡아먹어 버린다.
어쨌든 NodeMCU 자체는 USB 하나만 끼워넣고도 몇가지 기본적인 테스트는 해 볼 수 있다. 뭔가 확장기능이 필요하면 추가 기판을 사용하면 될 것이다.
지금 이걸로 만드려고 하는 것은 최대 12 채널 짜리 서보 컨트롤러이다. 아두이노에서 라이브러리를 사용하면 서보모터 12개를 운영할 수 있는 것으로 기억하는데, NodeMCU에서도 GPIO핀을 다 쓰면 그 정도가 될 거라는 생각이든다. 실제로 많이 써봐야 8 개 정도 될 것이다.
사실 이 보드를 사놓고 오랫동안 쓰질 않아서 알았던 내용도 다 까먹었는데, 기억을 되살릴겸 NodeMCU에서 흔히하는 기본 예제 몇가지를 돌려보기로 하였다.
NodeMCU를 깊이있게 파헤칠 생각은 없기 때문에 그냥 아두이노 IDE에서 사용한다.
자꾸 까먹어서 아두이노 IDE에서의 NodeMCU 사용법을 여기에 다시 정리한다. 이 과정은 github.com/esp8266/Arduino의 Readme.md 문서에 설명되어 있다.
1. 아두이노 IDE를 실행 시킨 후, 파일 -> 환경설정으로 들어간다.
아래와 같이 추가적인 보드 매니저 URLs 에디터 창에 다음 URL을 적어넣고 확인을 누른다.
https://arduino.esp8266.com/stable/package_esp8266com_index.json
2. 툴 -> 보드 -> 보드 매니저로 찾아들어가 아래와 같이 esp8266을 써 넣는다. 잠시후 나타나는 패키지를 설치한다.
3. 툴 -> 보드에서 NodeMCU 1.0 선택
이제 NodeMCU를 USB에 연결하고 흔한 아두이노 예제인 blink를 실행 시켜보았다.
blink.ino
int LED_pin = 2;
int turn_on = 0;
int turn_off = 1;
void setup() {
// put your setup code here, to run once:
pinMode(LED_pin, OUTPUT);
digitalWrite(LED_pin, turn_off);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(LED_pin, turn_on);
delay(1000);
digitalWrite(LED_pin, turn_off);
delay(1000);
}
여기서 특이한 것은 LED 핀의 번호이다. 보통 NodeMCU에서 blink 예제에서 사용하는 포트번호가 이 보드에서는 먹지 않았는데, 회로 차이가 있는 것으로 보인다.
두번째도 NodeMCU의 기본적인 예제로 웹브라우저에 Hello world를 출력한다. 시리얼 모니터에 출력된 ip 주소로 웹에 접속하여 출력을 확인한다.
hello.ino
#include <ESP8266WiFi.h>
const char* ssid = "******";
const char* password = "*****";
WiFiServer server(80);
void setup() {
Serial.begin(115200);
delay(10);
// 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);
client.flush();
// 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.print("HELLO WORLD!");
client.println("</html>");
delay(1);
Serial.println("Client disonnected");
Serial.println("");
}
마지막으로 테스트 할 예제는 blink의 웹버전이다. LED의 on/off를 웹브라우저에서 제어한다.
wifi_blink.ino
#include <ESP8266WiFi.h>
const char* ssid = "******";
const char* password = "*****";
WiFiServer server(80);
// 변수 지정
int LED_pin = 2;
int turn_on = 0;
int turn_off = 1;
void setup() {
Serial.begin(115200);
delay(10);
pinMode(LED_pin, OUTPUT);
digitalWrite(LED_pin, turn_off);
// 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);
client.flush();
// Match the request
int value = turn_off;
if (request.indexOf("/LED=ON") != -1) {
digitalWrite(LED_pin, turn_on);
value = turn_on;
}
if (request.indexOf("/LED=OFF") != -1) {
digitalWrite(LED_pin, turn_off);
value = turn_off;
}
// 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.print("Led pin is now: ");
if(value == turn_on) {
client.print("On");
} else {
client.print("Off");
}
client.println("brbr");
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("</html>");
delay(1);
Serial.println("Client disonnected");
Serial.println("");
}