タッチノード
センサーユニットは複数のセンサーで構成されています。
- パッシブ赤外線モーションセンサー
- アナログ温度センサー。 TMP036またはLM35のいずれかです。 一部の可変オフセットを除き、両方とも摂氏温度ごとに10 mV電圧の同じ温度特性を持っています。
- フォトレジスター(光センサー)。
- コマンドボタン
タッチノードにはLEDのペアも含まれています。これらはデバッグ目的で必要です。
- ボタンが押されたときにオン/オフする赤いLED。
- モーションセンサーがトリガーされると点灯する緑色のLED。
これは、Fritzingアプリケーションツールによって作成されたセンサーノードの概略図です。
デバイスの概略図
センサーアセンブリを組み立てるには、次のコンポーネントが必要です。
- 1 x Edisonモジュール。
- Edison用Arduino拡張ボードx 1
- 2 x 200オームの抵抗。
- 2 x 1kΩ抵抗。
- 1 x 10kΩ抵抗。
- 1 xコマンドボタン。
- 2 x LED。 赤と緑を使用しましたが、他の色でも使用できます。
- 1 x温度センサー、TMP036またはLM35。
- 1 x赤外線モーションセンサー。
- 無はんだプロトタイピング用の1 xボード。
- プロトタイピング用のワイヤまたはジャンパ。
同様のコンポーネントは、小売顧客にサービスを提供するさまざまなサプライヤーで見つけることができます。 たとえば、 AdafruitやSparkfunの場合 。 大量のコンポーネントが必要な場合、 Mouser ElectronicsまたはDigiKeyで同じものを見つけることができますが、少し安くなります。
Arduino用プログラム
センサーノードの機能を実装するArduinoのプログラムを以下に示します。 Arduinoの開発に精通している読者は、問題なくこのコードを理解できます。 ただし、ここでいくつかの実装機能を明確にし、Edisonと通常のArduino(Arduino Unoなど)のいくつかの違いを指摘します。
割り込みは、ボタンとモーションセンサーからの信号を処理するために使用されます。 これらのデバイスの入力イベントは非同期で発生するため、割り込みメカニズムを使用して最適に処理されます。 Edisonでの割り込みの動作は、Arduino Unoの場合とは異なります。 主な違いは次のとおりです。
- Edison割り込みは、すべてのGPIO出力を生成できます。 Arduino Unoでは、ピン2と3のみが割り込みを生成できるため、より柔軟な設計をEdisonに実装できます。
- Edisonですべてのピンが割り込みを生成できるため、attach_interruptコールは、Arduino Unoのように事前定義された番号0または1ではなく、ピン番号を割り込みチャネルとして使用します。
- Edisonでは、millis()タイマーは割り込みハンドラーで引き続き実行されます。 これにより、時間間隔を測定するための呼び出しを行うことができます。
モーションセンサーは、モーションが検出されると信号接点で高(HIGH)ロジックレベルを設定します。 信号は数秒間このレベルのままで、その後低(LOW)論理レベルに切り替わります。 センサーによって記録されたイベントの履歴を取得するために、動きの検出に対応するパルスの持続時間を測定し、グローバルカウンターに蓄積します。 毎分、アクティビティのレベルを測定し、モーションセンサーが観測値の合計期間(1分)に対してHIGH値を与えた時間の割合を計算します。 アクティビティのレベルに関する情報はパーセンテージで表示されます。 したがって、動きが記録されていない場合、アクティビティのレベルはゼロになります。 センサーが1分間動きを記録した場合、アクティビティレベルは100%に近くなります。 アクティビティレベルは、次の監視間隔の開始時にゼロにリセットされます。
スイッチ接点の跳ね返りから生じるボタンからの誤った割り込みの発生を防ぐために、最後の割り込みが発生した時間を追跡します。 新しいものが前のものよりも200ミリ秒より早く到着した場合、それを偽と見なし、無視します。
Edisonは、DCソースの正極であるVCCを、アナログ-デジタルコンバーター(ADC)の基準電圧として使用します。 ボードにUSBポートから電力が供給されている場合、VCC電圧は正確に5 Vではない可能性があります。ほとんどの場合、4.8 V〜5.1 Vの範囲になります。ADCの分解能を計算するには、実際の基準電圧を使用する必要があります。 電源電圧を測定し、分解能(VCC / 1024)を計算するには、電圧計を使用できます。 結果の値は、10ビットEdisonアナログ-デジタルコンバーターの解像度になります。
/* Intel Edison : 1) : , 2) : 3) : 4) : Copyright (c) 2015 Intel Corporation THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <Arduino.h> // #define RED_LED 10 // #define GREEN_LED 11 // #define PIR_SENSOR 12 // #define BUTTON 13 // 10K // #define LIGHT_SENSOR A0 // #define TEMP_SENSOR A1 // TMP36 LM35 #define MIN_PULSE_SEPARATION 200 // #define ADC_STEPSIZE 4.61 // , . 4.72 VCC, #define USE_TMP036 1 #if (USE_TMP036 == 1) #define TEMP_SENSOR_OFFSET_VOLTAGE 750 #define TEMP_SENSOR_OFFSET_TEMPERATURE 25 #else // LM35 #define TEMP_SENSOR_OFFSET_VOLTAGE 0 #define TEMP_SENSOR_OFFSET_TEMPERATURE 0 #endif // unsigned long updateTime = 0; // volatile unsigned long activityMeasure; volatile unsigned long activityStart; unsigned long resetActivityCounterTime; // boolean toggleLED = 1; volatile unsigned long previousEdgeTime = 0; volatile unsigned long count = 0; /********************************************************************************************** ***********************************************************************************************/ void setup() { Serial.begin(115200); delay(3000); Serial.println("Ready"); pinMode(RED_LED, OUTPUT); pinMode(GREEN_LED, OUTPUT); pinMode(BUTTON, INPUT_PULLUP); pinMode(PIR_SENSOR, INPUT); attachInterrupt(BUTTON, buttonISR, RISING); // attachInterrupt(PIR_SENSOR, pirISR, CHANGE); // resetActivityCounterTime = millis(); // digitalWrite(RED_LED, LOW); digitalWrite(GREEN_LED,LOW); } /********************************************************************************************** ***********************************************************************************************/ void loop() { if (millis() > resetActivityCounterTime) { // 60 resetActivityCounterTime = millis() + 60000; Serial.print("ActivityLevel: ");Serial.println(100.0*activityMeasure/60000.0); activityMeasure = 0; } if (millis() > updateTime) { // 10 updateTime = millis() + 10000; Serial.print("Temperature sensor: "); Serial.println(readTemperature()); Serial.print("Light sensor: "); Serial.println(readLightSensor()); } delay(100); } /********************************************************************************************** , , HIGH , . , HIGH 3-5 , LOW. HIGH, . ***********************************************************************************************/ void pirISR() { int pirReading; unsigned long timestamp; timestamp = millis(); pirReading = digitalRead(PIR_SENSOR); if (pirReading == 1) { Serial.print(millis()); Serial.println(": PIR motion started"); // activityStart = timestamp; } else { int pulseWidth = timestamp-activityStart; activityMeasure += pulseWidth; Serial.print(millis()); Serial.println(": PIR motion ended"); Serial.print("Duration: "); Serial.print(pulseWidth); Serial.println(" ms"); Serial.print("ActivityMeasure: "); Serial.print(activityMeasure); Serial.println(" ms"); } // , digitalWrite(GREEN_LED, pirReading); } /********************************************************************************************** ***********************************************************************************************/ int readLightSensor() { return analogRead(LIGHT_SENSOR); } /********************************************************************************************** ***********************************************************************************************/ float readTemperature() { int sensorReading; float temperature; sensorReading = analogRead(TEMP_SENSOR); temperature = sensorReading * ADC_STEPSIZE; // temperature = (temperature - TEMP_SENSOR_OFFSET_VOLTAGE)/10.0 + TEMP_SENSOR_OFFSET_TEMPERATURE; temperature = temperature * 1.8 + 32.0; // return temperature; } /********************************************************************************************** ***********************************************************************************************/ void buttonISR() { // , Serial.print(millis()); Serial.println(": Button ISR"); if ((millis()-previousEdgeTime) >= MIN_PULSE_SEPARATION) { digitalWrite(RED_LED, digitalRead(RED_LED) ^ 1); count++; Serial.print("Count: "); Serial.println(count); } previousEdgeTime=millis(); }
テスト中
センサーアセンブリが正しく機能していることを確認するには、少なくとも次の実験を実行する必要があります。
- モーションセンサーの前で手を振ると、緑色のLEDが点灯します。 手が取り外された後、さらに2〜3秒間火傷し、電源が切れます。
- モーションセンサーに手をかざすと、緑色のLEDが点灯します。 手を離さずにセンサーの前で手を動かさずに動かした場合、つまり動きを止めた場合、上記の間隔が経過すると緑色のLEDが消灯します。
- ボタンを押すと、赤色のLEDがオン/オフになります。
- シリアルポートからのデータを表示するデバッグウィンドウには、温度センサーと光センサーからの情報が10秒ごとに表示されます。 モーションセンサーによって検出されたアクティビティのレベルに関するメッセージは、毎分表示される必要があります。
- あなたが手で光センサーを覆う場合、これはそれから来るインジケーターの値の減少に反映されるはずです。 たとえば、LEDフラッシュを使用してこのセンサーを照らすと、値は最大値、つまり1023に近くなります。
- 温度センサーの上部を指で押さえると、システムは温度の上昇を記録するはずです。 この場合、温度は徐々に正常な体温に達するはずです-華氏約95-98度。
以下に、実験を示すビデオを示します。
結論
Intel Edisonを使用してセンサーノードを構築し、Arduino IDEでプログラムを作成しました。 この種のセンサーは、ホームセキュリティシステムにあります。 EdisonとArduinoのプログラミングの違いも考慮されました。 このシリーズの次の記事では、センサーノードをインターネットに接続して、モノのインターネット、つまり実際のIoTデバイスへの完全な参加者にします。 最終プロジェクトでは、すでに説明したMosquitto MQTT-brokerがセンサーノードのデータ転送インターフェイスとして使用されます。