반응형

ESP32 에는 기본적으로 온도센서를 내장하고 있다. 이를 사용하는 방법을 알아보려고 한다. 



위 ESP32 블록 다이어그램을 보면 온도센서가 있음을 알 수 있다. 소스는 구글링을 통해서 가지고 왔다. 


■ 스케치

소스출처 : https://gist.github.com/xxlukas42/7e7e18604f61529b8398f7fcc5785251


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifdef __cplusplus
extern "C" {
#endif
uint8_t temprature_sens_read();
#ifdef __cplusplus
}
#endif
uint8_t temprature_sens_read();
 
void setup() {
  Serial.begin(115200);
}
 
void loop() {
  Serial.print("Temperature: ");
  
  // Convert raw temperature in F to Celsius degrees
  Serial.print((temprature_sens_read() - 32/ 1.8);
  Serial.println(" C");
  delay(5000);
}
cs



그런데 위와 같이 작성하고 실행을 해 보니 이상하다.


위와 같이 시리얼 모니터에 똑같은 온도만 계속 표시가 된다. 그리고 너무 높다. 방 안의 온도가 현재 20도 정도인데 53도 라니...


왜 그런지 모르겠다. 칩 자체의 온도가 높은건가? 소숫점 2째자리 까지 표시가 되는데 하나도 변화가 없는 것이 제대로 측정되지 않는 것 같다. 


혹시 왜 그런지 아는 분들의 댓글 바란다.

반응형
반응형

NodeMCU Lua 사용해보기 지난 10편에서는 ThingSpeak 에 ESP8266 보드를 이용해서 DHT11 의 데이터를 업로드 해 보았다.  이번에는 비슷한 서비스인 dweet.io 라는 IoT 클라우드 서비스를 이용해 보려고 한다. ThingSpeak 는 회원가입이 필요 했는데 dweet 은 회원가입이 필요 없고 Things 의 이름을 Key 로 사용한다. 고유한 이름으로 Thing 의 이름을 지정해주고 자신의 IoT 데이터를 업로드 하면 되는 것이다.


dweet.io 사이트에서 어떠한 오퍼레이션 없이 유니크한 Thing Name 을 가지고 dweet 으로 데이터를 보내면 dweet.io 에서 데이터를 받아서 저장하기 때문에 바로 데이터 업로드를 위한 하드웨어 및 소스를 준비하면 된다.  ESP8266 보드인 Amica 에 DHT11 온습도 센서를 아래와 같이 연결을 하였다.


 ESP8266 (Amica Board)

 DHT11

 D5

 Signal

 3.3V

 VCC (+)

 GND

 GND


■ 소스


credentials.lua

1
2
3
4
-- WiFi Connect information
SSID = "Your WiFi SSID"
PASSWORD = "Your 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
-- 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("dht11_dweet.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


dht11_dweet.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
DHT_PIN = 5 -- defined by DHT shield (D5)
HOST    = "dweet.io"
THING_NAME   = "Your Thing Name"
 
function read_DHT()
  status,temp,humi,temp_decimial,humi_decimial = dht.read(DHT_PIN)
  if( status == dht.OK ) then
    print("DHT Temperature = "..temp.." grdC  ".."Humidity = "..humi.." %")
  elseif( status == dht.ERROR_CHECKSUM ) then
    print"DHT Checksum error." );
  elseif( status == dht.ERROR_TIMEOUT ) then
    print"DHT Time out." );
  end
end
 
