用這個例子來練習Raspberry Pi在物聯網(IoT)的應用應該是簡單又恰當的。實做上可分成兩部
份分別完成後再做整合,分別是1. Raspberry Pi 取得溫溼度資料, 2. 將溫溼度資料上傳至氣象
網站。
整個練習用到的零件清單如下:
– Raspberry Pi 2 B
– USB電源
– WiFi dongle
– DHT12 溫溼度感測器
– 母對母杜邦線
– 作業系統: NOOBS version 1.9.3
– Linux 核心版本: 4.4.21-v7+
– Python 3.4.2
接線說明:
DHT12採用I2C介面
圖片來源:http://goods.ruten.com.tw/item/show?21615469486417
接線圖如下:
1. Raspberry Pi 取得溫溼度資料
1.1 作業系統設定並安裝I2C函式庫和工具
啟動Raspberry Pi並在LX Terminal完成以下項目(亦可使用Putty遠端登入
Raspberry Pi):
(1) 啟動I2C
鍵入 sudo raspi-config ,進入raspi-config
選擇 “ 9 Advanced Options ”
選擇 “ A7 I2C“ 啟動I2C
鍵入 sudo reboot重新開機
(2) 執行系統update 和upgrade
sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
(3) 安裝SMBus
sudo apt-get install python-smbus python3-smbus python-dev python3-dev
安裝時發現系統已經有SMBus, 不過還是繼續安裝
(4) 安裝i2c-tools
sudo apt-get install i2c-tools
(5) 查詢I2C裝置位址
sudo i2cdetect -y 1
=> 得到0x5c , 這是這顆DHT12當作I2C slave 時的address
(6) 檢查是否有資料進來
i2cdump -y 1 0x5c
1.2 讀取DHT12的資料
將DHT12當I2C slave,DHT12每次送出5個bytes至I2C,我們可以呼叫SMBus的函式
read_i2c_block_data()一次讀進來,這5個bytes存放的資料如下:
byte 0: 存放濕度值的整數部分
byte 1: 存放濕度值的小數部分
byte 2: 存放溫度值(攝氏)的整數部分
byte 3: 存放溫度值(攝氏)的小數部分
byte 4: 存放檢查碼(checksum),它的值等於前4個bytes所存放值的加總,在程式碼
中把前面4個bytes的值加總,如果等於這byte的內容,表示資料是可用的,
否則該次的資料是有問題的,應丟棄 不用
2. 將溫溼度資料上傳至氣象網站
WOW(Weather Observations Website, http://wow.metoffice.gov.uk/) 是英國國家氣象服務
Met Office的網站,可以在上面申請一個免費帳號,然後建立一個氣象觀測站,把我
們從DHT12 得到的溫度和濕度資料上傳至該網站。
至於如何上傳資料到該氣象網站,詳細請參考以下連結:
http://wow.metoffice.gov.uk/support/dataformats
以下謹說明這裡會用到的部分。
使用HTTP GET或POST將資料上傳至WOW,這部分其實可以先在瀏覽器送出類似以下的
字串來做實驗(全部在一行,不換行):
http://wow.metoffice.gov.uk/automaticreading?
siteid=xxx&siteAuthenticationKey=yyy&dateutc=2016-10-
01+04%3A16%3A55&humidity=68&tempf=84.2&softwaretype=Python3.x
以上字串是一個HTTP的GET request,問號 ( ? ) 後面是要傳送到網站上的資料,其中:
siteid:這是在所建的觀測站名子旁邊(或下面)顯示的一個識別碼
siteAuthenticationKey:這是建觀測站時所輸入的AuthenticationKey,可以使用網站
的'Edit Site'功能來更改
dateutc:UTC 的日期和時間 (台灣的時間是UTC+8小時), %3A 代表 ' : '
humidity:濕度值(0 - 100 %)
tempf:溫度值,使用華氏(Fahrenheit )溫度
softwaretype : 應該只是一個字串,我使用 'Python3.x'
程式碼
( 注意:若要使用這程式碼,需使用自己的siteid 和 siteAuthenticationKey )
# This application posts weather information from DHT12 to Met Office website
# Weather information: humidity, temperature
# Met Office website: http://wow.metoffice.gov.uk/
# Format: http://wow.metoffice.gov.uk/automaticreading?siteid=ZZZZZZ&siteAuthenticationKey=XXXXXXXXX&dateutc=2016-10-
#01+04%3A16%3A55&humidity=68&tempf=84.2&softwaretype=Python3.x
# Python 3.4.2
# Author: Viiresh Yang
import smbus
import time
import http.client
from datetime import datetime
gotData = 0
I2C = smbus.SMBus(1)
address = 0x5c
register = 0x00
length = 5
data = I2C.read_i2c_block_data(address, register, length)
print(data[0],data[1],data[2],data[3],data[4])
if data[0]+data[1]+data[2]+data[3] == data[4]:
humidity = data[0] + data[1]/10.0
tempC = data[2] + data[3]/10.0
print('Humidity: ' + str(humidity) + ' % '+ 'Temperature: '+ str(tempC) + ' Centigrade')
gotData = 1
else:
print('No data')
gotData = 0
if gotData == 1:
tempF = tempC*(9.0/5.0) + 32.0
#make a HTTP connection to the website that you want to post weather information to
conn = http.client.HTTPSConnection("wow.metoffice.gov.uk")
#Use your own siteAuthenticationKey
siteStr = "/automaticreading?siteid=ZZZZZZ&siteAuthenticationKey=XXXXXXXX"
utcdatetime = datetime.utcnow()
today = utcdatetime.date()
current = utcdatetime.time()
datetimeStr = "dateutc=" + str(today) + "+" + str(current)
humidityStr = "humidity=" + str(humidity)
temperatureStr = "tempf=" + str(tempF)
softwaretypeStr = "softwaretype=Python3.x"
# make a request string according to requirement from Met Office
requestString = siteStr + "&" + datetimeStr + "&" + humidityStr + "&" + temperatureStr + "&" + softwaretypeStr
# show requestString on screen for checking
#print(requestString)
# make a HTTP GET requst
conn.request("GET", requestString)
# get HTTP response from the website
response = conn.getresponse()
#print HTTP response on screen
print(response.status, response.reason)
#close HTTP connection
conn.close()
資料上傳至WOW後,可用瀏覽器連至該網站看上傳結果