本篇文章要來介紹的是使用 Raspberry Pico W 和 RS485 溫溼度感測器的淹水偵測裝置,為了因應最近強降雨的情形,怕地下室淹水所製作的,現在這套設備正在 CAVEDU 地下室服役中。
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 settings(需自行輸入IFTTT相關資訊)
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 settings(需自行輸入WIFI帳號和密碼)
wifi_ssid = "enter_your_wifi_ssid"
wifi_password = "enter_your_wifi_password"
# Initialize UART(初始化UART)
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)
# LCD initialization (LCD 初始化)
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)
# Initialize RTC (RTC 初始化)
rtc = RTC()
# Connect to the WiFi (WIFI連線)
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
# Update the time from NTP server (更新時間)
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))
# Get current time(取得目前時間)
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
# Send data to IFTTT (傳資料到IFTTT)
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()
# Sensor Access Function (RS485感測器回傳資料)
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
# Print on LCD (顯示數值在LCD)
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() # update the time from NTP server at the start
lcd.putstr("WIFI is connected!")
# setting the initial time to a value that triggers the first send
last_sent_hour = -1
last_sent_minute = -1
line_flag = False
while True:
current_time, current_hour, current_minute = get_time()
# read sensor every 15 minutes (每15分鐘上傳數值到Google Sheets)
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
# send to LINE sheet once every day at 7:00pm (每晚七點上傳數值到LINE)
if current_hour == 19 and current_minute == 0 and line_flag == False:
soil_temp, soil_vwc = Sensor_Access()
#send_to_ifttt(IFTTT_URL_GOOGLE_SHEET, soil_temp, soil_vwc, state)
send_to_ifttt(IFTTT_URL_LINE, soil_temp, soil_vwc, state)
line_flag = True
# reset line_flag after 7:00pm (重置line_flag)
if current_hour == 19 and current_minute > 0:
line_flag = False
# send to LINE when soil_vwc is between 0 and 10 (當淹水時會發緊報)
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 "
# print on LCD every second (LCD每秒更新一次顯示畫面)
lcd_print(current_time, soil_vwc)
print(current_time, soil_vwc)
utime.sleep(1) # sleep for 1 second
# Run the main function (執行主程式)
main()
筆者將裝置設置在地下室容易淹水的地方,由於感測器很靈敏,所以使用海綿來吸水,到一定程度後感測器就會發出通報 (下圖左)。裝置運作時,可由外接 LCD 看到當下的時間和濕度。