# 自動植物灌水 ![このレッスンの概要をスケッチノートで表した画像](../../../../../translated_images/lesson-7.30b5f577d3cb8e031238751475cb519c7d6dbaea261b5df4643d086ffb2a03bb.ja.jpg) > スケッチノート作成者:[Nitya Narasimhan](https://github.com/nitya)。画像をクリックすると拡大表示されます。 このレッスンは、[Microsoft Reactor](https://developer.microsoft.com/reactor/?WT.mc_id=academic-17441-jabenn)による[IoT for Beginners Project 2 - Digital Agricultureシリーズ](https://youtube.com/playlist?list=PLmsFUfdnGr3yCutmcVg6eAUEfsGiFXgcx)の一環として教えられました。 [![IoTによる自動植物灌水](https://img.youtube.com/vi/g9FfZwv9R58/0.jpg)](https://youtu.be/g9FfZwv9R58) ## 講義前のクイズ [講義前のクイズ](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/13) ## はじめに 前回のレッスンでは、土壌の湿度を監視する方法を学びました。今回のレッスンでは、土壌の湿度に応じて反応する自動灌水システムの主要な構成要素を構築する方法を学びます。また、センサーが変化に反応するまでに時間がかかることや、アクチュエーターがセンサーで測定される特性を変化させるまでに時間がかかることについても学びます。 このレッスンで学ぶ内容は以下の通りです: * [低電力IoTデバイスで高電力デバイスを制御する](../../../../../2-farm/lessons/3-automated-plant-watering) * [リレーを制御する](../../../../../2-farm/lessons/3-automated-plant-watering) * [MQTTを使って植物を制御する](../../../../../2-farm/lessons/3-automated-plant-watering) * [センサーとアクチュエーターのタイミング](../../../../../2-farm/lessons/3-automated-plant-watering) * [植物制御サーバーにタイミングを追加する](../../../../../2-farm/lessons/3-automated-plant-watering) ## 低電力IoTデバイスで高電力デバイスを制御する IoTデバイスは低電圧を使用します。この電圧はセンサーやLEDのような低電力アクチュエーターには十分ですが、灌水に使用される水ポンプのような大型ハードウェアを制御するには不十分です。家庭用植物に使用できる小型ポンプでさえ、IoT開発キットには電流が多すぎて基板が焼けてしまいます。 > 🎓 電流はアンペア(A)で測定され、回路を流れる電気の量を表します。電圧が押し出す力を提供し、電流は押し出される量を示します。[Wikipediaの電流のページ](https://wikipedia.org/wiki/Electric_current)で電流について詳しく読むことができます。 この問題を解決するには、ポンプを外部電源に接続し、アクチュエーターを使用してポンプをオンにする必要があります。これは、指でスイッチを押してライトをオンにするのと似ています。指を動かすのに必要なエネルギーはわずかですが、これにより110V/240Vの電力が流れるライトが接続されます。 ![ライトスイッチがライトに電力を供給する様子](../../../../../translated_images/light-switch.760317ad6ab8bd6d611da5352dfe9c73a94a0822ccec7df3c8bae35da18e1658.ja.png) > 🎓 [家庭用電力](https://wikipedia.org/wiki/Mains_electricity)は、世界の多くの地域で国のインフラを通じて家庭や事業所に供給される電力を指します。 ✅ IoTデバイスは通常3.3Vまたは5Vを供給し、電流は1アンペア(1A)未満です。これを家庭用電力と比較すると、家庭用電力は通常230V(北米では120V、日本では100V)で、30Aを引き出すデバイスに電力を供給できます。 これを実現するアクチュエーターにはいくつかの種類があり、既存のスイッチに取り付けて指でオンにする動作を模倣する機械装置も含まれます。その中で最も一般的なのがリレーです。 ### リレー リレーは電気信号を機械的な動きに変換してスイッチをオンにする電気機械式スイッチです。リレーの中心部は電磁石です。 > 🎓 [電磁石](https://wikipedia.org/wiki/Electromagnet)は、電気をコイル状のワイヤーに流すことで作られる磁石です。電気がオンになるとコイルが磁化され、電気がオフになると磁化が失われます。 ![オンの状態では、電磁石が磁場を作り、出力回路のスイッチをオンにする](../../../../../translated_images/relay-on.4db16a0fd6b669262fd6699aff3fbcd31b6057c06d90411b6bddc06326d1cf75.ja.png) リレーでは、制御回路が電磁石に電力を供給します。電磁石がオンになるとレバーを引き、スイッチを動かして接点を閉じ、出力回路を完成させます。 ![オフの状態では、電磁石が磁場を作らず、出力回路のスイッチをオフにする](../../../../../translated_images/relay-off.c34a178a2960fecdc3c6400d43e633ed11c6746cd653cfb4a768fa097c40394c.ja.png) 制御回路がオフになると電磁石がオフになり、レバーが解放されて接点が開き、出力回路がオフになります。リレーはデジタルアクチュエーターであり、高信号がリレーをオンにし、低信号がリレーをオフにします。 出力回路は灌水システムなどの追加ハードウェアに電力を供給するために使用できます。IoTデバイスはリレーをオンにして灌水システムに電力を供給し、植物に水を与えます。その後、IoTデバイスはリレーをオフにして灌水システムへの電力を切り、水を止めます。 ![リレーがオンになり、ポンプが作動して植物に水を送る様子](../../../../../images/strawberry-pump.gif) 上の動画では、リレーがオンになります。リレーのLEDが点灯してオンであることを示します(一部のリレーボードにはオンまたはオフを示すLEDがあります)。そしてポンプに電力が供給され、ポンプが作動して植物に水を送ります。 > 💁 リレーは、1つの出力回路をオンまたはオフにする代わりに、2つの出力回路を切り替えるためにも使用できます。レバーが動くと、1つの出力回路を完成させるスイッチから別の出力回路を完成させるスイッチに移動します。通常、共通の電源接続または共通のグランド接続を共有します。 ✅ 調査してみましょう:リレーにはさまざまな種類があり、制御回路が電力を供給されたときにリレーをオンまたはオフにするかどうかや、複数の出力回路があるかどうかなどの違いがあります。これらの異なる種類について調べてみてください。 レバーが動くと、電磁石との接触音としてはっきりとしたクリック音が聞こえることがよくあります。 > 💁 リレーを接続して、接続が実際にリレーへの電力を切断するように配線することができます。これによりリレーがオフになり、リレーに電力が送られ、再びオンになります。この動作が繰り返されることで、リレーが非常に速くクリックし、ブザー音を発します。これが初期の電気ドアベルで使用されたブザーの仕組みです。 ### リレーの電力 電磁石がレバーを引くために必要な電力は少なく、IoT開発キットの3.3Vまたは5V出力で制御できます。出力回路はリレーによってはるかに多くの電力を供給でき、家庭用電圧や産業用のさらに高い電力レベルを含む場合もあります。このようにして、IoT開発キットは小型の植物用ポンプから商業農場全体の大規模な産業システムまで灌水システムを制御できます。 ![制御回路、出力回路、リレーがラベル付けされたGroveリレー](../../../../../translated_images/grove-relay-labelled.293e068f5c3c2a199bd7892f2661fdc9e10c920b535cfed317fbd6d1d4ae1168.ja.png) 上の画像はGroveリレーを示しています。制御回路はIoTデバイスに接続され、3.3Vまたは5Vを使用してリレーをオンまたはオフにします。出力回路には2つの端子があり、どちらも電源またはグランドとして使用できます。出力回路は最大250Vで10Aまで対応可能で、さまざまな家庭用電力デバイスに十分です。さらに高い電力レベルに対応するリレーも入手可能です。 ![リレーを介して配線されたポンプ](../../../../../translated_images/pump-wired-to-relay.66c5cfc0d89189900cd601777f5caeb39ee35c6250f6c86bf38feaceedb21fe9.ja.png) 上の画像では、ポンプにリレーを介して電力が供給されています。USB電源の+5V端子からリレーの出力回路の1つの端子に赤いワイヤーが接続され、もう1つの端子からポンプに赤いワイヤーが接続されています。黒いワイヤーがポンプをUSB電源のグランドに接続しています。リレーがオンになると回路が完成し、ポンプに5Vが供給されてポンプが作動します。 ## リレーを制御する IoT開発キットからリレーを制御できます。 ### タスク - リレーを制御する 以下のガイドに従って、IoTデバイスを使用してリレーを制御してください: * [Arduino - Wio Terminal](wio-terminal-relay.md) * [シングルボードコンピュータ - Raspberry Pi](pi-relay.md) * [シングルボードコンピュータ - 仮想デバイス](virtual-device-relay.md) ## MQTTを使って植物を制御する これまでのところ、リレーは単一の土壌湿度測定値に基づいてIoTデバイスによって直接制御されています。商業灌水システムでは、制御ロジックが集中化され、複数のセンサーからのデータを使用して灌水の決定を行い、設定を一箇所で変更できるようにします。これをシミュレーションするために、MQTTを使用してリレーを制御できます。 ### タスク - MQTTを使ってリレーを制御する 1. `soil-moisture-sensor`プロジェクトにMQTTライブラリやpipパッケージを追加し、MQTTに接続するコードを追加します。クライアントIDは、あなたのIDを接頭辞として`soilmoisturesensor_client`と名付けてください。 > ⚠️ 必要に応じて、[プロジェクト1、レッスン4のMQTT接続手順](../../../1-getting-started/lessons/4-connect-internet/README.md#connect-your-iot-device-to-mqtt)を参照してください。 1. 土壌湿度設定を含むテレメトリを送信するためのデバイスコードを追加します。テレメトリメッセージでは、プロパティ名を`soil_moisture`としてください。 > ⚠️ 必要に応じて、[プロジェクト1、レッスン4のMQTTへのテレメトリ送信手順](../../../1-getting-started/lessons/4-connect-internet/README.md#send-telemetry-from-your-iot-device)を参照してください。 1. テレメトリを購読し、リレーを制御するコマンドを送信するローカルサーバーコードを`soil-moisture-sensor-server`というフォルダーに作成します。コマンドメッセージのプロパティ名は`relay_on`とし、クライアントIDはあなたのIDを接頭辞として`soilmoisturesensor_server`と名付けてください。プロジェクト1、レッスン4で作成したサーバーコードと同じ構造を維持してください。このコードは後のレッスンで追加されます。 > ⚠️ 必要に応じて、[MQTTへのテレメトリ送信手順](../../../1-getting-started/lessons/4-connect-internet/README.md#write-the-server-code)や[MQTTでのコマンド送信手順](../../../1-getting-started/lessons/4-connect-internet/README.md#send-commands-to-the-mqtt-broker)を参照してください。 1. 受信したコマンドからリレーを制御するためのデバイスコードを追加します。メッセージの`relay_on`プロパティを使用してください。`soil_moisture`が450を超える場合は`relay_on`にtrueを送信し、それ以外の場合はfalseを送信します。これは以前にIoTデバイスに追加したロジックと同じです。 > ⚠️ 必要に応じて、[MQTTからのコマンドに応答する手順](../../../1-getting-started/lessons/4-connect-internet/README.md#handle-commands-on-the-iot-device)を参照してください。 > 💁 このコードは[code-mqtt](../../../../../2-farm/lessons/3-automated-plant-watering/code-mqtt)フォルダーにあります。 デバイスとローカルサーバーでコードが実行されていることを確認し、仮想センサーが送信する値を変更したり、土壌に水を加えたりセンサーを土壌から取り外したりして土壌湿度レベルを変更することでテストしてください。 ## センサーとアクチュエーターのタイミング レッスン3ではナイトライトを作成しました。これは、光センサーが低い光レベルを検出するとすぐにLEDが点灯するものです。光センサーは光レベルの変化を瞬時に検出し、デバイスは`loop`関数や`while True:`ループの遅延時間の長さによってのみ制限される迅速な応答が可能でした。IoT開発者として、常にこのような迅速なフィードバックループに頼れるわけではありません。 ### 土壌湿度のタイミング 前回のレッスンで物理センサーを使用して土壌湿度を測定した場合、植物に水を与えた後、土壌湿度の読み取り値が下がるまで数秒かかることに気付いたかもしれません。これはセンサーが遅いのではなく、水が土壌に浸透するのに時間がかかるためです。 💁 センサーの近くに水をやりすぎた場合、測定値が急激に下がり、その後戻るのを目にしたかもしれません。これは、センサー付近の水が土壌全体に広がり、センサー付近の土壌水分を減少させることによって引き起こされます。 ![土壌水分測定値が658のまま変化せず、水やり後に水が土壌に浸透して320に下がる](../../../../../translated_images/soil-moisture-travel.a0e31af222cf14385de5380dfc32c7b8213960965228b8e4f7b7ab7f73b310a3.ja.png) 上の図では、土壌水分測定値が658を示しています。植物に水をやっても、この測定値はすぐには変化しません。これは水がまだセンサーに到達していないためです。水やりが終わっても、センサーに水が到達して測定値が新しい水分レベルを反映するまで時間がかかることがあります。 もし土壌水分レベルに基づいてリレーを使った灌漑システムを制御するコードを書く場合、この遅延を考慮し、IoTデバイスに賢いタイミングを組み込む必要があります。 ✅ 少し時間を取って、これをどう実現するか考えてみてください。 ### センサーとアクチュエーターのタイミングを制御する 農場用の灌漑システムを構築する任務を与えられたと想像してください。土壌の種類に基づき、栽培される植物にとって理想的な土壌水分レベルはアナログ電圧読み取り値で400~450に一致することが判明しています。 ナイトライトと同じ方法でデバイスをプログラムすることもできます。センサーが450を超える値を読み取る間はリレーをオンにしてポンプを作動させます。しかし問題は、水がポンプから土壌を通ってセンサーに到達するまで時間がかかることです。センサーは450のレベルを検出すると水を止めますが、ポンプで供給された水が土壌に浸透し続けるため、水分レベルはさらに下がり続けます。その結果、水が無駄になり、根が損傷するリスクが生じます。 ✅ 覚えておいてください - 水が多すぎることは少なすぎることと同じくらい植物に悪影響を及ぼし、貴重な資源を浪費します。 より良い解決策は、アクチュエーターがオンになるタイミングとセンサーが読み取るプロパティが変化するまでの遅延を理解することです。つまり、センサーは値を再測定する前にしばらく待つ必要があり、アクチュエーターも次のセンサー測定が行われる前にオフになる必要があります。 リレーを毎回どのくらいオンにするべきでしょうか?慎重に進める方が良く、リレーを短時間だけオンにして水が浸透するのを待ち、その後水分レベルを再確認する方が良いです。必要であれば水を追加するためにポンプを再度オンにすることはできますが、土壌から水を取り除くことはできません。 > 💁 このようなタイミング制御は、構築するIoTデバイス、測定するプロパティ、使用するセンサーやアクチュエーターに非常に特化したものです。 ![イチゴの植物がポンプを通じて水に接続されており、ポンプがリレーに接続されている。リレーと植物内の土壌水分センサーが両方ともRaspberry Piに接続されている](../../../../../translated_images/strawberry-with-pump.b410fc72ac6aabad3e28de9775bf2393ead73dcfec6fd8c9bc01cf107ecd171a.ja.png) 例えば、私はイチゴの植物を持っており、土壌水分センサーとリレーで制御されるポンプが接続されています。水を追加すると、土壌水分測定値が安定するまで約20秒かかることを観察しました。つまり、リレーをオフにして20秒待ってから水分レベルを確認する必要があります。水が多すぎるよりも少なすぎる方が良いです。ポンプを再度オンにすることはできますが、植物から水を取り除くことはできません。 ![ステップ1、測定を行う。ステップ2、水を追加する。ステップ3、水が土壌に浸透するのを待つ。ステップ4、再測定を行う](../../../../../translated_images/soil-moisture-delay.865f3fae206db01d5f8f100f4f44040215d44a0412dd3450aef7ff7b93b6d273.ja.png) これにより、最適なプロセスは以下のような水やりサイクルになります: * ポンプを5秒間オンにする * 20秒待つ * 土壌水分を確認する * 必要なレベルに達していない場合は、上記の手順を繰り返す ポンプにとって5秒は長すぎる場合があります。特に水分レベルが必要なレベルを少し超えている場合はそうです。最適なタイミングを知るためには試してみて、センサーデータを基に調整するのが良いです。これにより、より細かいタイミング制御が可能になります。例えば、必要な土壌水分を100超えるごとにポンプを1秒間オンにするなど、固定の5秒間ではなく柔軟な制御が可能です。 ✅ 調査してみてください:他にタイミングを考慮すべき点はありますか?土壌水分が低すぎる場合、植物にいつでも水をやることができますか?それとも植物に水をやるのに適した時間帯や不適切な時間帯があるのでしょうか? > 💁 屋外栽培の自動灌漑システムを制御する際には、天気予報も考慮することができます。雨が予想される場合は、雨が終わるまで水やりを保留にすることができます。その時点で土壌が十分に湿っている可能性があり、水やりが不要になることがあります。これは、雨の直前に水をやることで水を無駄にするよりもはるかに効率的です。 ## 植物制御サーバーにタイミングを追加する サーバーコードを修正して、水やりサイクルのタイミングを制御し、土壌水分レベルが変化するのを待つようにします。リレータイミングを制御するサーバーロジックは以下の通りです: 1. テレメトリメッセージを受信する 1. 土壌水分レベルを確認する 1. 問題がなければ何もしない。測定値が高すぎる場合(土壌水分が低すぎることを意味する)、以下を実行する: 1. リレーをオンにするコマンドを送信する 1. 5秒間待つ 1. リレーをオフにするコマンドを送信する 1. 土壌水分レベルが安定するまで20秒間待つ 水やりサイクル、つまりテレメトリメッセージを受信してから土壌水分レベルを再度処理する準備が整うまでのプロセスには約25秒かかります。土壌水分レベルは10秒ごとに送信されるため、サーバーが土壌水分レベルの安定を待っている間にメッセージが受信され、別の水やりサイクルが開始される可能性があります。 これを回避する方法は2つあります: * IoTデバイスコードを変更してテレメトリを1分ごとに送信するようにする。この方法では水やりサイクルが完了してから次のメッセージが送信されます。 * 水やりサイクル中にテレメトリの購読を解除する 最初の方法は大規模な農場では必ずしも良い解決策ではありません。農家は水やり中の土壌水分レベルを記録して後で分析したいかもしれません。例えば、農場の異なるエリアでの水の流れを把握し、よりターゲットを絞った水やりを行うためです。2番目の方法の方が良いです。このコードは使用できないテレメトリを無視するだけですが、テレメトリは他のサービスが購読するために引き続き存在します。 > 💁 IoTデータは1つのデバイスから1つのサービスに送信されるだけではありません。代わりに、多くのデバイスがデータをブローカーに送信し、多くのサービスがそのデータをブローカーから受信することができます。例えば、1つのサービスが土壌水分データを聞いてデータベースに保存し、後で分析することができます。また、別のサービスが同じテレメトリを聞いて灌漑システムを制御することもできます。 ### タスク - 植物制御サーバーにタイミングを追加する サーバーコードを更新してリレーを5秒間作動させ、その後20秒間待機するようにします。 1. VS Codeで`soil-moisture-sensor-server`フォルダーを開きます(まだ開いていない場合)。仮想環境が有効になっていることを確認してください。 1. `app.py`ファイルを開きます。 1. 既存のインポートの下に以下のコードを追加します: ```python import threading ``` このステートメントはPythonライブラリから`threading`をインポートします。`threading`を使用すると、待機中にPythonが他のコードを実行できます。 1. サーバーコードがテレメトリメッセージを処理する`handle_telemetry`関数の前に以下のコードを追加します: ```python water_time = 5 wait_time = 20 ``` これにより、リレーを作動させる時間(`water_time`)とその後に土壌水分を確認するまでの待機時間(`wait_time`)が定義されます。 1. このコードの下に以下を追加します: ```python def send_relay_command(client, state): command = { 'relay_on' : state } print("Sending message:", command) client.publish(server_command_topic, json.dumps(command)) ``` このコードは、リレーを制御するコマンドをMQTT経由で送信する`send_relay_command`という関数を定義します。テレメトリは辞書として作成され、JSON文字列に変換されます。`state`に渡される値はリレーをオンにするかオフにするかを決定します。 1. `send_relay_code`関数の後に以下のコードを追加します: ```python def control_relay(client): print("Unsubscribing from telemetry") mqtt_client.unsubscribe(client_telemetry_topic) send_relay_command(client, True) time.sleep(water_time) send_relay_command(client, False) time.sleep(wait_time) print("Subscribing to telemetry") mqtt_client.subscribe(client_telemetry_topic) ``` これにより、必要なタイミングに基づいてリレーを制御する関数が定義されます。まずテレメトリの購読を解除して、水やり中に土壌水分メッセージが処理されないようにします。次にリレーをオンにするコマンドを送信します。その後、`water_time`の間待機してからリレーをオフにするコマンドを送信します。最後に、土壌水分レベルが安定するまで`wait_time`秒間待機します。その後、テレメトリの購読を再開します。 1. `handle_telemetry`関数を以下のように変更します: ```python def handle_telemetry(client, userdata, message): payload = json.loads(message.payload.decode()) print("Message received:", payload) if payload['soil_moisture'] > 450: threading.Thread(target=control_relay, args=(client,)).start() ``` このコードは土壌水分レベルを確認します。450を超える場合、土壌に水が必要であるため、`control_relay`関数を呼び出します。この関数は別のスレッドでバックグラウンドで実行されます。 1. IoTデバイスが動作していることを確認し、このコードを実行します。土壌水分レベルを変更し、リレーに何が起こるか観察してください。リレーは5秒間オンになり、その後少なくとも20秒間オフのままになります。土壌水分レベルが十分でない場合のみ再度オンになります。 ```output (.venv) ➜ soil-moisture-sensor-server ✗ python app.py Message received: {'soil_moisture': 457} Unsubscribing from telemetry Sending message: {'relay_on': True} Sending message: {'relay_on': False} Subscribing to telemetry Message received: {'soil_moisture': 302} ``` シミュレーションされた灌漑システムでこれをテストする良い方法は、乾燥した土壌を使用し、リレーがオンの間に手動で水を注ぎ、リレーがオフになったら注ぐのを止めることです。 > 💁 このコードは[code-timing](../../../../../2-farm/lessons/3-automated-plant-watering/code-timing)フォルダーにあります。 > 💁 実際の灌漑システムを構築するためにポンプを使用したい場合は、[6V水ポンプ](https://www.seeedstudio.com/6V-Mini-Water-Pump-p-1945.html)と[USB端子電源](https://www.adafruit.com/product/3628)を使用できます。ポンプへの電力またはポンプからの電力がリレーを介して接続されていることを確認してください。 --- ## 🚀 チャレンジ センサーにアクチュエーターの結果が到達するまで時間がかかるという同様の問題を抱える他のIoTや電気デバイスを考えることができますか?家や学校にいくつかあるかもしれません。 * どのようなプロパティを測定していますか? * アクチュエーターが使用された後、プロパティが変化するまでどのくらいの時間がかかりますか? * プロパティが必要な値を超えて変化しても問題ありませんか? * 必要に応じてプロパティを元の値に戻す方法はありますか? ## 講義後のクイズ [講義後のクイズ](https://black-meadow-040d15503.1.azurestaticapps.net/quiz/14) ## 復習と自己学習 * [リレーのWikipediaページ](https://wikipedia.org/wiki/Relay)で、電話交換機での歴史的な使用を含むリレーについてさらに学びましょう。 ## 課題 [より効率的な水やりサイクルを構築する](assignment.md) **免責事項**: この文書は、AI翻訳サービス [Co-op Translator](https://github.com/Azure/co-op-translator) を使用して翻訳されています。正確性を期すよう努めておりますが、自動翻訳には誤りや不正確な表現が含まれる可能性があります。原文(元の言語で記載された文書)が信頼できる情報源として優先されるべきです。重要な情報については、専門の人間による翻訳を推奨します。この翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。