반응형

이번에는 NodeMCU, Lua, ESP8266 (Amica Board) 를 가지고 인터넷을 통하여 릴레이(Relay) 를 제어해 보려고 한다. 릴레이에 대해서는 이 블로그에서 많이 다루었지만 인터넷으로 릴레이를 제어하는 것은 처음인 듯 하다. 릴레이를 인터넷을 통하여 제어할 수 있다는 의미는 세계 어디서든 인터넷에만 연결되어 있으면 집안 또는 원격지의 전기, 전자기구 들을 제어할 수 있다는 말과 같다. 활용하기에 따라 요즘 IoT 광고에 나오는 기능들을 충분히 DIY로 구현해 볼 수 있다고 생각한다.


릴레이는 예전에 테스트 해 보았던 4채널 릴레이 모듈을 이용했다. 4개의 릴레이가 붙어 있어서 4개의 전원을 ON/OFF 할 수 있다. VCC, GND 와 제어를 위한 IN1 ~ IN4 단자가 달려 있다.


ESP8266 보드는 이제껏 계속 사용해 왔던 위와 같은 Amica 라는 이름의 ESP8266 개발보드를 이용했다. 펌웨어는 'NodeMCU_float_0.9.6-dev_20150704' 버전을 이용했다. 


그런데 문제가 발생했다. 위의 개발보드의 단자를 보면 3.3V 출력 밖에 없다. 하지만 릴레이 모듈은 5V 에서 동작한다. 외부전원을 사용해 볼까? 생각하다가 그냥 보드의 3.3V 에 연결해서 테스트해 보기로 했다. 연결해보니 정상적으로 동작하긴 한다. 그러나 5V 로 동작할 때 보다 뭔가 릴레이의 접점이 붙는 소리가 힘이 없다. 테스트용으로는 상관이 없겠지만 신뢰성 있는 장치를 만들 경우에는 릴레이에 정격의 전압을 반드시 사용해야 할 듯 하다.


 ESP8266

 Relay (4 Channel)

 3.3V

 VCC

 GND

 GND

 D1

 IN1

 D2

 IN2

 D3

 IN3

 D4

 IN4


연결은 위의 표와 같이 해 주었다.


■ 소스

internet_relay.lua 소스는 http://www.robokits.co.in 의 소스를 참고하여 수정하였다. 원래는 2채널용 소스였고 잡다한 HTML 태그가 달려 있었는데 정리해 주고, 인터넷 연결 부분의 소스를 분리해 주었다.


credentials.lua

1
2
3
-- WiFi Connect information
SSID = "와이파이 이름"
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
-- 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(110001, 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(030000, 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
--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);
 
--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 _, _, 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 Relay 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/>";
        html_buffer1 = html_buffer1.."</body></html>";
    
    
        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
        --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:close();
        collectgarbage();
    end)
end)
 
cs


internet_relay.lua 소스를 보면 ESP8266 이 웹서버로 동작한다. 8080 포트로 클라이언트의 요청을 기다리고 있다가 클라이언트(브라우저)의 요청이 있을 경우 html_buffer 의 내용을 브라우저로 보내준다. HTML 의 내용에는 각 릴레이에 해당되는 버튼에 링크태그를 걸어서 버튼 클릭 시 pin 이라는 name 으로 릴레이의 ON/OFF value 를 보내준다. 이 값을 가지고 if 문을 이용하여 각각의 릴레이를 ON/OFF 하도록 제어하는 것이다.




위의 소스를 보드에 업로드 하고 브라우저에서 ESP8266에 할당된 IP + 설정한 포트번호를 치고 들어가면 위와 같이 버튼 8개가 나열된다. 각 버튼 클릭 시 릴레이 1 ~ 4 가 제대로 제어가 됨을 확인 하였다.



물론 위와 같이 공유기의 내부IP를 이용한 접속은 말 그대로 내부IP(사설IP)이기 때문에 집에서 밖에 콘트롤 할 수 없으며 별 의미가 없다.  이럴 경우는 공유기의 DDNS, 포트포워딩 설정을 이용하면 외부에서도 접근이 가능하다. 이에 대해서는 예전 글 "외부에서 NodeMCU 웹서버 접속하기" 를 참고하면 된다.



▶추가사항 (2016.07.29) : http://deneb21.tistory.com/427 에 조금 더 업그레이드 된 소스를 올려 놓았다. (릴레이 현재상태를 알 수 있도록 함.)

반응형

+ Recent posts