
こんにちは、Habrozhitel様!
最近、父は私に電話して、彼は彼が絶えず水を飲むのを忘れるか、過度に水を注ぐ花を持っていると私に話しました;その結果、彼は乾くか、逆に過剰な水分に苦しんでいます。
マイクロコントローラとC#を使用してこの問題を解決します。

簡単な協議の後、このプロセスを自動化することが決定されました。 私たちは、見たいものの基本的な要件を自分自身で特定しました。
- 安価で、市場の同等品よりも安くなければなりません。
- プログラムが非常に簡単で、画面に視覚的なインターフェイスが必要です
- 情報はセンサーに基づいて収集する必要があります(つまり、タイマーに意味がない-執筆時点で市場にあるすべてのアナログはタイマーベースであるか、または見つかりませんでした)
- 花はコンピューターの隣にあるため、USBを使用できます(電源供給を避けることが望ましい)
パート1.ハードウェア
Habré( 質問 )について質問したところ、Arduinoやその他のデバイスに関する多くの提案を受け取りましたが、 AVR-USB-MEGA16で停止しました (Andreyに感謝します。開発のアドバイスと支援、および配信の速さについて)。

その結果、次のコンポーネントが購入されました。
- AVR-USB-MEGA16-500ルーブル。
- 土壌水分センサー-120ルーブル。
- 200 l / hの水槽ポンプ-507こする。
- 土壌洗浄剤(キットからチューブが必要)-330ルーブル。
- 水族館スタッファー-193こする。
- リレー5DC / 220AC-170ルーブル。
- 双極トランジスタ-7.5ルーブル
- 抵抗-10 p。
- 端子付きブロック-100 r
- ヒューズボックス-50 r
- ヒューズ-22ルーブル。
- USBケーブル-220ルーブル。
合計、すべてのささいなことは別として、それは約2200ルーブルになりました。

すべての部品は非常にコンパクトで、最大のものはポンプです。

それで、すべてが買われました、それは構築する時間です。 @AlekseyNovikovは、リレースイッチング回路についてアドバイスしました。 以下に図を示します。

ダイオードを削除することを決めた唯一のもの。 夕方のはんだ付けに費やした後、私は完全に健全な結果を得ました:

次に、最も興味深いもの、つまり作業のロジックに目を向けます。
パート2.ソフトウェアパート
このアイデアを始める前の主な恐怖または懸念は、マイクロコントローラーのプログラミングの難しさ、通常のデバッグの欠如、およびその他の難しさでした。したがって、この記事の主な目的は、新しいアイデアではないので、現代の言語を使用してそのようなデバイスを使用するシンプルさを促進することですC#などのプログラミング。
ボードから必要なものは2つだけです。
- 土壌水分センサーの測定値
- リレーのオン/オフ
したがって、KPFのファームウェアと組み合わせてWPFを使用しました(この仕組みの詳細については、こちらを参照してください )。
このプログラムは、トレイアイコンと小さな目立たないウィンドウです。

プログラムの設定も可能な限り簡単です。