function dweet()
  read_DHT()
  conn=net.createConnection(net.TCP,0
  conn:on("receive", function(conn, pl) print("response: ",pl) end)
  conn:on("connection", function(conn, payload) 
          print("connected"
          conn:send("POST /dweet/for/"..THING_NAME.."?"
          .. "temp=" .. temp 
          .. "&humi=" .. humi 
          .. " HTTP/1.1\r\n"
          .. "Host: " .. HOST .. "\r\n"
          .. "Connection: close\r\n"
          .. "Accept: */*\r\n\r\n"end)
  conn:on("disconnection", function(conn, payload)
          print("disconnected"end)
  conn:connect(80, HOST)
end
 
dweet()
 
-- dweets every 60 sec.
tmr.alarm(010 * 10001, function() dweet() end )
 
print("Dweets every 60 sec DHT11 data to dweet.io")
print("Stop this by tmr.stop(0)")
cs


credentials.lua 와 init.lua 에서 ESP8266 보드를 와이파이에 연결시키고 dht11_dweet.lua 에서 dweet.io 로 DHT11의 온습도 데이터를 업로드 한다. 위의 3가지 lua 파일을 ESP8266 보드에 업로드 하고 실행하면 되는 것이다. dweet.io 사이트에서는 아무것도 설정해 주지 않아도 된다. 다만 위의 소스에서 THING_NAME 의 값은 유니트한 값이어야 한다.


ESPlorer 에서 위와 같이 데이터를 업로드하고 실행하면 dweet.io 에서 데이터가 잘 전송되었다는 리턴값을 보내 준다.


소스를 수정 후 업데이트 할 경우에는 위에 사용된 타이머 0번을 Stop 시키고 업로드 해야 한다. tmr.stop(0) 명령어를 이용해서 타이머를 멈추고 업로드 하면 된다.



이제 dweet.io 사이트에 들어가 본다.


■ dweet.io

https://dweet.io/ 

 

dweet.io 사이트에서 상단의 Play 를 클릭하면 아래와 같이 API 설정 목록이 뜬다.


Play 메뉴에서 여러가지 API 에 대한 설명을 볼 수 있고 자신의 Thing 에 대한 설정을 할 수 있다. 둘러보면 모두 이해할 수 있는 내용이다. 이 API 들을 이용해서 데이터를 끌어와 관련 웹이나 스마트폰 앱 또는 또 다른 Thing 을 만들 수 있을 것이다.


위의 소스를 이용해서 데이터를 업로드한 dweet 의 THING NAME 은 'deneb_nodemcu_dht11_01' 이다. http://dweet.io/follow/deneb_nodemcu_dht11_01 (이 URL 은 언제든지 내가 ESP8266의 전원을 끊으면 동작하지 않을 수 있음) 를 클릭해서 들어가보면 데이터가 잘 업로드 되고 있는 것을 알 수 있다.



위의 화면에서 'Create a Custom Dashboard' 를 클릭하면 freeboard.io 사이트로 이동을 하는데 Things의 데이터를 비주얼하게 표현해 주는 사이트이다. 


사이트에 가입하면 위와 같이 게이지 같은 위젯도 추가가 가능하다. 


dweet.io 를 사용해본 소감은 ThingSpeak 보다 간단해서인지 왠지 적응이 잘 안된다. 너무 오픈되어 있어서 그런가? 좀 혼란스럽다. 아직까지는 ThingSpeak 가 더 마음에 든다. 앞으로 dweet 에 대해 새로운 사항을 알게되면 이 포스팅에 내용을 추가할 생각이다.

반응형
반응형

예전에 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' 을 설치하고 설정한 모습 입니다.

반응형
반응형

지난 글들에서 NodeMCU Lua 를 이용해서 간단한 웹서버를 만들어 보았고 공유기 설정을 통하여 NodeMCU ESP8266 웹서버를 외부에서도 접속이 가능하도록 만들어 보았습니다. 하지만 브라우저로 웹서버에 접속해도 Hello NodeMCU 라는 글자만 출력되었었죠. 아무런 정보도 표시되지 않는다면 IoT 로서의 의미가 없습니다. 이번에는 온습도 센서인 DHT11 을 ESP8266 개발보드인 Amica 에 연결해서 웹서버에 접속하면 온도와 습도가 표시되도록 해 보겠습니다. 어디든 인터넷만 연결이 되면 스마트폰, PC 등에서 현재 집의 온도와 습도를 알 수 있는 것이죠.


제가 가지고 있는 DHT11 센서 입니다. 저항이 달려 있는 모듈형태로 되어 있어서 보드와 연결 시 따로 저항을 연결하지 않아도 됩니다. 모듈형태가 아니라 위의 파란부분의 핀 4개짜리 센서만 가지고 있다면 5K 정도의 저항을 Signal 과 VCC 사이에 달아 주어야 합니다. DHT11 에 대한 자세한 사용법은 [여기] 를 참고 하시면 됩니다.


그리고 Amica  ESP8266 개발 보드 입니다. DHT11 이 3V~5.5V를 지원하므로 전원은 3.3V 핀을 이용하면 됩니다. 연결은 아래의 표를 참조해서 연결하면 됩니다.


 DHT 11

 ESP8266 (Amica)

 Signal

 D5

 VCC

 3.3V

 GND

 GND


연결이 되었으면 이제 소스를 코딩하면 됩니다. 소스는 이전 글에서 해 보았던 웹서버 만들기의 credentials.lua, init.lua, webserver.lua 를 변형해서 사용할 것 입니다.


■ credentials.lua

와이파이 연결정보를 가지고 있는 파일 입니다.


1
2
3
4
-- 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
-- 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")
    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




■ webserver.lua

웹서버를 실행하고 DHT11 센서의 값을 읽어서 웹에서 요청이 들어오면 준비된 HTML (온도 및 습도값 포함) 을 전송하는 기능을 합니다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
pin = 5 -- dht11 signal pin
srv = net.createServer(net.TCP)
srv:listen(8080, function(conn)
 
    status, temp, humi, temp_dec, humi_dec = dht.read(pin)
    if status == dht.OK then
        temp_1 = math.floor(temp)
        humi_1 = math.floor(humi)
    elseif status == dht.ERROR_CHECKSUM then
        print"DHT Checksum error." )
    elseif status == dht.ERROR_TIMEOUT then
        print"DHT timed out." )
    end
    tmr.delay(1000000)
    conn:on("receive", function(sck, payload)
        print(payload)
        sck:send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>My House Temperature & Humidity<br/></h1>" .. "<br/><h1>Temperature = " .. temp .. "C</hr>" .. "<br/><h1>Humidity = " .. humi .. "%</hr>")
    end)
    conn:on("sent", function(sck) sck:close() end)
end)
print("webserver ready...")
cs


위의 소스를 보면 이전 글에서 작성 했던 웹서버 코드를 기반으로 DHT11 값을 추가해서 HTML 을 리턴 할 수 있도록 수정해 주었습니다.


DHT11 의 경우 초기의 NodeMCU 같은 경우는 별도의 라이브러리를 사용해야 코드가 단순화 되었었는데 지금은 위와 같이 간단하게 읽어오는 것이 가능 합니다. 아마도 펌웨어 자체에 라이브러리가 포함이 된 듯 합니다.



위의 3개의 소스를 ESPlorer 를 통해서 ESP8266 개발보드에 'Save to ESP' 해서 업로드 해 줍니다. init.lua 는 맨 마지막에 업로드 해 주는 것이 좋습니다.


소스를 모두 업로드 하고 Reset 을 눌러서 Soft Reset 을 한 번 해 줍니다. 시리얼 창에 'webserver ready...' 라는 메시지가 나오면 준비가 완료된 것 입니다.


이제 브라우저를 열고 저의 공유기에서 ESP8266 웹서버에 할당된 IP 인 192.168.0.18 로 접속해서 온도와 습도가 잘 나오는지 확인해 봅니다. 포트는 8080 을 이용했으므로 다음과 같이 브라우저의 주소창에 입력하면 됩니다. http://192.168.0.18:8080/



이번에는 외부에서 스마트폰 LTE 연결로 확인을 해 보겠습니다. 물론 이것을 가능하게 하려면 [여기] 를 참고 하셔서 공유기의 DDNS, 포트 포워드 를 설정해서 외부에서도 ESP8266 웹서버에 접속 가능하도록 만들어 주어야 합니다.


위와 같이 스마트폰으로 외부에서도 DDNS에서 만들어준 URL을 입력하면 DHT11 센서가 측정한 값을 실시간으로 볼 수 있습니다. 이를 응용하면 가스누출, 조명 밝기, 침입자 탐지 등도 원격지에서 모니터링 할 수도 있을 것 같습니다.



▶ 추가사항 (2016.07.08) : 위의 webserver.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
pin = 5 -- dht11 signal pin
temp = 0 -- initialize temperature
humi = 0 -- initialize humidity
port = 8080 -- web port
 
srv = net.createServer(net.TCP)
srv:listen(port, function(conn)
    ReadDHT()   -- dht read function call
    tmr.delay(1000000)
    conn:on("receive", function(sck, payload)
        print(payload)
        --// response html
        sck:send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>My House Temperature & Humidity<br/></h1>" .. "<br/><h1>Temperature = " .. temp .. "C</hr>" .. "<br/><h1>Humidity = " .. humi .. "%</hr>")
    end)
    -- response
    conn:on("sent", function(sck) sck:close() end)
end)
print("webserver listening..."
 
 
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   --release dht module
end
 
cs


반응형

+ Recent posts