사물인터넷(IoT)2016. 7. 9. 12:12

예전에 IoT 클라우드 서비스인 ThingSpeak.com 에 대해서 알아보고 실제로 ESP8266 모듈인 ESP-01과 아두이노를 이용해서 DHT22 의 온도, 습도 데이터를 ThingSpeak 에 올려본 적이 있습니다. 하지만 AT Command 기반 이었고 ESP-01 은 아두이노에서 읽은 센서 데이터를 받아서 인터넷에 올려주는 역할만을 했습니다. 이번에는 NodeMCU 를 이용해서 DHT11 센서의 온도와 습도 데이터를 ThingSpeak 에 올려보도록 하겠습니다. 지난 글에서 구현 했던 DHT11 센서의 데이터를 읽어서 온도, 습도를 알려주는 웹서버는 인터넷을 통해서 들어오는 요청에 대해서 응답을 줬었지만 ThingSpeak 연동은 센서 데이터를 ESP8266을 통해서 보내는 것이므로 반대의 개념이 되겠습니다. ThingSpeak 서비스에 대해서는 예전에 자세하게 다룬 적이 있어서 링크로 대신 합니다. 



ThingSpeak 서비스 개념도 입니다. 센서로 부터 데이터를 받은 ESP8266 보드가 데이터를 ThingSpeak 서버에 업로드하고 그 데이터를 스마트폰, PC, 아두이노, 또 다른 ESP8266 등 n개의 장치로 보내서 활용이 가능 합니다. 물론 받은 데이터로 또 다른 장치를 제어할 수도 있습니다. 활용하기 나름이죠.


ESP8266 보드는 여전히 ESP-12E 기반의 Amica 보드를 이용 합니다. 센서는 DHT11 온도 습도 센서를 이용합니다. 센서와 ESP8266 개발보드와의 연결은 아래의 이전 글 을 참고해서 연결하면 됩니다. 똑같습니다. 다시 말하자면 센서의 전원은 Amica 보드의 3.3V 에 연결하고 Signal 은 D5에 연결했습니다.


이제 ESPlorer를 열고 ESP8266 Amica 보드를 연결하고 코딩을 합니다. credentials.lua 와 init.lua 는 NodeMCU 웹서버 만들기 글에서 사용한 것과 동일 합니다. 대신 dht11_thingspeak.lua 를 init.lua 에서 call 해 줍니다.


■ 소스 #1 (credentials.lua)

1
2
3
4
-- WiFi Connect information
SSID = "your wifi name"
PASSWORD = "your wifi password"
 
cs



■ 소스 #2 (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")
        dofile("dht11_thingspeak.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


■ 소스 #3 (dht11_thingspeak.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
pin = 5 -- dht11 signal pin
temp = 0
humi = 0
writekey = "your thinkspeak channel write api key"
 
tmr.alarm(1,15000,1,function()readDHT()sendData(temp,humi)end)
 
--read DHT11 temp, humi data function
function readDHT()
    status, temp, humi = dht.read(pin)
    if status == dht.OK then
        temp = math.floor(temp)
        humi = math.floor(humi)
    elseif status == dht.ERROR_CHECKSUM then
        print"DHT Checksum error." )
    elseif status == dht.ERROR_TIMEOUT then
        print"DHT timed out." )
    end
    dht = nil
end
 