ソフトウェアの作業における主な困難には、次の問題が含まれます。
- ポンプに表示されるポンプの性能は、現実とはほとんど関係ありません
- ポンプの性能は水の高さに大きく依存します。たとえば、ポンプが単に水を排出する場合、私のポンプの性能は1時間あたり350リットルに達しますが、80 cmの持ち上げ高さでは1時間あたり40リットルにはほとんど達しません。
- ポンプが目で作動する容器の容量を決定することは困難です。
- 水が花に到達する前に、チューブの上の難しい経路を通過する必要があります。
これらの問題を解決するために、測定に基づく単純なアルゴリズムが発明されました。 すべてが整った後、水がタンクに集められます:
- 水の上昇速度を決定します:マウスで適切なフィールドをクリックしてからEnterを押すだけで、最初の水滴が表示されたらすぐにポンプが作動し始め、もう一度Enterを押すと、水を持ち上げるのにかかった時間がわかります。
- 特定の高さでのポンプの性能を決定します。時間を決定した後、容量がわかっているガラスを見つけ、混合物用の哺乳瓶を取り出し、測定されたリスクを適用し、「Watering Volume」の値を200 mlに設定します。 「Pump Performance」フィールドをマウスでクリックし、Enterを押して、ボトルに正確に200 mlが注がれるまで待ちます。これが再び発生したら、Enterを押して、正確なポンプ性能が得られます。
- タンクの容量を決定します:ここでは、バケツまたは大容量が必要です。同様に、目的のフィールドをアクティブにし、Enterを押して、ほぼすべての水が注がれるまで待機します。ポンプがまだ少し水で覆われている瞬間に停止する必要があります。 使用できる水量があります。
すべて、システムは作動する準備ができています。 設定の最初のパラメーター-散水の量によると、土壌水分センサーとこのタイプの植物の最適な湿度に基づいて自動的に決定されます(残念ながら、インターフェイスに入れませんでした、XMLファイルにインストールされます)
APC(Automatic Watering Flower)のアルゴリズムは単純です:
10分に1回、土壌水分センサーから読み取り値が取得されます(一連の測定が行われ、算術平均が取得されます)。 証拠に基づいて、標準からの逸脱が5%を超える場合、土壌に灌漑する決定が行われ、その後散水が行われます。 すべてのアクションに関するデータがデータベースに記録され、それらに基づいて灌漑の予測が作成され、スケジュールと灌漑の必要量が決定されます。 注がれた液体の量を決定するアルゴリズムも非常に簡単です。 74%(特定のプラントのXMLファイルに示されている)などの特定の湿度標準があり、100 mlのボリュームで最初の散水が行われ、10分後に次の湿度測定が行われ、湿度が必要未満の場合は基準湿度レベルからの偏差が確認されます。次の散水は、偏差(100 ml、50 ml、10 ml、3 ml)に応じて段階的に追加されます。 湿度レベルが+ -5単位変更されていない場合、タンクの水がなくなったと思われるため、SMSを送信します。
残念ながら、 私は花が好きではなく 、単に花がありません。そのため、実際の植物でシステムを実行できませんでした。実験の最初の週に成功した実験用の菊を購入しました。 メカニズムは私の父に無事に送られました(こんにちはRussian Post、パッケージは1週間で届くはずで、既に3つあり、何が問題なのかはまだわかりません)。インストールして開始するとすぐに、ビデオを確実に撮って追加します。
このシステムの欠点には、多くのことが含まれます。まず、PCに依存します。次に、PCに依存します。次に、非常に大きく、大きなタンク、ワイヤーが入ります。太いチューブがポットの上部になり、センサーからのワイヤーがポットから出ます。差し込まれた 220Vポンプ。
近い将来のすべての欠点を排除する計画、私は1つのポットにすべてを含む3Dモデルを描きたい-タンク、ポンプ、水路、センサー、LCDスクリーンなど、私はこれらすべてを少なくとも6か月間バッテリーで動作させたい、このポットはArduin Pro Miniで動作します。
現時点では、Blenderをマスターしています(3D Maxで多くの経験があります)。海賊版ソフトウェアを完全に放棄することに決めたので、終了後、モデルを3D印刷に引き渡し、すべての欠点を取り除き、プロトタイプを実行し、この記事の続きを書きます。
UPD:現在のデバイス図を囲みます(ダイオードなし、後で追加する必要があります)

最も興味深い点には、デバイスの準備が含まれます。
public static bool Init() { dev = new ATMega16(vid, pid); // dev ATMega16. if (!dev.IsOpen()) // USB { return false; } else // , USB { dev.DDRD |= 0x80; // 7 D - dev.PORTD &= 0x7F; // dev.ADMUX = (3 << ATMega16.REFS0); // // 200 . // 128 ( ADPS0, ADPS1 ADPS2 1). .. 125 . // (1/125000)*13 = 104 , - 9.6 // ADEN 1 dev.ADCSRA = (1 << ATMega16.ADEN) | (1 << ATMega16.ADPS2) | (1 << ATMega16.ADPS1) | (1 << ATMega16.ADPS0); } return true; }
センサー測定値:
dev.ADMUX = (byte)((dev.ADMUX & 0xE0) | 0); // - ADC0 dev.ADCSRA |= (1 << ATMega16.ADSC); // // ( 100 ). while ((dev.ADCSRA & (1 << ATMega16.ADIF)) == 0) ; return (dev.ADCL + (((int)dev.ADCH) << 8)); //
センサーからの読み取り値を湿度(%)で変換し、その後小文字の値に変換します。
var persantage = (int)(stateOfSoil / 8.4); if (persantage < 10) result = ""; else if (persantage < 20) result = " "; else if (persantage < 30) result = ""; else if (persantage < 40) result = ""; else if (persantage < 50) result = ""; else if (persantage < 60) result = ""; else if (persantage < 70) result = ""; else if (persantage < 80) result = ""; else if (persantage < 90) result = ""; else result = ""; return String.Format("{0} ({1}%)", result, persantage);
ポンプオン:
dev.PORTD |= 0x80;
ポンプを無効にします:
dev.PORTD &= 0x7F;