前言
本篇文章要來介紹的是使用 Raspberry Pico W 和 RS485 溫溼度感測器的淹水偵測裝置,為了因應最近強降雨的情形,怕地下室淹水所製作的,現在這套設備正在 CAVEDU 地下室服役中。
Pico W淹水偵測裝置功能如下:
每15分鐘會上傳資料點至Google Sheet雲端,以確保裝置運作中
可定時(如:每日7:00PM把目前偵測到的溫溼度發送到 LINE 通訊軟體
若濕度過高,則會立即通報LINE中。由於LINE可以把相關人員加入群組中,所以只要有人接到通報,就可以第一時間做處置。
撰寫/攝影 |
許鈺莨 (ChatGPT協作編輯) |
時間 |
2 小時 |
材料表 |
|
難度 |
2(滿分5) |
本文
智慧偵測淹水裝置接線圖
智慧偵測淹水裝置主要由下列元件所組成:
- Raspberry Pi Pico W: 接收RS485感測器訊號,並上傳至雲端及LINE 訊息。
- Raspberry Pi Pico W擴充板 : 擴充Raspberry Pi Pico W腳位,以方便將感測器腳位。
- TTL轉RS485模組 : 可將RS485感測器訊號轉成TTL訊號,再讓Raspberry Pi Pico W接收
- RS485溫溼度感測器:可以偵測室內的溫度及濕度。
- LCD液晶螢幕: 主要顯示目前的溼度狀況與時間。
- Raspberry Pi Pico W擴充板與LCD 接線

- Raspberry Pi Pico W擴充板與TTL轉RS485模組接線

- TTL轉RS485模組接線與RS485溫濕度感測器接線

智慧偵測淹水裝置流程圖
系統流程圖如下 (點選看大圖)

智慧偵測淹水裝置匯入LCD函式庫
- 匯入 Raspberry Pi pico 函式庫的做法,請參考「使用 Raspberry Pi Pico W 和 MicroPython 開發物聯網應用」
- 函式庫下載:https://reurl.cc/Dov54e
- 匯入檔案指令,匯入以上連結下載的 lcd_api.py 和 i2c_lcd.py
cd LCD_library
ampy --port COMX put lcd_api.py
ampy --port COMX put i2c_lcd.py
- 智慧偵測淹水裝置程式全貌
下列程式中需要 IFTTT 作為中介軟體來串接 pico W 與 LINE,相關IFTTT申請步驟,請參考 「LinkIt™ 7697空氣品質偵測並上傳Google表單(空氣盒子2.0)」。,並將申請到的 IFTTT 相關資訊填入以下 .py 檔之後上傳到 pi pico 開發板即可。
Alert_IFTTT_LINE_GOOGLE_settime_blog.py
import utime
import machine
import urequests
import ntptime
import network
from machine import I2C, Pin, RTC
from lcd_api import LcdApi
from i2c_lcd import I2cLcd
IFTTT_GOOGLE_EVENT = "enter_your_google_event"
IFTTT_LINE_EVENT = "enter_your_line_event"
IFTTT_KEY= "enter_your_webhook_key"
IFTTT_URL_GOOGLE_SHEET ='https://maker.ifttt.com/trigger/'+IFTTT_GOOGLE_EVENT+'/with/key/'+IFTTT_KEY
IFTTT_URL_LINE ='https://maker.ifttt.com/trigger/'+IFTTT_LINE_EVENT+'/with/key/'+IFTTT_KEY
wifi_ssid = "enter_your_wifi_ssid"
wifi_password = "enter_your_wifi_password"
uart = machine.UART(1, baudrate=9600, tx=machine.Pin(8), rx=machine.Pin(9), timeout=1000)
uart.init(9600, bits=8, parity=None, stop=1)
I2C_ADDR = 0x3f
I2C_NUM_ROWS = 2
I2C_NUM_COLS = 16
i2c = I2C(0, sda=machine.Pin(0), scl=machine.Pin(1), freq=400000)
lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS)
rtc = RTC()
def connect_wifi(ssid, password):
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
wlan.connect(ssid, password)
while not wlan.isconnected():
pass
def update_time():
ntptime.host = 'pool.ntp.org'
ntptime.settime()
tm = utime.localtime(utime.mktime(utime.localtime()) + 28800)
rtc.datetime((tm[0], tm[1], tm[2], tm[6] + 1, tm[3], tm[4], tm[5], 0))
def get_time():
time = rtc.datetime()
current_hour = time[4]
current_minute = time[5]
current_second = time[6]
current_time = "{:02d}:{:02d}:{:02d}".format(current_hour, current_minute, current_second)
return current_time, current_hour, current_minute
def send_to_ifttt(url, soil_temp, soil_vwc, state):
data = {'value1': str(soil_temp), 'value2': str(soil_vwc), 'value3': state}
request_headers = {'Content-Type': 'application/json'}
request = urequests.post(url, json=data, headers=request_headers)
request.close()
def Sensor_Access():
Read_SOIL_TEMP_HUMI_Command = bytes([0x01, 0x03, 0x00, 0x06, 0x00, 0x02, 0x24, 0x0A])
SOIL_buf = bytearray(11)
Sensor_Delay_mS = 50
uart.write(Read_SOIL_TEMP_HUMI_Command)
uart.readinto(SOIL_buf)
utime.sleep_ms(Sensor_Delay_mS)
SOIL_VWC_Data = (SOIL_buf[5] << 8) + SOIL_buf[6]
SOIL_VWC_Value = int(SOIL_VWC_Data) / 1000
SOIL_TEMP_Data = (SOIL_buf[3] << 8) + SOIL_buf[4]
SOIL_TEMP_Value = int(SOIL_TEMP_Data) / 100
return SOIL_TEMP_Value, SOIL_VWC_Value
def lcd_print(current_time, soil_vwc):
lcd.clear()
lcd.putstr("TIME: {time} VWC: {vwc:.1f}".format(time=current_time, vwc=soil_vwc))
def main():
state = " Normal "
connect_wifi(wifi_ssid, wifi_password)
update_time()
lcd.putstr("WIFI is connected!")
last_sent_hour = -1
last_sent_minute = -1
line_flag = False
while True:
current_time, current_hour, current_minute = get_time()
if current_minute % 15 == 0 and current_minute != last_sent_minute:
soil_temp, soil_vwc = Sensor_Access()
send_to_ifttt(IFTTT_URL_GOOGLE_SHEET, soil_temp, soil_vwc, state)
last_sent_minute = current_minute
if current_hour == 19 and current_minute == 0 and line_flag == False:
soil_temp, soil_vwc = Sensor_Access()
send_to_ifttt(IFTTT_URL_LINE, soil_temp, soil_vwc, state)
line_flag = True
if current_hour == 19 and current_minute > 0:
line_flag = False
soil_temp, soil_vwc = Sensor_Access()
if 0 < soil_vwc <= 10:
state = " ALERT!! "
send_to_ifttt(IFTTT_URL_LINE, soil_temp, soil_vwc, state)
send_to_ifttt(IFTTT_URL_GOOGLE_SHEET, soil_temp, soil_vwc, state)
else:
state = " Normal "
lcd_print(current_time, soil_vwc)
print(current_time, soil_vwc)
utime.sleep(1)
main()
- 安裝位置
筆者將裝置設置在地下室容易淹水的地方,由於感測器很靈敏,所以使用海綿來吸水,到一定程度後感測器就會發出通報 (下圖左)。裝置運作時,可由外接 LCD 看到當下的時間和濕度。
6. 實際執行
執行影片如本文開頭,為了較快看到效果,筆者設計是每秒上傳一次資料到雲端,請根據實際狀況來修改這個更新頻率。
Post Views: 443