--send data to thingspeak
function sendData(temp,humi)
    -- conection to thingspeak.com
    print("Sending data to thingspeak.com")
    conn=net.createConnection(net.TCP, 0
    conn:on("receive", function(conn, payload) print(payload) end)
    
    -- api.thingspeak.com 184.106.153.149
    conn:connect(80,'184.106.153.149'
    conn:send("GET /update?key="..writekey.."&field1="..temp.."&field2="..humi.." HTTP/1.1\r\n"
    conn:send("Host: api.thingspeak.com\r\n"
    conn:send("Accept: */*\r\n"
    conn:send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n")
    conn:send("\r\n")
    conn:on("sent",function(conn)
    print("Closing connection")
    conn:close()
    end)
    conn:on("disconnection", function(conn)
    print("Got disconnection...")
  end)
end
 
cs


인터넷을 통해서 thingspeak에 dht11 의 온도, 습도 데이터를 업로드 하는 소스 입니다. 4번째 줄 writekey 부분에 자신의 thingspeak 채널의 Write API Key 를 입력해야 합니다.


물론 thingspeak 채널에는 온도, 습도를 받을 수 있는 2개의 field 가 등록되어 있어야 합니다. 위의 링크의 thingspeak 글을 참고하면 쉽게 만들 수 있습니다.



소스를 모두 업로드 하고 장치를 Soft Reset 하면 위와 같이 데이터를 ThinsSpeak 에 업로드 하기 시작 합니다.


ThingSpeak.com 에 접속해서 데이터를 업로드 하고 있는 채널에 들어가면 위와 같이 우리집 온도와 습도가 그래프로 표시 됩니다. 물론 스마트폰 웹브라우저로도 볼 수 있으며 데이터를 csv, json, xml 형식으로 다운로드 받을 수도 있습니다. 



위의 링크를 참조하면 자신의 스마트폰에 위젯앱을 추가하여 데이터를 실시간으로 모니터링 할 수 있으며 입계값을 설정하여 경고가 울릴 수 있게 할 수도 있습니다. 예를 들어 온도가 30도가 넘으면 경고 알람을 울리게 설정할수도 있는 것이죠.


스마트폰에서 ThingSpeak 위젯앱 'IoT ThingSpeak Monitor Widget' 을 설치하고 설정한 모습 입니다.

반응형
Posted by 대네브 (deneb)

댓글을 달아 주세요

  1. 9577

    pin = 0
    r = 0
    writekey = "

    tmr.alarm(1,15000,1,function()readDHT(pin)prin(r)sendData(r)end)

    --read DHT11 temp, humi data function
    function readDHT(pin)
    r = adc.read(pin)
    adc = nil
    end

    function prin(r)
    print("VALUE"..r)
    end

    --send data to thingspeak
    function sendData(r)
    -- conection to thingspeak.com
    print("Sending data to thingspeak.com")
    conn=net.createConnection(net.TCP, 0)
    conn:on("receive", function(conn, payload) print(payload) end)

    -- api.thingspeak.com 184.106.153.149
    conn:connect(80,'184.106.153.149')
    conn:send("GET /update?key="..writekey.."&field1="..r.."&field2="..r.." HTTP/1.1\r\n")
    conn:send("Host: api.thingspeak.com\r\n")
    conn:send("Accept: */*\r\n")
    conn:send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n")
    conn:send("\r\n")
    conn:on("sent",function(conn)
    print("Closing connection")
    conn:close()
    end)
    conn:on("disconnection", function(conn)
    print("Got disconnection...")
    end)
    end

    이렇게 코딩했는데 값 전달이 잘 안되네요..ㅜㅜㅜ
    저는 아주대학교에 다니는 윤승식입니다. 저희가 하나의 프로젝트를 하고 있습니다. 자문을 구하고 싶은데 혹시 가능할까요..?

    2017.11.10 14:40 [ ADDR : EDIT/ DEL : REPLY ]
    • 죄송하지만 소스코드를 봐드리지는 않습니다.
      그리고 Write Key 를 이렇게 노출하시면...

      2017.11.11 20:58 신고 [ ADDR : EDIT/ DEL ]
    • 9577

      서버로 값 전달 시, 필드로 전달한다는 것이 어떤 것인가요..?

      conn:send("GET /update?key="..writekey.."&field1="..temp.."&field2="..humi.." HTTP/1.1\r\n")

      저는 구름 서버를 이용하는데 여러 값을 전달했을 때 구분을 어떻게 할 수 있을지 궁금합니다.

      2017.11.20 22:28 [ ADDR : EDIT/ DEL ]
    • get방식으로 url에 write값을 붙여서 여러가지 값을 저장 합니다.

      2017.11.21 17:08 신고 [ ADDR : EDIT/ DEL ]