さまざまな周辺機器(電子ロック、モーター、LEDストリップ、その他の電子機器)を制御するコントローラーに基づいた複雑な自動システムを作成します。
このシステムの作成はこれと同様のクエストルームに必要でしたが、 ハバロフスクの都市で。
私たちの探求は異なる設定にありますが、一般的にはほぼ同じセットのアクチュエーターがあります:リレー、ロック、テープ、リードスイッチなど
基本的なシステム要件:
- 信頼性 -複雑なシステムを開発する場合、認識しにくいエラーを発生させる可能性が高く、コードが多いほどエラーを見逃す可能性が高くなり、デバッグに時間がかかるため、誤操作の可能性を最小限に抑える必要があります。
- 柔軟性 -最小限の時間で作業のロジックを変更する機能
- 機能性 -機器の制御とセンサーの接続
特に、次のようなかなり複雑なシナリオが必要でした。
- Storyline non-linear-プレイヤーはパズルを解くいくつかの異なる方法を見つけることができます。
- 接続性 -他の多くのゲームイベントの完了後にのみ発生するイベント
すべての問題の解決策は、主に「状況指向プログラミングのパラダイム」に関する記事により発見されました。
- 柔軟性 -イベントアーキテクチャを正しく構築する
- 信頼性 -なぜなら すべてのイベントは同じタイプであり、単純なコードを使用して同様の方法で実装でき、信頼性を保証できます
- 機能 -イベントは、あらゆる方法で実装できるアクションをトリガーします
したがって、システムのアーキテクチャは、3種類の基本構造に基づいて構築できます。
- イベント
- トリガー
- アクション
このアーキテクチャでは、 トリガーコードテンプレートで状態の状態を設定すると(アクティブ化/非アクティブ化)、ボーナスとしてトリガーの状態を イベントとして使用できるため、イベント関係の任意の複雑なシステムとアルゴリズムの非線形性を構築できます。
アクションを別の機能ユニットに割り当てることにより、開発段階でも各アクションのプログラムコードを個別にテストする機会が得られます。このようなコードのデバッグは、プロジェクト全体のデバッグよりもはるかに簡単です。 トリガーはすでにデバッグされたコードを参照します。
トリガーは、イベントまたはトリガー状態の任意の組み合わせ(および/または\ not)をトリガー条件として使用できます。
イベントはどのようなものでもかまいません(ポート状態、シリアルのメッセージなど)。現在の実装では十分なポートステータスがあったため、このオプションのみが残っている間、機能の拡張にはそれほど時間はかかりません。
システムを作成する際に、ローカル市場で入手可能な機器を使用することが決定されました。他の地域からのメール配信の問題を考えると、Arduinoボードのみがそのようなことが判明しました。
アプリケーションは、このプラットフォーム用のスケッチコードを生成するように構成されていますが、必要に応じて、他のプログラミング言語への適応には数分しかかかりません。
したがって、Arduinoスケッチのテンプレートは、たとえば次のような最も単純な形式になります。
メインプログラムコード
@init void setup() { @runonce } void loop() { @loopcode } @triggers @sensors @actions
アクションコードテンプレート
//@description void @name() { bool debug=true; //@id @code //@id if (debug) { Serial.println("DoAction @name"); } }
トリガーコードテンプレート
//@description bool @nameActivated=false; bool @name(){ if (@nameActivated){ return true; }else { if (@event){ @nameActivated=true; Serial.println("@name Activated"); @nameDoAction(); return true; } return false; } return false; } void @nameDoAction(){ @nameActivated=true; //****************************************** @actions //****************************************** }
センサーコードテンプレート
//@description bool @name() { int @namePin=@pinNumber; pinMode(@namePin, INPUT_PULLUP); int sensorVal = digitalRead(@namePin); if (sensorVal == @trueval) {return true;}else{return false;} }
初期化パターンの例
このテンプレートでは、ライブラリを接続し、プロジェクト全体のグローバル変数と関数を宣言できます。
#include <etherShield.h> #include <ETHER_28J60.h> #include <EEPROM.h> static uint8_t mac[6] = {0x54, 0x55, 0x58, 0x10, 0x10, 0x24}; static uint8_t ip[4] = {192, 168, 137, 15}; static uint16_t port = 80; ETHER_28J60 ethernet; bool started=false;
アプリケーションウィンドウのテンプレートデータに基づいて、すべてのスクリプトパラメータを設定できます。
ファームウェアをエクスポートした後、同様のコードを取得できます。
たくさんのスケッチレター
このアプローチの利点は、ファームウェアのエクスポート時のすべてのアクションブロックが開発の段階で既にデバッグされ、アクションコードのトリガー、センサー、ラッパーのすべてのブロックがデバッグされ、コードがエラーなしでコンパイルされ、デバッグ段階なしで すぐに正しく動作する ことです。
実際には、クエストルームを開発する場合、スクリプトを何度も変更する必要がありました。アプリケーションのおかげで、ファームウェアコードを変更する必要はなく 、プログラムインターフェイスのトリガーパラメーターを変更するだけです。
クエストの写真はまだ掲載していませんが、希望があれば添付できます。 現時点では、このスキームに従って作成されたファームウェアを備えた機器は、1回の誤動作なしで50以上のゲームサイクルをすでに解決しています。
アプリケーションのソースコードは公開されており、誰でもアクセスできます 。
典型的なテンプレート設定のテストアプリケーションは、 githubにあります。
この記事が、スマートホーム、セキュリティシステム、またはその他のさまざまなプロセスを自動化するシステムを作成することを決定した人に役立つことを願っています。