오늘 우리는 인터넷에 연결되어 사용자가 와이파이를 통해 집을 원격으로 제어할 수 있는 디바이스를 만들 것입니다. Arduino 보드(어떤 모델이든 상관없음)와 ESP8266-01 와이파이 모듈을 사용합니다. 시작해 봅시다!
스마트 홈이란?
작동 시나리오
컨트롤 패널
사용자가 우리 시스템에 연결된 가전제품을 제어할 수 있는 간단한 웹 페이지를 컨트롤 패널로 만들겠습니다. 웹 페이지 제작에는 다음을 사용합니다:
HTML
CSS
jQuery
임베디드 하드웨어
웹 페이지는 웹 서버로 작동하는 ESP8266-01에 명령을 보냅니다. 이 모듈은 아두이노 보드와 연결되어 있습니다. 수신된 데이터에 따라 아두이노는 전구 켜기, TV 끄기 등의 동작을 수행합니다. 이 부분에서는 다음을 사용합니다:
Arduino
ESP8266-01
ESP8266-01 시작하기
앞서 말했듯 아두이노 보드를 인터넷에 연결해야 하지만, 오늘 사용할 Arduino Nano에는 이 기능이 없습니다. 그래서 ESP8266-01 와이파이 모듈을 사용해 작은 아두이노 보드에 와이파이 기능을 추가합니다.
시중에는 많은 ESP 와이파이 모듈 모델이 있습니다. 어떤 것을 선택해야 할까요? 거의 모든 ESP 패밀리 모듈이 작업을 잘 수행하지만, 각각 고유한 특징과 사양이 있습니다. 각 모델의 사양과 기능을 살펴보고 필요에 가장 적합한 것을 선택하시기 바랍니다.
내 필요에 따르면 ESP8266-01이 가장 적합합니다. 여러 이유가 있습니다. 메이커 커뮤니티에서 매우 유명하여 거의 모든 질문이나 문제에 대한 답을 찾을 수 있는 탄탄한 온라인 커뮤니티가 있습니다. 가격도 매우 저렴합니다(약 1.5달러).
또한 아두이노 보드와 사용하기 매우 쉽습니다. 시리얼 와이파이 모듈이라 시리얼 통신으로 아두이노와 통신할 수 있습니다. 내장 마이크로컨트롤러가 있어 독립형 마이크로컨트롤러와 와이파이 모듈 콤보로 사용할 수 있습니다. 내장 GPIO 2개도 있습니다. 이 모든 기능을 1.5달러에 얻을 수 있다니 정말 훌륭합니다. 이 모듈을 자세히 살펴보겠습니다.
ESP8266-01 핀아웃
VCC: +3.3V 전원에 연결. 5V 소스에 연결하지 마세요. 손상됩니다.
GND: 음극 핀, 회로의 그라운드에 연결.
CH_PD: 칩 활성화 핀 - 활성 HIGH. 로직 HIGH로 연결해 모듈 부팅 허용.
RST: 칩 리셋 핀 - 활성 LOW. LOW로 당겨지면 모듈 리셋.
GPIO0, GPIO2: 범용 입출력 핀.
Tx: 마이크로컨트롤러(아두이노)의 Rx에 연결해 시리얼 통신 수립.
Rx: 마이크로컨트롤러(아두이노)의 Tx에 연결해 시리얼 통신 수립.
ESP8266-01 설정
앞서 언급했듯 ESP8266-01은 아두이노의 시리얼 핀 0, 1(Tx, Rx)을 통해 아두이노와 통신합니다. 하지만 이 핀들은 아두이노 시리얼 모니터를 디버깅용으로 함께 사용하므로 바쁩니다. 따라서 ESP8266-01과 사용할 다른 두 개의 시리얼 통신 핀이 필요합니다.
다행히 아두이노가 이를 쉽게 만들었습니다. "SoftwareSerial" 라이브러리가 있어 소프트웨어로 기능을 복제해 아두이노의 다른 디지털 핀에서 시리얼 통신을 할 수 있습니다. 예를 들어 이 라이브러리로 핀 2, 3을 Rx, Tx로 설정해 하드웨어 시리얼(핀 0, 1)과 함께 사용할 수 있습니다.
"SoftwareSerial" 라이브러리는 전송 속도가 19,200 보드 이하일 때 잘 작동합니다. 하지만 작은 문제가 있습니다! ESP8266-01은 공장에서 115,200 보드로 통신하도록 프로그래밍되어 있어 "SoftwareSerial" 라이브러리로는 통신하기 어렵습니다. 그래서 와이파이 모듈을 재프로그래밍해 통신 속도를 "SoftwareSerial"과 잘 맞는 9600 보드로 변경해야 합니다. 이를 위해 "AT 명령어"를 사용합니다.
ESP8266-01 통신 속도 변경하기
1단계: 아두이노에 빈 프로그램 업로드
아두이노 보드에 빈 코드를 업로드합니다. 아두이노가 백그라운드에서 아무것도 실행하지 않는지 확인하기 위함입니다.
2단계: ESP8266-01을 아두이노 보드에 배선
ESP8266-01을 재설정하고 통신 속도(보드레이트)를 변경하기 위해 AT 명령어를 사용합니다. AT 명령어는 모뎀, 휴대폰, 블루투스 모듈, 와이파이 모듈, GSM 모듈 등을 제어하는 명령어입니다. 제조사명, 모델 번호, IMEI 등 기본 정보를 얻을 수 있습니다. "AT"는 "ATtention"의 약자이며, 모든 명령어가 "AT"로 시작하므로 AT 명령어라 부릅니다. "AT" 접두사는 명령어 자체의 일부가 아니라 명령어의 시작을 알리는 역할만 합니다.
중요한 AT 명령어들
명령어 4번은 ESP8266-01 펌웨어 버전에 따라 다릅니다. AT+CIOBAUD=<baud>가 작동하지 않으면 AT+UART_DEF=<baud>,8,1,0,0을 시도해 보세요.
1단계: 시리얼 모니터 열기
2단계: 통신 속도를 115,200 보드로 설정
앞서 말했듯 ESP는 공장에서 115,200 보드로 통신하도록 설정되어 있습니다. 따라서 처음에만 아두이노 통신 속도도 115,200으로 맞춥니다. 나중에 변경할 것입니다. 또한 "Both NL & CR"을 선택해야 합니다.
3단계: "AT" 전송 후 응답 확인
ESP 모듈이 내 말을 듣고 있는지 확인합니다.
4단계: ESP8266-01 통신 속도 변경
내 ESP8266-01 모듈의 펌웨어 버전은 1.6입니다. AT+UART_DEF=<baud>,8,1,0,0 명령어가 잘 작동했습니다. 안 되면 AT+CIOBAUD=<baud>를 시도하세요. "OK" 응답이 오면 통신 보드레이트가 115,200에서 9600으로 변경된 것입니다. 축하합니다!
시리얼 모니터 통신 속도를 다시 9600으로 변경하고 "AT"를 전송해 새 속도(9600)에서 ESP 모듈이 들리는지 확인합니다.
보세요! 작동합니다. ESP8266-01이 이제 115,200 보드 대신 9600 보드레이트로 아두이노 보드와 통신할 수 있습니다.
이제 와이파이 네트워크에 연결해 봅시다
엔터를 누르면 ESP8266-01이 네트워크를 검색하고 연결합니다. 성공하면 다음을 반환합니다:
WIFI CONNECTED
WIFI GOT IP
이 시점에서 ESP8266-01의 통신 속도를 115,200 보드에서 9600 보드로 성공적으로 변경했습니다. 이제 사용자가 가전제품을 제어할 컨트롤 패널(웹 페이지)을 만들 차례입니다. 만들어 봅시다!
인터넷이란?
사실 인터넷은 땅속에 묻힌 선입니다. 광섬유, 구리선, 위성일 수도 있지만 인터넷은 단순히 선입니다. 그 선에 직접 연결된 두 컴퓨터는 통신할 수 있습니다. 컴퓨터가 그 선에 직접 연결되면 서버라고 하고, 직접 연결되지 않으면 클라이언트라고 합니다.
서버: 아파치 같은 특정 운영체제를 실행하는 특수 컴퓨터로, 웹 페이지, 파일, 데이터베이스를 디스크에 저장합니다. 인터넷에 연결된 모든 서버는 172.217.171.228 같은 고유한 IP 주소를 가집니다. IP 주소는 사람들을 쉽게 찾아주 전화번호 같은 것입니다. IP 주소는 사람이 외우기 어려우니 이름을 붙였습니다. google.com(도메인 이름).
클라이언트: 우리 같은 일반 컴퓨터로, 인터넷 서비스 공급자(ISP)를 통해 간접적으로 인터넷에 연결되며 고유한 IP 주소를 가집니다.
작동 시나리오
간단히 말해, 웹 브라우저(클라이언트)에서 요청을 보내고 웹 서버에서 응답을 받는 것으로 시작합니다.
컴퓨터(클라이언트)의 브라우저에서 makesomestuff.org 같은 웹사이트 URL을 입력하면, 브라우저는 웹사이트를 호스팅하는 웹 서버에 요청을 보냅니다. 웹 서버는 HTML 페이지나 다른 문서 형식을 포함한 응답을 브라우저에 반환해 표시합니다.
오늘 우리 프로젝트에서 정확히 해야 할 일입니다. 같은 로컬 네트워크에 연결된 웹 브라우저(클라이언트)에서 ESP8266-01(웹 서버)로 요청을 보냅니다. 이 요청에는 아두이노에 전구 켜기/끄기 등을 지시하는 데이터가 들어 있습니다. 자, 웹 페이지를 만들어 봅시다!
웹 페이지 만들기
웹 페이지를 만들려면 HTML, CSS, 자바스크립트를 다뤄야 합니다. 이 이름들을 처음 들어봤다면 걱정하지 마세요. 제가 다 설명해 드리겠습니다.
HTML: "HyperText Markup Language"의 약자로 웹 페이지의 주요 구조를 만드는 데 사용합니다. 버튼, 이미지, 문단, 헤더, 테이블 등 다양한 요소를 추가합니다. 브라우저가 웹 페이지 콘텐츠를 어떻게 표시할지 알려주는 일련의 요소로 구성되며, 이 요소들은 태그로 표현됩니다.
CSS: "Cascading Style Sheets"의 약자입니다. 웹 페이지 주요 구조를 만든 후 예쁘게 꾸미는 데 사용합니다. HTML 요소의 스타일을 설명하는 언어입니다. 선택자와 선언 블록으로 구성됩니다.
자바스크립트: 웹 페이지를 더 인터랙티브하게 만드는 프로그래밍 언어입니다. 애니메이션, 지도 추가나 복잡한 기능 구현에 사용합니다. 오늘은 주로 웹 브라우저(클라이언트)에서 웹 서버(ESP8266-01)로 HTTP 요청을 보내 전구 켜기/끄기 등의 동작을 수행하는 데 사용합니다.
웹 페이지 구조 만들기
다가올 설명을 쉽게 이해하려면 이 멋진 HTML 입문을 읽어보시길 권장합니다.
우리의 컨트롤 패널은 매우 단순합니다. 크기가 다른 헤더 두 개, 이미지 하나, LED 켜기/끄기 버튼 두 개가 있습니다.
코드
<!DOCTYPE html>
<html>
<head>
<title>Smart Home System</title>
</head>
<body>
<h1> Smart Home Control Panel</h1>
<h4>Sorry But I'm a Meme Addict!</h4>
<img src="dogMeme.jpg" width="400px" height="400px">
<br>
<button id="111" class="button">LAMP ON</button>
<br>
<button id="110" class="button">LAMP OFF</button>
</body>
</html>
코드 설명
<!DOCTYPE html>: 이 문서가 HTML5 문서임을 선언합니다.
<html>: HTML 페이지의 루트 요소입니다.
<head>: 페이지에 대한 메타 정보를 포함합니다.
<title>: 문서 제목을 지정합니다. 브라우저 탭에 표시됩니다.
<body>: 웹 페이지의 가시적 콘텐츠를 포함합니다.
<h1>: 큰 헤더를 정의합니다.
<h4>: 더 작은 헤더를 정의합니다. 헤더 값이 작아질수록 글자 크기도 작아집니다.
<img>: 웹 페이지에 이미지를 추가합니다. 표시할 이미지는 프로젝트 폴더와 같은 위치에 있어야 합니다.
<br>: 커서를 새 줄로 이동시킵니다.
<button>: 페이지 콘텐츠에 버튼을 추가합니다.
웹 페이지의 각 버튼에는 매우 중요한 두 속성인 id와 class가 있습니다. 이 두 값을 버튼에 할당한 이유는 jQuery 코드 설명에서 다루겠습니다.
웹 페이지 스타일링
다가올 설명을 쉽게 이해하려면 이 멋진 CSS 입문을 읽어보시길 권장합니다.
이제 웹 페이지가 더 멋져 보입니다(너무 많이는 아니지만요). 멋진 녹색 배경색을 주고, 페이지 콘텐츠를 중앙 정렬했으며, 헤더 글자 색과 글꼴을 바꿔 페이지를 더 생동감 있게 만들었습니다. 이 모든 스타일링을 CSS로 했습니다.
코드
<!DOCTYPE html>
<html>
<head>
<title>Smart Home System</title>
</head>
<body style="background-color: seagreen; color: seashell; text-align: center;">
<h1> Smart Home Control Panel</h1>
<h4>Sorry But I'm a Meme Addict!</h4>
<img src="dogMeme.jpg" width="400px" height="400px">
<br>
<button style="margin: 10px;" id="111" class="button">LAMP ON</button>
<br>
<button style="margin:10px;" id="110" class="button"> LAMP OFF</button>
</body>
</html>
코드 설명
몇 줄의 코드를 추가해 웹 페이지를 더 예쁘게 만들었습니다. style="background-color: seagreen; color: seashell; text-align: center;"를 body 태그 안에 넣어 모든 웹 페이지 콘텐츠를 페이지 중앙에 배치하고, 배경색을 seagreen으로, 글자 색을 seashell로 설정했습니다.
또한 두 버튼 태그 안에 style="margin: 10px;"를 추가해 각 버튼의 네 면에 10픽셀 여백을 주었습니다.
웹 서버로 요청 보내기
다가올 설명을 쉽게 이해하려면 이 멋진 jQuery 입문을 읽어보시길 권장합니다.
이제 웹 페이지 구조를 만들고 스타일링했으니, 앞서 추가한 두 버튼에 기능을 추가해야 합니다. 사용자가 "LAMP ON" 버튼을 클릭하면 브라우저가 고유한 데이터를 담아 서버(ESP8266-01)로 요청을 보냅니다. 이 고유한 데이터는 아두이노에 전구를 켜라고 지시합니다. "LAMP OFF" 버튼도 마찬가지입니다. 클릭하면 브라우저가 고유한 데이터를 담아 서버로 요청을 보내고, 아두이노는 전구를 끕니다. 코드를 봅시다.
<!DOCTYPE html>
<html>
<head>
<title>Smart Home System</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body style="background-color: seagreen; color: seashell; text-align: center;">
<h1> Smart Home Control Panel</h1>
<h4>Sorry But I'm a Meme Addict!</h4>
<img src="dogMeme.jpg" width="400px" height="400px">
<br>
<button style="margin: 10px;" id="111" class="button">LAMP ON</button>
<br>
<button style="margin:10px;" id="110" class="button"> LAMP OFF</button>
<script>
// 자바스크립트 시작
$(".button").click(function () {
// "button" 클래스의 버튼이 클릭되면
var p = $(this).attr('id');
// 이 버튼의 id를 가져와 "p" 변수에 저장
pin: p
// 웹 서버로 보낼 버튼 id를 담은 딕셔너리
$.get("https://192.168.1.4:80/", {
// 웹 서버 "https://192.168.1.4:80/"로 GET 요청 전송
// (":80"은 포트 번호 80) 딕셔너리 형태 {pin: p}로 데이터 전송
// 중요: IP 주소를 본인의 ESP8266 새 IP 주소로 변경하세요!
pin: p
});
});
</script>
</body>
</html>
코드 설명
가장 먼저 jQuery 라이브러리를 코드에 가져와야 합니다. 그래서 head 태그에 이 줄을 추가했습니다.
<script>
// 자바스크립트 시작
$(".button").click(function () {
// "button" 클래스의 버튼이 클릭되면
var p = $(this).attr('id');
// 클릭된 버튼의 "id" 속성 값을 가져와 "p" 변수에 저장
pin: p
// 웹 서버로 보낼 버튼 id를 담은 딕셔너리 (키-값)
$.get("https://192.168.1.4:80/", {
// 웹 서버 "https://192.168.1.4:80/"로 GET 요청 전송
// (":80"은 포트 번호 80) 딕셔너리 {pin: p} 형태의 데이터 전송
// 중요: IP 주소를 본인의 ESP8266 새 IP 주소로 변경하세요!
pin: p
});
});
</script>
$(".button").click(function () {: 사용자가 "button" 클래스와 연결된 버튼을 클릭하면 다음 함수를 실행합니다.
var p = $(this).attr('id');: 클릭된 버튼의 "id" 속성 값을 가져와 "p" 변수에 저장합니다.
pin: p: 변수 "p"의 값을 딕셔너리(키-값) 형태로 넣습니다. 키는 "pin", 값은 "p" 변수 값입니다.
$.get("https://172.20.10.11:80/", { pin: p });});: IP 주소가 "172.20.10.11"인 웹 서버로 GET 요청을 보냅니다. 이 GET 요청에는 클릭된 버튼의 id 속성 값이 들어 있습니다.
사용자가 "LAMP ON" 버튼을 누르면 id 값이 111이므로 GET 요청 헤더에 pin=111 같은 데이터가 포함됩니다. 다음 그림을 보세요!
반대로 "LAMP OFF" 버튼을 누르면 요청에 pin=110 데이터가 포함됩니다.
코드 로직
왜 하필 111과 110을 선택했는지 궁금하실 겁니다. 답해 드리죠. 사실 111과 110은 두 부분으로 나뉩니다.
1부: 앞의 두 숫자로, 둘 다 "11"입니다. 이는 제어하려는 부하가 연결된 아두이노 핀 번호를 의미합니다.
2부: 세 번째 숫자로, 클릭된 버튼에 따라 1과 0으로 바뀝니다. 이는 핀 상태(ON 또는 OFF)를 의미합니다.
아두이노 코드에서 이 데이터를 수신해 두 부분을 분리하고 각각 다른 변수에 저장합니다. 1부는 pinNumber 변수에, 2부는 pinState 변수에 저장한 후, 연결된 부하를 제어하는 간단한 코드 한 줄을 실행합니다: digitalWrite(pinNumber, pinState);
부하 연결하기
이제 아두이노 보드에 부하를 연결해 제어해야 합니다. 에어컨이나 TV 같은 고전압 장치를 연결하기 전에, LED 같은 저전압 부품으로 회로와 코드를 테스트해 모든 것이 잘 작동하는지 확인해야 합니다. 배선도는 다음과 같습니다.
배선은 매우 간단합니다. LED 양극을 아두이노 디지털 핀 11에, 음극을 1k옴 저항을 통해 GND에 연결합니다.
아두이노 코드
#include <SoftwareSerial.h> // SoftwareSerial 라이브러리로 핀 2,3을 Rx, Tx로 사용
SoftwareSerial esp8266(2,3); // Rx => 핀 2, Tx => 핀 3
#define serialCommunicationSpeed 9600 // 소프트웨어/하드웨어 시리얼 통신 속도(보드레이트)
#define DEBUG true // 디버그용 상수
int redLED = 12; // 빨간 LED가 연결된 핀
int blueLED = 11; // 파란 LED가 연결된 핀
void setup() {
pinMode(redLED, OUTPUT);
pinMode(blueLED, OUTPUT);
digitalWrite(redLED, LOW); // 프로그램 시작 시 빨간 LED 끔
digitalWrite(blueLED, HIGH); // 프로그램 시작 시 파란 LED 켬
Serial.begin(serialCommunicationSpeed); // 하드웨어 시리얼(0,1) 9600으로 시작
esp8266.begin(serialCommunicationSpeed); // 소프트웨어 시리얼(2,3) 9600으로 시작
InitWifiModule(); // ESP8266과 액세스 포인트(홈 라우터 또는 모바일 핫스팟) 간 통신 초기화
digitalWrite(blueLED, LOW); // 초기화 완료 후 파란 LED 끔 (인디케이터)
}
void loop() {
if(esp8266.available()) {
if(esp8266.find("+IPD,")) {
delay(1000); // 데이터가 버퍼에 채워지길 1초 대기
int connectionId = esp8266.read()-48; // read()는 ASCII 십진값 반환. 0은 48부터 시작하므로 48 빼서 문자값으로 변환
esp8266.find("pin="); // 요청 헤더의 "pin=" 부분으로 커서 이동해 핀 번호와 상태 읽기
int pinNumber = (esp8266.read()-48)*10; // 첫 번째 바이트 읽기(핀 12면 첫 숫자는 1) 후 10 곱하기. pinNumber = 10
pinNumber = pinNumber + (esp8266.read()-48); // 두 번째 바이트 읽기(핀 12면 두 번째 숫자는 2) 더하기. pinNumber = 12
int statusLed = (esp8266.read()-48); // 세 번째 바이트 읽어 statusLed에 저장. 1 또는 0
digitalWrite(pinNumber, statusLed); // pinNumber의 LED를 statusLed 값에 따라 켜거나 끔
Serial.println(connectionId); // 디버깅용 시리얼 모니터 출력
Serial.print(pinNumber);
Serial.print(" ");
Serial.println(statusLed);
String closeCommand = "AT+CIPCLOSE="; // TCP/IP 연결 종료
closeCommand += connectionId;
closeCommand += "\r\n"; // 엔터 키 시뮬레이션
sendData(closeCommand, 1000, DEBUG); // ESP8266에 명령 전송 실행
}
}
}
/******************************************************************************************************************************************************************************************
* 이름: sendData
* 설명: AT 명령어가 ESP8266으로 전송되는 방식을 제어
* 매개변수: command - 보낼 AT 명령어, timeout - 응답 대기 시간, debug - 시리얼 창에 출력?(true=예, false=아니오)
* 반환: esp8266의 응답(있는 경우)
******************************************************************************************************************************************************************************************/
String sendData(String command, const int timeout, boolean debug) {
String response = "";
esp8266.print(command); // AT 명령어를 esp8266으로 전송 (아두이노 -> ESP8266)
long int time = millis(); // 현재 시간 저장
while((time+timeout) > millis()) { // 1초 동안만 실행
while(esp8266.available()) { // ESP8266에서 온 응답이 아두이노 입력 버퍼에 있는가?
char c = esp8266.read(); // 있으면 다음 문자 읽어 response 문자열 변수에 저장
response += c; // 다음 문자를 response 변수에 추가. 마지막엔 응답을 담은 문자열 배열 완성
}
}
if(debug) { // debug 변수가 TRUE면 시리얼 모니터에 응답 출력
Serial.print(response);
}
return response; // 문자열 응답 반환
}
/******************************************************************************************************************************************************************************************
* 이름: InitWifiModule
* 설명: sendData() 함수로 보낼 AT 명령어들을 제공
* 매개변수: 없음
* 반환: 없음 (void)
******************************************************************************************************************************************************************************************/
void InitWifiModule() {
sendData("AT+RST\r\n", 2000, DEBUG); // ESP8266 모듈 리셋
// delay(1000);
sendData("AT+CWJAP=\"PUT YOUR SSID\",\"PUT YOUR PASSWORD\"\r\n", 2000, DEBUG); // 와이파이 네트워크 연결
delay(3000);
sendData("AT+CWMODE=1\r\n", 1500, DEBUG); // ESP8266 와이파이 모드를 스테이션 모드로 설정
delay(1000);
sendData("AT+CIFSR\r\n", 1500, DEBUG); // IP 주소, MAC 주소 표시
delay(1000);
sendData("AT+CIPMUX=1\r\n", 1500, DEBUG); // 다중 연결
delay(1000);
sendData("AT+CIPSERVER=1,80\r\n", 1500, DEBUG); // 포트 80에서 통신 시작, HTTP 요청용 포트 80
}
코드 설명
코드는 꽤 직관적입니다. InitWifiModule()과 sendData() 두 가지 함수를 구현했습니다.
sendData() 함수는 AT 명령어가 ESP8266-01 모듈로 전송되는 방식을 제어합니다.
InitWifiModule() 함수는 sendData() 함수에 ESP8266-01로 보낼 AT 명령어들을 제공합니다.
loop() 함수에서 들어오는 HTTP 요청 헤더를 읽고 "+IPD,"를 검색합니다. 이는 요청이 성공적으로 도착했음을 의미합니다. 그런 다음 핀 값을 읽는데, 사용자가 "LAMP ON" 버튼을 클릭했으면 "111", "LAMP OFF" 버튼을 클릭했으면 "110"이 됩니다.
아두이노 코드 103번째 줄에 와이파이 SSID와 비밀번호를 넣는 것을 잊지 마세요:
sendData("AT+CWJAP=\"PUT YOUR SSID\",\"PUT YOUR PASSWORD\"\r\n", 2000, DEBUG);
자세한 코드 설명은 코드 내 주석을 참고하세요. 잘 문서화되어 있습니다.
작동 원리
아두이노 보드에 코드를 업로드한 후 시리얼 모니터를 열고 ESP 모듈이 보내는 응답을 읽습니다.
프로그램 초기에 이전 그림처럼 페이지 끝에 "OK"가 보이면 ESP8266-01 모듈이 와이파이(액세스 포인트)에 성공적으로 연결되어 IP와 MAC 주소를 받은 것입니다. 이제 멋진 웹 페이지를 열고 이것저것 제어해 보세요 😉
하지만 이전 그림처럼 페이지 끝에 "FAIL" 또는 "ERROR"가 보이면 ESP 모듈이 어떤 이유로든 와이파이(액세스 포인트)에 연결할 수 없는 것입니다. 네트워크의 올바른 SSID와 비밀번호를 입력했는지 확인해 보세요.
고전압 부하 추가하기
코드를 테스트해 모든 것이 완벽하게 작동함을 확인한 후, 지루한 LED를 에어컨, TV, 전구 같은 고전압 부하로 교체해야 합니다. 하지만 이러한 고전압 가전제품을 제어하려면 릴레이를 다뤄야 합니다.
릴레이가 무엇이고 왜 필요한가요? 릴레이는 코일에 전원을 공급해 켜고 끄는 기계식 스위치입니다. 주로 저전력 신호(5V 또는 0V)로 고전력 회로를 제어하는 데 사용됩니다. 따라서 5V 또는 0V 신호만으로 에어컨이나 AC 램프 같은 고전력 장치를 켜고 끌 수 있습니다. 정말 놀랍죠!
2채널 릴레이 모듈에는 두 개의 제어 핀(IN1, IN2)이 있습니다. 이 핀들은 두 개의 아두이노 디지털 핀에 연결해 두 코일의 상태(부하 회로 닫기/열기)를 제어합니다.
릴레이 모듈의 반대편에서 COM(공통)은 부하 한쪽 끝에 연결해야 합니다. 부하의 다른 쪽 끝은 NC(상시 닫힘) 또는 NO(상시 열림)에 연결합니다. NO에 연결하면 트리거 전에는 부하가 분리되고, NC면 반대입니다.
배선도
보시다시피 2채널 릴레이 모듈을 사용해 두 개의 다른 AC 부하를 제어할 수 있습니다. 첫 번째 릴레이를 아두이노 디지털 출력 핀 11에, 두 번째 릴레이를 디지털 출력 핀 12에 연결했습니다.
웹 페이지를 약간 수정해 두 번째 연결 부하를 제어할 ON/OFF 버튼 두 개를 추가하겠습니다.
<!DOCTYPE html>
<html>
<head>
<title>Smart Home System</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body style="background-color: seagreen; color: seashell; text-align: center;">
<h1> Smart Home Control Panel</h1>
<h4>Sorry But I'm a Meme Addict!</h4>
<img src="dogMeme.jpg" width="400px" height="400px">
<br>
<button style="margin: 10px;" id="111" class="button">Blue LED ON</button>
<button id="110" class="button">Blue LED OFF</button>
<br>
<button style="margin:10px;" id="121" class="button"> Red LED ON</button>
<button id="120" class="button">Red LED OFF</button>
<script>
// 자바스크립트 시작
$(".button").click(function () {
var p = $(this).attr('id');
pin: p
$.get("https://192.168.1.4:80/", {
pin: p
});
});
</script>
</body>
</html>
작동 원리
지난 시도와 똑같습니다. 아두이노 코드를 보드에 업로드하고(아직 안 했다면) 시리얼 모니터를 열어 ESP 모듈이 액세스 포인트에 성공적으로 연결되어 IP와 MAC 주소를 받았는지 확인합니다.
그런 다음 멋진 웹 페이지를 열고 제어를 시작하세요 😉
더 전문적으로 만들기!
브레드보드 회로를 전문적인 인쇄 회로 기판 (PCB)로 옮겨 프로젝트를 더 견고하고 튼튼하게 만들어볼까요? Autodesk Eagle 소프트웨어로 프로젝트 회로를 설계했습니다. 모든 PCB 파일은 오픈소스로 다음 링크에서 접근 가능합니다: https://www.pcbway.com/project/shareproject/IoT_Using_Arduino_and_ESP8266_01.html
우리는 오픈소스를 사랑하니까요 😉
자신만의 PCB를 PCBWay에서 주문하세요. 이 회사는 이 분야에서 평판이 매우 좋으며 170개 이상의 국가로 합리적인 가격에 배송합니다. 프로젝트 PCB 파일 링크를 열고 "장바구니에 담기"만 누르면 됩니다!
문제 해결
ESP 모듈이 액세스 포인트에 성공적으로 연결되었지만 웹 페이지 버튼을 클릭해도 아무 반응이 없는 경우
웹 브라우저에서 포트 80(HTTP)으로 요청을 보내는지 확인하세요. 예: $.get("https://192.168.1.4:80/")
PC/노트북과 ESP 모듈이 같은 액세스 포인트에 연결되어 있는지 확인하세요.
jQuery 코드에서 올바른 ESP 모듈 IP 주소를 썼는지 확인하세요.
부하가 아두이노 디지털 핀 11, 12에 연결되어 있는지 확인하세요.
웹 페이지 코드 파일 수정 후 저장하고, 웹 브라우저에서 페이지를 새로고침해 변경사항을 적용하세요.
마무리
완료했습니다! 오늘 튜토리얼에서 HTML, CSS, jQuery로 간단한 웹 페이지를 만드는 법, 웹 기반 컨트롤 패널로 AC 부하를 무선 제어하는 법, 멋진 ESP8266-01 와이파이 모듈을 아두이노 보드와 사용하는 법을 배웠습니다.
더 많은 튜토리얼과 오픈소스 프로젝트를 보고 싶다면 제 블로그 www.makesomestuff.org를 방문하세요.
마지막으로, 질문 있으시면 아래 댓글란에 남겨주세요. 기꺼이 답변해 드리겠습니다 😉
코드
웹 페이지
최종 아두이노 코드
웹 페이지 HTML
<!DOCTYPE html>
<html>
<head>
<title>Smart Home System</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body style="background-color: seagreen; color: seashell; text-align: center;">
<h1> Smart Home Control Panel</h1>
<h4>Sorry But I'm a Meme Addict!</h4>
<img src="dogMeme.jpg" width="400px" height="400px">
<br>
<button style="margin: 10px;" id="111" class="button">Blue LED ON</button>
<button id="110" class="button">Blue LED OFF</button>
<br>
<button style="margin:10px;" id="121" class="button"> Red LED ON</button>
<button id="120" class="button">Red LED OFF</button>
<script>
$(".button").click(function () {
var p = $(this).attr('id');
pin: p
$.get("https://192.168.1.4:80/", {
pin: p
});
});
</script>
</body>
</html>