静電容量式のレインセンサを使ってみた

静電容量式のレインセンサを使ってみました。センサは静電容量式で、雨が落ちると端子間の静電容量値が変化し、それを検出するようになっています。抵抗式タイプのものを以前使っていて、電極が腐食して検出できなくなったことがありますが、このセンサであれば腐食しないので長時間使えそうです。

M5StackやESP32、Raspberry Pi Pico W などを使用すれば、LINEに通知出来たり、降雨状態をロギングしたりできます。

降雨状態をモニタリングする

M5Stackを接続して、アナログ値とデジタル値をモニタリングしてみました。

デモ

使用した部品

静電容量式レインセンサ基板www.switch-science.com

静電容量式レインセンサ検出基板www.switch-science.com

LINEに通知が来るようにしてみる

LINE Notify を使用して、LINEに通知するようにしてみました。 アナログ値やデジタル値をAmbientでモニタリングできるようにしています。 Raspberry Pi Pico Wを使いました。言語はMicroPythonで書きました。

コード

main.py

from machine import ADC, Pin, RTC, WDT
import machine
import time
import wifi_connect
import ntptime
import ambient
import line

LAST_RAIN_TIME_FILE_NAME = "LAST_RAIN_TIME.txt"
RAIN_FLAG_FILE_NAME = "RAIN_FLAG.txt"

# WDTを8秒に設定
wdt = WDT(timeout=8000)

# 入力を初期化
rain_digital = Pin(22, Pin.IN)
rain_analog = ADC(Pin(26))
led = Pin("LED", Pin.OUT)

# LEDを点灯
led.on()

# WiFiに接続
wifi_connect.connect()

# LINEのアクセストークン
TOKEN = "LINE Notifyのアクセストークン"

# Ambientのインスタンス生成
am = ambient.Ambient("AmbientのチャンネルID", "Ambientのライトキー", ssl=True, userKey="Ambientのユーザーキー")

# NTPで時刻合わせを行う
rtc = RTC()
ntptime.settime()

# 最後に雨が降ってから止むまでしきい値(秒)
min_notify_time = 30 * 60  # 30分

# 現在のエポック秒
now_time = 0

# 最後に雨が降った時間
try:
    with open(LAST_RAIN_TIME_FILE_NAME, mode="r") as f:
        last_rain_time = int(f.read().strip())
        f.close()
except:
    # ファイルが存在しなかった場合、またはエラーの場合
    last_rain_time = - min_notify_time
    print("error")
    
# 雨が降っているかどうかのフラグ
try:
    with open(RAIN_FLAG_FILE_NAME, mode="r") as f:
        if f.read().strip() == "True":
            rain_flag = True
        else:
            rain_flag = False
            print(f.read().strip())
        f.close()
except:
    # ファイルが存在しなかった場合、またはエラーの場合
    rain_flag = False
    print("error")

# WDTをクリア
wdt.feed()

# LEDを消灯
led.off()
# メインループ
while True:
    # アナログ値を取得(16ビットから5ビットに変換して代入 1以上で降雨あり 1未満で降雨なし)
    analog_value = 16 - (rain_analog.read_u16() >> 11)
    # デジタル値を取得(0のとき降雨なし 1のとき降雨あり)
    digital_value = rain_digital.value()
    # 現在の経過秒数
    now_time = time.time()
    # 現在時刻
    now_datetime = time.gmtime()
    # 現在の時間
    now_hour = (now_datetime[3] + 9) % 24
    print(now_hour)
    if digital_value == 1:
        # 雨が降っているときの処理
        if rain_flag == False:
            # 雨が振り始めたときの処理
            rain_flag = True
            with open(RAIN_FLAG_FILE_NAME, mode="w") as f:
                f.write("True")
            # 7時から19時の間であればLINEで通知する
            if now_hour >= 7 and now_hour < 19:
                # 雨が振り始めました。
                line.send_message("%E9%9B%A8%E3%81%8C%E6%8C%AF%E3%82%8A%E5%A7%8B%E3%82%81%E3%81%BE%E3%81%97%E3%81%9F%E3%80%82", TOKEN)
        # 最後に雨が降った時間を設定
        last_rain_time = now_time
        with open(LAST_RAIN_TIME_FILE_NAME, mode="w") as f:
            f.write(str(now_time))
            f.close()
    else:
        # 雨が降っていないときの処理
        if now_time - last_rain_time >= min_notify_time and rain_flag == True:
            # 雨が上がったときの処理
            rain_flag = False
            with open(RAIN_FLAG_FILE_NAME, mode="w") as f:
                f.write("False")
                f.close()
            # 7時から19時の間であればLINEで通知する
            if now_hour >= 7 and now_hour < 19:
                # 雨が上がりました。
                line.send_message("%E9%9B%A8%E3%81%8C%E4%B8%8A%E3%81%8C%E3%82%8A%E3%81%BE%E3%81%97%E3%81%9F%E3%80%82", TOKEN)
    
    rain_value = max(analog_value, 0)
    print(str(analog_value) + "," + str(digital_value))
    try:
        am.send({"d1": rain_value, "d2": int(rain_flag), "d3": analog_value, "d4": digital_value})
    except:
        machine.reset()
    
    # LEDを点灯
    led.on()
    
    # 5秒待機
    for i in range(5):
        time.sleep(1)
        # WDTをクリア
        wdt.feed()
        
    # LEDを消灯
    led.off()

wifi_connect.py

def connect():
    import network
    import time
    import machine
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    if not wlan.isconnected():
        print("connecting to network...")
        wlan.connect("WiFiのSSID", "WiFiのパスワード")
        tri_time = 0
        while not wlan.isconnected():
            time.sleep(1)
            tri_time += 1
            if tri_time >= 60:
                print("WiFi RESET")
                time.sleep(1)
                machine.reset()
    print('network config:', wlan.ifconfig())

line.py

import urequests as requests
import ujson as json

def send_message(message, token):
    url ="https://notify-api.line.me/api/notify"
    headers = {
        "Content-Type" : "application/x-www-form-urlencoded",
        "Authorization": "Bearer " + token
    }
    data = 'message=' + message #quote処理が必要
    response = None
    try:
        response = requests.post(url, headers=headers, data=data).json()
    except:
        pass
    return response

使用した部品