概要
田 ん ぼ の 水 路 の 水 位 を リ ア ル タ イ ム で 監 視 し 、 大 雨 や 異 常 な 水 位 変 動が 発 生 し た 場 合 に 、農 家 や 管 理 者 に 通 知 を 送 信 す る こ と で 、適 切 な 対 策を 促 す こ と が で き る 。こ れ に よ っ て 、洪 水 の リ ス ク を 軽 減 し 、農 作 物 の保 護 と 水 管 理 の 効 率 化 を 実 現 し ま す 。
システム・設置イメージ図
システムイメージ図↓
追記
現段階で超音波センサで測定した値によって通知を送信することができている。今後、ラズパイを追加してLoRa通信できるように開発していく予定
アイデア詳細
今回製作したシステムの基本機能を紹介する。
- リアルタイム水位監視:超音波センサで水面までの距離を定期的に測定し、データをラズパイに送信する。
- 自動警告通知システム:測定した距離から異常な水位上昇を検知するとLineNotifyを通じて警告を通知する。
- 履 歴 デ ー タ の 記 録 : 測 定 デ ー タ を 保 存 し 、長 期 的 な 水 位 の 変 動 を可 視 化する。
全 体 の 処 理 の 流 れ と し て は 、常 時 ラ ズ パ イ と 接 続 し て い る 超 音 波 距離セン サ ー モ ジ ュ ー ル で 水 路 の 水 位 を 測 定 し 、 CSV フ ァ イ ル に 保 存 し 、5回測定するごとにLineに送信されます。
ま た 、 測 定 し た 値 が 基 準 値 を 超 え る と 水 位 が 危 険 な 状 態 と 判 断 し て 、LoRa で ラ ズ パ イ 間 を 通 信 し 、 ラ ズ パ イ か ら ス マ ホ へ と LineNotify を通 じ て 通 知 を 送 信 し ま す 。
使用した部品
今回の製作で使用した部品を紹介する
- Raspberry pi 4 × 2
- 超音波センサ(AJ-SR04M)
- ブレッドボード
- LoRaモジュール
- 配線(ジャンパー線など)
実際の配置イメージ
溝に沿うようにセンサの先を固定できるような外装にする予定。センサは、防水使用のものなので実際の設置場所でも正常に動作すると思われる。
ハードについて
現時点では、ラズパイ1つのみ使用して動作させているが遠距離でデータを受信できるようにもう1つラズパイを追加し通信させることを考えている。また、電源をバッテリーにし、屋外での使用も考えている
LineNotifyの動作画面
センサで測定した水位が危険値の時(今回のプログラムでは、30cmを超えるとき)、警告文と具体的な距離が通知される。また、5回測定ごとにセンサの測定値を送るように動作している。
接続
接続方法は以下の通りになっていて、ジャンパー線でブレッドボードを介して直接接続している。
センサ側 | ラズパイ側 |
---|---|
AJ-SR04M | Raspberry Pi 4 |
5V | 5V |
Trig | Pin 15 |
Echo | Pin 14 |
GND | GND |
ソースコード
以下、ラズパイのプログラムになります。
センサ側動作プログラムの概要は、距離センサで測定した値が30cmを超えると、測定値とともに危険文が通知されます。さらに、5回測定する毎にCSVファイルに保存した値をまとめて通知してみることができるようになっています。
センサ側動作プログラム
import RPi.GPIO as GPIO
import time
import requests
import csv
import os
# GPIOの設定
GPIO.setmode(GPIO.BCM)
TRIG = 15
ECHO = 14
GPIO.setup(TRIG, GPIO.OUT)
GPIO.setup(ECHO, GPIO.IN)
# Line Notifyのアクセストークン
LINE_NOTIFY_TOKEN = 'トークン'
LINE_NOTIFY_URL = 'https://notify-api.line.me/api/notify'
# CSVファイルの設定
csv_file = 'sensor_data.csv'
# CSVファイルの初期化
with open(csv_file, mode='w', newline='') as file:
writer = csv.writer(file)
writer.writerow(['Time', 'Distance (cm)']) # ヘッダー
def send_line_notify(message, token):
headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/x-www-form-urlencoded'
}
payload = {'message': message}
response = requests.post(LINE_NOTIFY_URL, headers=headers, data=payload)
return response
def get_distance():
GPIO.output(TRIG, False)
time.sleep(2)
GPIO.output(TRIG, True)
time.sleep(0.00001)
GPIO.output(TRIG, False)
start_time = time.time()
stop_time = time.time()
while GPIO.input(ECHO) == 0:
start_time = time.time()
while GPIO.input(ECHO) == 1:
stop_time = time.time()
time_elapsed = stop_time - start_time
distance = (time_elapsed * 34300) / 2
return distance
def read_csv():
with open(csv_file, mode='r') as file:
reader = csv.reader(file)
next(reader) # ヘッダーをスキップ
data = [row for row in reader]
return data
try:
while True:
distance = get_distance()
current_time = time.strftime('%Y-%m-%d %H:%M:%S')
with open(csv_file, mode='a', newline='') as file:
writer = csv.writer(file)
writer.writerow([current_time, f"{distance:.2f}"]) # データ行の追加
print(f"距離: {distance:.2f} cm")
if distance > 30:
message = f"\n⚠️警告: 距離が {distance:.2f} cm を超えました!"
response = send_line_notify(message, LINE_NOTIFY_TOKEN)
if response.status_code == 200:
print("通知が送信されました")
else:
print("通知の送信に失敗しました")
# CSVの内容をLINEに送信
if time.time() % 60 < 1: # 1分ごとに送信
csv_data = read_csv()
message = "\n📊 センサーデータ:\n" + "\n".join([f"{row[0]}: {row[1]} cm" for row in csv_data])
response = send_line_notify(message, LINE_NOTIFY_TOKEN)
if response.status_code == 200:
print("データが送信されました")
else:
print("データ送信に失敗しました")
time.sleep(1)
except KeyboardInterrupt:
print("プログラムが中断されました")
finally:
GPIO.cleanup()
以下のプログラムは、超音波距離センサの動作確認プログラムになります。
ピンをマイコンと接続することで動作確認が可能になります。接続図を参考にしてみてください。
超音波センサ動作確認プログラム
import RPi.GPIO as GPIO
import time
# GPIOの設定
GPIO.setmode(GPIO.BCM)
TRIG = 15
ECHO = 14
GPIO.setup(TRIG, GPIO.OUT)
GPIO.setup(ECHO, GPIO.IN)
def get_distance():
# センサーの初期化
GPIO.output(TRIG, False)
time.sleep(2)
# トリガー信号を発信
GPIO.output(TRIG, True)
time.sleep(0.00001)
GPIO.output(TRIG, False)
start_time = time.time()
stop_time = time.time()
# エコー信号の開始と終了を計測
while GPIO.input(ECHO) == 0:
start_time = time.time()
while GPIO.input(ECHO) == 1:
stop_time = time.time()
# 時間差を計算し、距離を算出
time_elapsed = stop_time - start_time
distance = (time_elapsed * 34300) / 2
return distance
try:
while True:
distance = get_distance()
print(f"距離: {distance:.2f} cm")
time.sleep(1)
except KeyboardInterrupt:
print("プログラムが中断されました")
finally:
GPIO.cleanup()
これから
LoRaを用いた遠距離通信に挑戦していく予定
参考文献
- ラズパイ搭載 長距離無線通信ドローンの作成とアドホックネットワークの構築
https://qiita.com/YU_GENE/items/3c96d6f1a75299789700 - 防 水 型 超 音 波 セ ン サ モ ジ ュ ー ル J S N - S R 0 4 T と A r d u i n o U N O で 距 離 推 定 し て 遊 ん で み た
https://tmoribanner.hateblo.jp/entry/2020/03/15/211023
-
yuyu
さんが
2024/09/20
に
編集
をしました。
(メッセージ: 初版)
-
yuyu
さんが
2024/09/20
に
編集
をしました。
-
yuyu
さんが
2024/09/20
に
編集
をしました。
-
yuyu
さんが
2024/09/20
に
編集
をしました。
-
yuyu
さんが
2024/09/20
に
編集
をしました。
-
yuyu
さんが
2024/09/20
に
編集
をしました。
-
yuyu
さんが
2024/09/20
に
編集
をしました。
-
yuyu
さんが
2024/09/20
に
編集
をしました。
-
yuyu
さんが
2024/09/20
に
編集
をしました。
-
yuyu
さんが
2024/09/20
に
編集
をしました。
-
yuyu
さんが
2024/09/20
に
編集
をしました。
-
yuyu
さんが
2024/09/20
に
編集
をしました。
-
yuyu
さんが
2024/09/30
に
編集
をしました。
-
yuyu
さんが
2024/09/30
に
編集
をしました。
-
yuyu
さんが
2024/10/25
に
編集
をしました。
-
yuyu
さんが
2024/10/28
に
編集
をしました。
-
yuyu
さんが
2024/10/29
に
編集
をしました。
-
yuyu
さんが
2024/10/29
に
編集
をしました。
-
yuyu
さんが
2024/10/30
に
編集
をしました。
ログインしてコメントを投稿する