'NodeMCU Lua 사용해보기 #12 - 인터넷을 통한 릴레이 제어 #1' 글에서는 어떻게 인터넷을 통해서 릴레이(Relay)를 제어할 수 있는지 알아보았다. 그런데 사용을 하다보면 원격지에서 어떤 릴레이가 현재 ON 상태이고 OFF 상태인지 알 수 있는 방법이 없다. 만약 릴레이에 선풍기를 연결해 두었으면 현재 꺼진 상태인지 켜진 상태인지 알 수가 없는 것이다. 그래서 이번에는 NodeMCU 의 gpio 모듈을 이용해서 현재 릴레이의 상태를 알 수 있도록 소스를 수정해서 개선해 보았다. 이전 글에서 모든 연결과 조건은 동일하며 internet_relay.lua 의 소스만 수정하면 된다.
■ NodeMCU gpio Module Documentation
위의 NodeMCU Documentation 사이트에 들어가면 gpio 모듈에 대한 설명이 나온다. 이 중에서 gpio.read() 를 이용해서 현재 릴레이의 상태를 알 수 있다.
위의 사이트에 들어가면 나오는 gpio.read() 의 사용설명이다. gpio.read(핀번호) 로 현재 해당 gpio 단자의 상태를 알 수 있다. 0 이면 Low, 1 이면 High 의 상태인 것이다. 릴레이에서는 High가 OFF, Low 가 ON 상태 이므로 릴레이 제어에 사용하는 4개의 gpio 핀의 상태를 읽어서 HTML 에서 출력해 주도록 internet_relay.lua 소스를 수정하면 될 것이다.
■ 소스
인터넷 연결을 위한 credentials.lua 와 init.lua 의 소스는 이전 1편의 글과 동일하다. internet_relay.lua 소스만 수정이 되었다. 그래도 모든 소스를 다시 올려 본다.
credentials.lua
1 2 3 4 | -- WiFi Connect information SSID = "WiFi Name(SSID)" PASSWORD = "WiFi Password" | cs |
init.lua
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | -- http://deneb21.tistory.com/ -- load credentials, 'SSID' and 'PASSWORD' declared and initialize in there dofile("credentials.lua") function startup() if file.open("init.lua") == nil then print("init.lua deleted or renamed") else print("WiFi Connected...") file.close("init.lua") -- the actual application is stored in 'application.lua' --dofile("webserver.lua") dofile("internet_relay.lua") end end print("Connecting to WiFi access point...") wifi.setmode(wifi.STATION) wifi.sta.config(SSID, PASSWORD) wifi.sta.connect() tmr.alarm(1, 1000, 1, function() if wifi.sta.getip() == nil then print("Waiting for IP address...") else tmr.stop(1) print("WiFi connection established, IP address: " .. wifi.sta.getip()) print("You have 3 seconds to abort") print("Waiting...") tmr.alarm(0, 3000, 0, startup) end end) | cs |
internet_relay.lua
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | --http://deneb21.tistory.com/ --Configure relay ouutput pins, pins are floating and relay opto needs ground to be activated. So pins are kept high on startup. Relay1 = 1 Relay2 = 2 Relay3 = 3 Relay4 = 4 gpio.mode(Relay1, gpio.OUTPUT) gpio.write(Relay1, gpio.HIGH); gpio.mode(Relay2, gpio.OUTPUT) gpio.write(Relay2, gpio.HIGH); gpio.mode(Relay3, gpio.OUTPUT) gpio.write(Relay3, gpio.HIGH); gpio.mode(Relay4, gpio.OUTPUT) gpio.write(Relay4, gpio.HIGH); print("internet relay standby...") --Create server and send html data, process request from html for relay on/off. srv=net.createServer(net.TCP) srv:listen(8080,function(conn) --change port number if required. Provides flexibility when controlling through internet. conn:on("receive", function(client,request) local html_buffer = ""; local html_buffer1 = ""; local html_buffer2 = ""; local gpio1, gpio2, gpio3, gpio4 local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP"); if(method == nil)then _, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP"); end local _GET = {} if (vars ~= nil)then for k, v in string.gmatch(vars, "(%w+)=(%w+)&*") do _GET[k] = v end end html_buffer = html_buffer.."<html><head><meta http-equiv=\"Content-Language\" content=\"en-us\"><meta http-equiv=\"Content-Type\" content=\"text/html;\">"; html_buffer = html_buffer.."</head><body><font size=5>Internet Relay1 Control (NodeMCU/Lua, ESP8266)</font></br>"; html_buffer1 = html_buffer1.."<a href=\"?pin=ON1\"><button style=\"width:300\">Relay1 ON</button></a><a href=\"?pin=OFF1\"><button style=\"width:300\">Relay1 OFF</button></a><br/>"; html_buffer1 = html_buffer1.."<a href=\"?pin=ON2\"><button style=\"width:300\">Relay2 ON</button></a><a href=\"?pin=OFF2\"><button style=\"width:300\">Relay2 OFF</button></a><br/>"; html_buffer1 = html_buffer1.."<a href=\"?pin=ON3\"><button style=\"width:300\">Relay3 ON</button></a><a href=\"?pin=OFF3\"><button style=\"width:300\">Relay3 OFF</button></a><br/>"; html_buffer1 = html_buffer1.."<a href=\"?pin=ON4\"><button style=\"width:300\">Relay4 ON</button></a><a href=\"?pin=OFF4\"><button style=\"width:300\">Relay4 OFF</button></a><br/>"; local _on,_off = "","" if(_GET.pin == "ON1")then gpio.write(Relay1, gpio.LOW); elseif(_GET.pin == "OFF1")then gpio.write(Relay1, gpio.HIGH); elseif(_GET.pin == "ON2")then gpio.write(Relay2, gpio.LOW); elseif(_GET.pin == "OFF2")then gpio.write(Relay2, gpio.HIGH); elseif(_GET.pin == "ON3")then gpio.write(Relay3, gpio.LOW); elseif(_GET.pin == "OFF3")then gpio.write(Relay3, gpio.HIGH); elseif(_GET.pin == "ON4")then gpio.write(Relay4, gpio.LOW); elseif(_GET.pin == "OFF4")then gpio.write(Relay4, gpio.HIGH); end -- Relay Status Read if(gpio.read(1)==0) then gpio1 = "ON" else gpio1 = "OFF" end if(gpio.read(2)==0) then gpio2 = "ON" else gpio2 = "OFF" end if(gpio.read(3)==0) then gpio3 = "ON" else gpio3 = "OFF" end if(gpio.read(4)==0) then gpio4 = "ON" else gpio4 = "OFF" end -- Relay Status print print("gpio1:"..gpio1) print("gpio2:"..gpio2) print("gpio3:"..gpio3) print("gpio4:"..gpio4) -- Relay Status print html html_buffer2 = html_buffer2.."<br/>Relay1 : "..gpio1; html_buffer2 = html_buffer2.."<br/>Relay2 : "..gpio2; html_buffer2 = html_buffer2.."<br/>Relay3 : "..gpio3; html_buffer2 = html_buffer2.."<br/>Relay4 : "..gpio4; html_buffer2 = html_buffer2.."</body></html>"; --Buffer is sent in smaller chunks as due to limited memory ESP8266 cannot handle more than 1460 bytes of data. client:send(html_buffer); client:send(html_buffer1); client:send(html_buffer2); client:close(); collectgarbage(); end) end) | cs |
internet_relay.lua 소스를 보면 65행 에서부터 gpio.read() 모듈을 사용해서 해당 릴레이의 상태값을 얻어온다. 얻어온 값 (0 은 ON, 1 은 OFF) 에 따라 'ON' 또는 'OFF' 문자열을 할당한다. 그리고 html_buffer2 에 릴레이 상태 표시를 위한 HTML 을 만들어 준다. 기존의 html_buffer 와 html_buffer1 에 html_buffer2 를 붙여서 클라이언트(브라우저) 요청 시 HTML 을 출력해 준다.
동작 화면을 캡처해 보았다. 릴레이가 동작하는 장면도 같이 찍고 싶었지만 손이 3개면 가능하겠는데 2개라 찍지 못했다. 아무튼 잘 작동한다. 브라우저를 닫았다가 다시 열어도 잘 작동한다.
이것을 조금 더 발전시킨다면 인터넷으로 켜고 끌 수 있는 멀티콘센트도 충분히 만들 수 있을 것 같다. 물론 샤오미를 비롯해서 이미 많은 기업에서 Smart Plug 또는 WiFi Plug 라는 이름으로 이미 나와 있지만 말이다.
Xiaomi Smart Plug
▶추가사항(2016.09.30) : 위의 소스를 작성하면서 참고한 소스와 사이트를 정리해 본다.
http://www.instructables.com/id/WiFi-Internet-Controlled-Relays-using-ESP8266-Quic/
'ESP8266' 카테고리의 다른 글
NodeMCU Lua #15 - 서보(Servo) 제어 (0) | 2016.08.11 |
---|---|
NodeMCU Lua 사용해보기 #14 - 인터넷에서 현재시간 가져오기 (2) | 2016.07.29 |
NodeMCU Lua 사용해보기 #12 - 인터넷을 통한 릴레이 제어 #1 (7) | 2016.07.26 |
NodeMCU Lua 사용해보기 #11 - dweet.io 온습도 데이터 업로드 (0) | 2016.07.19 |
MQTT 개념과 Mosquitto 설치 및 사용 (0) | 2016.07.12 |