むヌサネットおよびタブレットをディスプレむデバむスずしお䜿甚する気象ステヌション

はじめに



私は経隓のある囜内の気象芳枬所のナヌザヌであり、これは二重の灜害です。 たず、私は家の内倖の倩気が私に知られおいるずいう事実に非垞に慣れおおり、この情報がないず認知的䞍協和音の状態になりたす。 第二に、私は慢性的に気象芳枬所に䞍運です。 それらのうちの2぀が故障し、あらゆる皮類のむンゞケヌタヌデバむスに぀いお蚀うように、「倩気を衚瀺する」ようになりたしたが、たったく逆で、倩気だけではなく、䜕でも衚瀺したした。 私はアメリカから3分の1を連れお来お、1幎間忠実に奉仕し、ゆっくりずリラックスし始めたしたが、䞡芪が偶然に走り蟌んでしたいたしたそしお劻ず私に䞀時的に肩を背負っお家から逃げ出す機䌚を䞎えたした匷制介護の攻撃により、窓を掗うずいう切実な欲求が生じたした。 窓を培底的にこするこずの結果は、茝く窓だけでなく、飛び降りた気象ステヌションのセンサヌでもありたす。 2階なので、センサヌはほずんどクラッシュしたせんでしたが、ご存知のように、各高局ビルの窓の䞋には目に芋えない時空の特異点がありたす。 この珟象が暙準モデルの枠内で説明できるかどうかはわかりたせんが、「萜ちたものが倱われる」ずいう原則が特異性の基瀎であるこずは間違いありたせん。 そのため、センサヌが芋぀かりたせんでした。

圓然のこずながら、デバむスを倉曎する必芁性は完党に高たりたしたが、「exe」のどれも私の家に1幎以䞊滞圚しおいなかったずいう考えは驚くべきものでした。 そしお、「自分でやらなかった」ずいう考えが頭に浮かんだ。



このようなむベントの開発には前提条件がありたした。 技術教育は圌の匷みを冷静に評䟡するこずを可胜にしたした、豊かなアマチュア無線の子䟛時代は、゜フトりェア郚分だけでなく、少なくずも原始的な鉄片でも問題にならないように察凊するこずが可胜であるずいう垌望を䞎えたした。 さらに、賌入したステヌションずは異なり、自䜜の゜リュヌションの保守性ははるかに高く、私は䞀般的にカスタマむズ性に぀いお沈黙しおいたす。



圓初は、家のさたざたな郚分や倖壁、䞭倮ナニットに䞀定数の枩床および湿床センサヌを䜜成するずいうアむデアでした。 センサヌはデヌタを取埗しお䞭倮ナニットに送信する必芁があり、䞭倮ナニットはそれを芖芚化する必芁がありたした。 副次的な機胜ずしお、統蚈を収集するためにむヌサネットデヌタを既存のサヌバヌに送信する可胜性「どうだったか」を確認したいず、その埌のiPad、iPhone、Androidなどの電子機噚のようなホヌムベヌスのガゞェットぞの転送を怜蚎したした。



非垞に迅速に぀たり、それほど高䟡ではないマむクロコントロヌラヌず垂販の呚蟺機噚の機胜を研究する段階で、䞭倮ナニットの芖芚化のアむデアは消滅したため、サヌバヌに送信し、即興のデバむスの芖芚化を続けおヘッドステヌタスを取埗したした。

Arduinoは、このアむデアを実装するためのプラットフォヌムずしお遞ばれたした。 理由開発されたむンフラストラクチャ、倚くの䟋、販売䞭の倚くのコンポヌネント、䟡栌本物のArduinoではなく、䞭囜のミラヌクロヌンに぀いお話す堎合、アクセシビリティEbayの利点は、あらゆる奜みに芋られたす。 原則ずしお、むき出しのコントロヌラヌにも同じこずが実装できたすが、テクノロゞヌを入力しただけなので、既存の゚ントリヌしきい倀を䞊げたくありたせんでした。 唯䞀の気象センサヌは矎的なデバむスではありたせんでしたが、壁に20 cmの盎線サむズのcoをかけたくなかったので、Arduino Pro Miniがベヌスずしお遞択され、いく぀かの印象的なUnoサむズではありたせんでした。



したがっお、抂念的には、システムは4぀の郚分で構成されおいたす。





亀換プロトコル



システムのコンポヌネントの説明に進む前に、プロトコルず空䞭のデヌタ亀換の原理に぀いお簡単に説明したす。 無線亀換は、 VirtualWireラむブラリに基づいおいたす。このラむブラリには、マンチェスタヌコヌディングやチェックサム怜蚌などの「正しい」送信手段が既にありたす。 パケット構造が固定されたマむクロプロトコルが、このラむブラリの䞊に実装されたした。 各パケットは、送信デバむスのアドレスuint16、センサヌのタむプint16、およびデヌタfloatの3぀のフィヌルドで構成されおいたす。 远加のセキュリティ察策がサヌバヌ偎で実装されおいるため、パケットの長さをチェックするこずを陀いお、着信デヌタの正確性に関する远加の怜蚌はありたせん。 送信デバむスのアドレスは、デバむスがオンになったずきに、以前に生成されおいない堎合はランダムに生成され、EEPROMに蚘録されたす。 各デバむスには、さたざたなタむプのセンサヌの倚くの読み取り倀を任意に送信する暩利がありたす。 そのため、各気象センサヌは2぀のパケットを送信したす-枩床枬定倀ず湿床枬定倀を持぀パケット。

したがっお、䞀般的なバストポロゞを持぀無線ネットワヌクが線成されたすが、衝突怜出や配信保蚌などの高床な機胜はありたせん。 2぀のデバむスが同時にデヌタを送信しようずするず、衝突の結果ずしおデヌタが倱われたす。

マむクロプロトコルの実装は、送信ず受信ずいう2぀の䞻芁なメ゜ッドを含む個別のラむブラリで発行されたした。 他のすべおのメ゜ッドは、たずえば送信デバむスのアドレスを生成するために必芁なサヌビスメ゜ッドです。



ラむブラリの゜ヌスコヌド
// This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // Created by Andrey Filimonov 2014 #ifndef WIRELESSSENSORPIPE_H #define WIRELESSSENSORPIPE_H #if ARDUINO >= 100 #include "Arduino.h" #else #include "WProgram.h" #endif class WirelessSensorPipe { public: enum SensorType { TEMPERATURE = 0, HUMIDITY, PRESSURE, WATERFLOW, HEATERSETPOINT, HEATERFLAMEENABLED, HEATERRWTEMPERATURE, HEATERTARGETROOMTEMPERATURE }; struct Packet { int16_t id; SensorType type; float value; }; private: Packet data; int16_t _id; public: void begin(uint16_t transmitPin, uint16_t receivePin, uint16_t pttPin = 10, uint16_t eepromAddress = 0); void send(SensorType type, float value); bool receive(Packet& packet, uint16_t timeout = 30000); int16_t id() {return _id;}; private: void EEPROMWriteInt(int p_address, int16_t p_value); int16_t EEPROMReadInt(int p_address); }; #endif
      
      





 // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // Created by Andrey Filimonov 2014 #include "WirelessSensorPipe.h" #include "VirtualWire.h" #include "EEPROM.h" //#define DEBUG void WirelessSensorPipe::EEPROMWriteInt(int p_address, int16_t p_value) { byte lowByte = ((p_value >> 0) & 0xFF); byte highByte = ((p_value >> 8) & 0xFF); EEPROM.write(p_address, lowByte); EEPROM.write(p_address + 1, highByte); } int16_t WirelessSensorPipe::EEPROMReadInt(int p_address) { byte lowByte = EEPROM.read(p_address); byte highByte = EEPROM.read(p_address + 1); return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00); } void WirelessSensorPipe::begin(uint16_t transmitPin, uint16_t receivePin, uint16_t pttPin, uint16_t eepromAddress) { // Initialise the IO and ISR vw_set_rx_pin(receivePin); vw_set_tx_pin(transmitPin); vw_set_ptt_pin(pttPin); vw_setup(256); // Bits per sec vw_rx_start(); // Start the receiver PLL running _id = EEPROMReadInt(eepromAddress); if (_id <= 10000) { randomSeed(analogRead(0)); _id = random(10000, 60000); EEPROMWriteInt(eepromAddress, _id); } } void WirelessSensorPipe::send(SensorType type, float value) { data.id = _id; data.type = type; data.value = value; vw_send((uint8_t *)&data, sizeof(Packet)); vw_wait_tx(); // Wait until the whole message is gone } bool WirelessSensorPipe::receive(Packet& packet, uint16_t timeout) { bool result = false; uint8_t message_length = sizeof(Packet); if (vw_wait_rx_max(timeout) && vw_get_message((uint8_t*)&data, &message_length) && message_length == sizeof(Packet)) { packet.id = data.id; packet.type = data.type; packet.value = data.value; result = true; } return result; }
      
      









気象センサヌ



倩気センサヌの䜜成は簡単に思えたした。 既存のMKこれはArduino Pro Miniの䞀郚ずしおATMega328であるこずを思い出したすで枩床ず湿床センサヌプロゞェクトではDHT11でしたをフックし、433 MHz OOKトランスミッタヌをフックし、センサヌからデヌタをポンプし、トランスミッタヌにアップロヌドする゜フトりェアポンプを䜜成し、それだけですできた。 DHT11をArduinoに接続する方法に぀いおは説明したせん。この皮の資料は、Habré http://habrahabr.ru/post/171525/、http://habrahabr.ru/post/184966/ を含めおいっぱいです。 OOKトランスミッタヌを433 MHzで接続するこずも問題ではありたせん http://habrahabr.ru/post/210830/ 。 Adafruit DHTラむブラリは、デヌタの取埗に䜿甚されたすラむブラリのセットは、 https  //github.com/adafruitにありたす 。 コミュニケヌションの線成には、説明されおいるマむクロプロトコルが䜿甚されたす。



完璧䞻矩ぞの枇望のためではないにしおも、すべおがシンプルになりたす。 事実は、センサヌはバッテリヌで動䜜しなければならず、長時間動䜜するずいう信念は脳に根ざしおいるずいうこずです。 そしお、ここで埅ち䌏せが行われたした。Arduinoが元の状態で、アクションが取られなかった堎合、玄50mAを消費するためです。 䞀般的なAAAバッテリヌの楜芳的な容量は1200mAhです。 この食欲により、バッテリヌのセットは24時間持続したす。 すべおのセンサヌのバッテリヌを1日に1回亀換するずいう考えは熱意を匕き起こさなかったので、Atmelのコントロヌラヌの省電力モヌドを研究しお、すべおを詊したした。 ゜フトりェアのトリックに加えお、呚蟺機噚、぀たりDHT11ずトランスミッタヌで䜕かをする必芁がありたした。 バッテリヌが絶えず消耗しないように、+ 5Vを電源バスではなく、別のArduino脚に接続するこずにしたした。 これにより、必芁な堎合にのみ呚蟺機噚を含めるこずができたす。 たた、気象デヌタを5分に1回以䞊送信するのは意味がないため、呚蟺機噚も5分に1回、数秒間必芁です。 仕様によるず、ATmega328はピンを介しお40mAを䟛絊するこずができたすが、䞀方で、トランスミッタヌの消費は30mA、DHT11の消費ははるかに少なく、同時に動䜜するこずはありたせん。センサヌからのデヌタが最初に読み取られ、送信されたす。 したがっお、40mAで十分です。 芁玄するず、デバむスには3぀のコンシュヌマヌがありたす。

  1. 呚蟺機噚実質的には別のレッグから電源䟛絊されたす
  2. マむクロコントロヌラヌ自䜓ここでは、省゚ネに察凊する必芁がありたす
  3. Arduinoボヌド䞊の䞍必芁な呚蟺機噚たずえば、電源の存圚を瀺すLED


+ 6.5V ... 12Vから5VのLEDおよび電圧コンバヌタヌは、Arduinoボヌド䞊にあり、12Vを超えお䜕かに電力を䟛絊したい堎合に必芁です。センサヌは3぀のバッテリヌから電力を䟛絊されるため、すぐに切断されたした。合蚈電圧が3.7V ... 5.1VのAAA鮮床の皋床によるであるため、降圧コンバヌタヌは圹に立ちたせん。 LEDは私にずっおも圹に立たない、ずにかく誰もケヌスの䞭にそれを芋たせん。 䞇歳、手術により食欲がほが半分に枛少したした-最倧28mA。 しかし、これはただたくさんありたす。 枬定時たでに、呚蟺電源はすでにMKフットから䟛絊されおおり、その時点でオフになっおいたため、28mAがコントロヌラヌ自䜓の食欲であるず結論付けられたした。 ゜フトりェアのみゞャムできたす。 倚くの指瀺ずマニュアルが読たれたした。 この知識には最も倚くの知識が含たれおいたす。 省゚ネの詊緎をスキップするず、りォッチドッグタむマヌがトリガヌされたずきに終了する省゚ネモヌドSLEEP_MODE_PWR_DOWNを含めるこず、アナログ-デゞタルコンバヌタヌがオフになるこず、蚱容できない䜎電源電圧での動䜜モヌドの怜出いわゆるブラりンアりトモヌドが最も助けになったず蚀えたす。 私のリストの最初の2぀のポむントだけを管理しお゚ネルギヌ倪った人を無酞玠状態にした堎合、消費量は玄20uAになりたす。 これは元の28mAよりも1000倍小さく、原則ずしおそこで停止できたすが、ATmega328デヌタシヌトには、マむクロコントロヌラが䜕かでビゞヌでないずき、1uA未満しか消費できないず曞かれおいたす

MCの内郚では、電源電圧の䜎䞋に察するデバむスの応答が異なりたす。 そのため、䟛絊電圧が䜎䞋するず、氎晶の䞻芁郚分が動䜜し、䞀郚のデバむスが正垞に動䜜しない、䞍安定になる、たたは正垞に動䜜しないずいう状況が発生する可胜性がありたす。 このような鉄の䞍敎合を回避するために、MCは電源電圧の臚界レベル以䞋の䜎䞋を怜出し、完党にオフにするこずができたす。 ただし、この機胜は刀明したずおり、非垞に倧きなパワヌを必芁ずしたす。 ブラりンアりトを無効にするず、マむクロアンペア電流を枬定するモヌドの私の䞭囜のマルチメヌタDT838は、䜕も感じないこずを瀺したした。 ここにある 電流が1uA未満になったずは蚀えたせんが、マむクロ電流蚈の感床しきい倀よりも確実に小さくなりたした。これは確かに20uA未満です。 枬定の粟床がそれ以䞊のトレヌニングを蚱可しなかったため、結果を満足のいくものずみなし、゚ネルギヌ消費に関する研究を終了するこずが決定されたした。

そのため、センサヌが組み立おられ、コヌドが内郚に瞫い付けられたす。これは、5分ごずにオンになり、残りの時間はディヌプスリヌプになる同じポンプを実装しおいたす。 ブレッドボヌドでは、送信されたデヌタの受信機がホむップアップされたした。 すべおがパワヌアップされ、...省略蚘号の埌、通垞は予期しない叙事詩ファむルを曞き蟌みたすが、いや、すべおがスムヌズに進み、テストレシヌバヌはデヌタを受信し始め、デヌタは完党に適切に芋えたした枩床-25床、湿床-40。 ほら、仲間 ゞョブが完了したした。 興味深いこずに、フィヌルド条件に近い条件にデバむスを配眮するこず、぀たり、送信機ず受信機の間の距離を10cmから5mに増やすこずが決定されたした。 そしお、ここで叙事詩ファむルは忍び寄った。 5mの距離での盎接芖界の条件では、受信機は䜕も登録したせんでした。 私はそのようなむベントの準備ができおいお、䜕が起こっおいるのか知っおいたず思いたした。 事実は、その時点で受信機も送信機もアンテナを持っおいなかったずいうこずです。 すべおの芏則に埓っお、1察の1/4波長アンテナが即座に枬定され、切断されたした433MHzの堎合、これは玄17.5 cmのワむダであるこずを思い出したす。 導䜓はアンテナず奇跡の代わりに密閉され、送信は完了したした 次のステップは、レシヌバヌずトランスミッタヌの間に厚さ375 mmのケむ酞塩壁を配眮するこずにより、芋通し線をなくすこずです。 たた、トラブル、䌝送、぀たりそうではありたせん。 デバむス、アンテナ、それらの圢状、および内郚の䜍眮に合わせお螊る撚り線、単芯、異なる絶瞁䜓でなぜ䜕にも぀ながりたせんでした。 䌝送速床を途方もない256 bpsに䞋げおも、状況はそれほど改善したせんでした。 アンテナのブランド化を詊みお、攟射線物理孊の分野での私の知識䞍足により、3人が攟射線物理教育に携わりたした。そのうちの1人は物理科孊の候補者です。 すべおの合唱団は、「アンテナはそれずは䜕の関係もない、これらの送信機は、信号が正しく゚ンコヌドされおいれば、アンテナずしお取り付けられたごみず䞀緒に動䜜し、おそらく10メヌトル以内に動䜜しないように䜕か特別なこずをした」 。 VirtualWireがマンチェスタヌコヌドを䜿甚し、その䞊に远加のチェックを加えおいるため、皮肉を噛み砕いおコヌディングが正しいず䞻匵したため、䜕か間違ったこずをする可胜性があるず考え始めたした。 䞀芋明癜に芋えたすが、欠陥のある送信機たたは受信機に出くわしたずいう信じられないほどの仮定をすべお砎棄するず5぀のセットがあり、詊しおみたしたが、結果は同じです、1぀のバヌゞョンしかありたせんでした-私は送信機を完成しおいたせん。 実隓目的のために、MKフットから+ 5Vバスず送信機に送信機の電力を転送したした。受信機にデヌタがありたす。 さらに、アンテナの䜍眮、アンテナの構成、受信機ず送信機が家のどこにあるかに関係なく、それらはそこにありたす。 䌝送を䞭断するこずができた唯䞀の状況は、送信機を鉄のキャップで芆うこずでしたただし、これはすでに「aaaaa」ずいうシビア人の厳しい男性によるシリヌズです。 さらに、10秒間掗脳したした以前にやったこずがないのはなぜですか。OOKトランスミッタヌは、䜕も送信しないずきに䜕も食べないので、「倖郚」の方法でバッテリヌを保護する意味がありたせん。 トランスミッタヌの電源がMKフットによっお十分に䟛絊されないバヌゞョンの時間。 このテヌマに関する理論を正匏に確認したこずはありたせんが、オシロスコヌプはありたせん。オシロスコヌプはありたせん。正確に芋぀けるこずはおそらく䞍可胜ですが、そのような有効な仮説です。 勇敢な䞭囜人によっお送信機に宣蚀された30mAは、䜕を意味しおもかたいたせん。 たずえば、テストシヌケンスを送信するずきの平均消費量。 同時に、ナニットの転送䞭のピヌク消費は、40mA以䞊を含め、䜕でもかたいたせん。 䞀方、MK出力甚に宣蚀された40mAは正確に䞊限であり、それを超えるず䜕も保蚌されないず確信しおいたす。 そのため、トランスミッタのピヌク消費量は、MKの胜力を簡単に超える可胜性がありたす。 センサヌを蚭蚈する2週間圓初は数日が蚈画されおいたしたのうち、送信機の問題を解決するために時間の90を費やしたこずは泚目に倀したす。

ささいな電気回路は次のようになりたす。

画像

センサヌ゜ヌスコヌド
 #include <avr/sleep.h> #include <avr/wdt.h> #include <DHT.h> #include <VirtualWire.h> //workaround for the stupid arduino problem of not being able to include a library from another library, so i'm including the libs needed by WSP here #include <EEPROM.h> #include <WirelessSensorPipe.h> //#define DEBUG #define KIDROOM //#define OUTDOOR /* hardware configuration */ #define ACCESSORIESPOWERPIN 3 #define DHTPIN 4 #define TRANSMITPIN 2 #if defined (KIDROOM) #define DHTTYPE DHT22 #define TCORRECTION (0) #define HCORRECTION (0) #elif defined (OUTDOOR) #define DHTTYPE DHT22 #define TCORRECTION (0) #define HCORRECTION (0) #endif #ifdef DEBUG #define SLEEPDURATION 0 //sleep duration in seconds, shall be a factor of 8 #else #define SLEEPDURATION 320 //sleep duration in seconds, shall be a factor of 8 #endif DHT dht(DHTPIN, DHTTYPE); void sleepFor8Secs() { // disable ADC ADCSRA = 0; // clear various "reset" flags MCUSR = 0; // allow changes, disable reset WDTCSR = bit (WDCE) | bit (WDE); // set interrupt mode and an interval WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); // set WDIE, and 8 seconds delay wdt_reset(); // pat the dog set_sleep_mode (SLEEP_MODE_PWR_DOWN); sleep_enable(); // turn off brown-out enable in software MCUCR = bit (BODS) | bit (BODSE); MCUCR = bit (BODS); sleep_cpu (); // cancel sleep as a precaution sleep_disable(); } // watchdog interrupt ISR (WDT_vect) { wdt_disable(); // disable watchdog } // end of WDT_vect WirelessSensorPipe pipe; void setup () { #ifdef DEBUG Serial.begin(9600); Serial.println("Entered setup"); #endif dht.begin(); pinMode(ACCESSORIESPOWERPIN, OUTPUT); pipe.begin(TRANSMITPIN, 0); #ifdef DEBUG Serial.print("Sensor id:"); Serial.print(pipe.id()); #endif } void loop() { pinMode(ACCESSORIESPOWERPIN, OUTPUT); digitalWrite(ACCESSORIESPOWERPIN, HIGH); //turn on the DHT sensor and the transmitter delay(2000); //sleep till the intermediate processes in the accessories are settled down float humidity = dht.readHumidity() + HCORRECTION; float temperature = dht.readTemperature() + TCORRECTION; digitalWrite(ACCESSORIESPOWERPIN, LOW); // turn off the accessories power pinMode(ACCESSORIESPOWERPIN, INPUT); //change pin mode to reduce power consumption #ifdef DEBUG Serial.print("Humidity: "); Serial.println(humidity); Serial.print("Temperature: "); Serial.println(temperature); /* blink the LED to indicate that the readings are done */ digitalWrite(13, HIGH); delay(100); digitalWrite(13, LOW); #endif pipe.send(WirelessSensorPipe::TEMPERATURE, temperature); delay(1000); pipe.send(WirelessSensorPipe::HUMIDITY, humidity); for (int i = 0; i < SLEEPDURATION / 8; i++) sleepFor8Secs(); }
      
      







泚意深い読者は、ファヌムりェアがDHTから読み取られたデヌタの修正を導入するこずを可胜にしたこずに気付くでしょう。 実際のずころ、DHT11には倚くの欠点がありたす。すなわち、敎数床の粟床、極端に䜎いキャリブレヌション、枬定から枬定、およびセンサヌからセンサヌぞの結果の再珟性です。 そのため、近くに立っおいる2台のDHT11は2床の枩床差を瀺すこずがありたすが、これは私には適しおいたせんでした。 さらに、次の蚘事のトピックに目を向けるず、私の家はボむラヌで加熱されおいるず蚀いたす。ボむラヌはその瞬間に手で制埡されおいたした。 路䞊の状況に基づいお、目的のボむラヌ出力を蚭定したす。 ほずんどすべおの最新のボむラヌには、少なくずもオン/オフモヌドで制埡する機胜がありたす。 そのため、次のプロゞェクトでは、通りや郚屋で利甚可胜な枩床デヌタを䜿甚しお、宀内環境をサヌモスタットで制埡したす。 この目的のために、郚屋の内郚の枩床をある皋床の粟床で枬定するこずは非垞に無瀌です。そのような無瀌は枩床制埡システムの自励振動に぀ながりたす。 そのため、DHT11を、修正を必芁ずしないはるかに高䟡なDHT22に眮き換えるこずが決定されたした2぀のDHT22、1箇所に立぀ず、読み取り倀は10分の1床たで䞀臎したす。

センサヌ写真
画像

画像

画像





䞭倮ナニット



そのため、気象デヌタはオン゚アで利甚できたす。 問題は、次に䜕をすべきかです。 そしお、それらをキャッチし、HTTPでカプセル化し、既存のホヌムのサヌバヌに転送する必芁がありたす。 これを行うために、䞭倮ナニットにArduino Nano、433MHz超再生レシヌバヌ、ENC28J60むヌサネットモゞュヌルを装備するこずにしたした。 Proボヌドの代わりにNanoを䜿甚するには、Nanoボヌドに3V3コンバヌタヌが必芁であり、ENC28J60は、情報ピンの+ 5Vの蚱容倀にもかかわらず、3V3の電力を必芁ずしたす。

スキヌムは次のようになりたす。

画像

ご芧のように、ENC28J60に加えお、回路には䞭倮ナニットの䜍眮の枩床/湿床を取埗するためのDHTセンサヌ最終的にはDHT22ず、圧力の枬定に䜿甚されるBMP085センサヌも含たれおいたす。 ハヌドりェア実装の機胜のうち、BMP085が異なり、センサヌ自䜓は3V3で駆動されるこずに泚意する䟡倀がありたすが、組み蟌みの5V-> 3V3コンバヌタヌで賌入したため、䞡方の電圧で駆動できたす。 Nanoの堎合、独自のコンバヌタヌがあるため、これは無関係ですが、Pro Miniを䜿甚する堎合は䟿利な機胜になりたす。

ハヌドりェア郚分に驚きはありたせんでしたが、゜フトりェアには驚きたした。 サプラむズはむヌサネットコントロヌラヌに接続されおいたす。 たず、ENC28J60は、むヌサネットシヌルドで広く䜿甚されおいるW5100ずは異なり、TCP / IPハヌドりェア実装を含たず、スタックはプログラムで実装され、このチップで動䜜するラむブラリを備えおいたす。 第二に、コミュニティ䜓隓党䜓はArduinoでのプリミティブHTTPサヌバヌの実装に集䞭しおいたすが、私の仕事は、ArduinoをHTTP GETリク゚ストを介しおサヌバヌにデヌタを送信する「ブラりザ」にするこずです。 このようなブラりザを実装しようずするず、かなりの困難に盎面したした。 むヌサカヌドラむブラリは必芁なこずを行うbrowseUrlメ゜ッドを定矩しおいるにもかかわらず、その動䜜は安定しおいたせん。 メ゜ッド自䜓は、GET芁求を生成するためのラむブラリぞの芁求のみを意味したす。 芁求自䜓を実行するには、サヌバヌからデヌタを受信したずきに呌び出されるコヌルバックメ゜ッドを定矩し、browseURLを呌び出した埌、盎接トラフィックをポンピングするpacketLoopメ゜ッドを呌び出す必芁がありたす。 したがっお、理論的には、メッセヌゞを送信する䜜業は、browseUrlぞの単䞀の呌び出しず、芁求をポンピングしお応答を受信するpacketLoopぞの耇数の呌び出しの2぀の段階で構成されたす。 packetLoopを䜕回プルする必芁があるかは完党に理解できたせん。 このメ゜ッドはステヌタスを返したせん。 入力は、パケットの長さを受け入れたす。これは、packetReceiveメ゜ッドを呌び出すこずで決定できたす。 私が最初に考えたのは、packetReceiveがれロ以倖を返すたでpacketReceiveずpacketLoopをプルするこずでした。 ただし、たず、browseUrlを呌び出した盎埌に、倚くのpacketReceive呌び出しがれロを返したす。 第二に、最初の非れロが出珟した埌、䞀連のれロが移動し、再びれロではなくなりたす。 サヌバヌからの回答は私には興味がないので、䞻な問題は、サヌバヌぞのGETリク゚ストを取埗するために必芁な回数だけpacketLoopを呌び出すこずです。反察方向の転送はスキップされたす。 ここでコヌルバックが圹立ちたした。これは、デヌタがENC28J60バッファに衚瀺されるずきにむヌサカヌドが呌び出すものです。 最初の呌び出しを埅っお、サヌバヌぞの転送が行われ、転送が反察方向に開始されたこずを確認するだけで十分です。 その埌、packetLoop呌び出しを終了できたす。 問題は、コヌルバックがbrowseUrlの埌に呌び出されない堎合があり、その埌packetLoop呌び出しのルヌプで氞久に呌び出される堎合があるこずです。 この手順を時間に制限する必芁がありたした。 Arduinoが5秒以内にサヌバヌから応答を受信しない堎合、珟圚の芁求詊行をスロヌしたす。 別の非垞に䞍快な驚きは、時々送信されたす非垞に䞍安定に再珟されたすが、確実に1日に1回発生したすタンデムENC28J60 /むヌサカヌドは、䜕も送受信されない堎合に安定状態になりたす。 MKを再起動するこずで凊理されたす。 そのため、転送に倱敗した詊行を怜蚎し、それらが倧量に蓄積した堎合、コントロヌラヌを匷制的にオヌバヌロヌドする必芁がありたした。

これらすべおのトリックにより、䞭倮ナニットは安定しお動䜜したす。私は珟圚、1か月間、その動䜜に干枉しおいたせん。

䞭倮ナニットのスケッチ
 #include <Wire.h> #include <DHT.h> #include <VirtualWire.h> #include <EtherCard.h> #include <EEPROM.h> #include <Time.h> #include <WirelessSensorPipe.h> #include <Adafruit_BMP085.h> #define DEBUG /* Hardware configuration */ #define RECEIVEPIN 2 #define DHTPIN 4 #define DHTTYPE DHT22 /* Sensor corrections */ #define TCORRECTION (0) #define HCORRECTION (0) /* Timeouts */ #define RECEIVETIMEOUT 30 // wireless receive timeout #define MEASUREUPDATEPERIOD 300 //self measuring period /* Own sensors */ DHT dht(DHTPIN, DHTTYPE); Adafruit_BMP085 bmp; /*Sensor pipe*/ WirelessSensorPipe pipe; /* Ethercard stuff */ #define BUFFER_SIZE 400 byte Ethernet::buffer[BUFFER_SIZE]; #define FAILEDSENDATTEMPTSALLOWED 10 //if it fails to send data more than FAILEDSENDATTEMPTSALLOWED attempts the reboot is forced static uint8_t mymac[6] = { 0x54,0x55,0x58,0x12,0x34,0x56 }; char PROGMEM websrvip_str[] = "192.168.1.250"; byte answer_received = 0; // called when the client request is complete static void my_callback (byte status, word off, word len) { #ifdef DEBUG Serial.print(F("HTTP GET status: ")); Serial.println(status); // Ethernet::buffer[off+300] = 0; // Serial.print((const char*) Ethernet::buffer + off); #endif answer_received = 1; } void(* resetFunc) (void) = 0; int num_of_failed_send_requests = 0; void sendSensorData(int sensor_id, int sensor_type, float data) { char buffer[40]; char conv_buffer[11]; buffer[0] = 0; strcat_P(buffer, PSTR("?script=updS")); strcat_P(buffer, PSTR("&id=")); strcat(buffer, itoa(sensor_id, conv_buffer, 10)); strcat_P(buffer, PSTR("&t=")); strcat(buffer, itoa(sensor_type, conv_buffer, 10)); strcat_P(buffer, PSTR("&v=")); strcat(buffer, dtostrf(data, 2, 2, conv_buffer)); #ifdef DEBUG Serial.print(hour()); Serial.print(":"); Serial.print(minute()); Serial.print(":"); Serial.print(second()); Serial.print(" :"); Serial.print(F("Sending request with params: ")); Serial.println(buffer); #endif answer_received = 0; ether.browseUrl(PSTR("/objects/"), buffer, websrvip_str, &my_callback); int packet_len = 1; int begin_waiting_time = now(); while(!answer_received || packet_len != 0) { packet_len = ether.packetReceive(); ether.packetLoop(packet_len); if (now() - begin_waiting_time > 5) { num_of_failed_send_requests++; Serial.print(F("Failed to send data ")); Serial.print(num_of_failed_send_requests); Serial.println(F(" times")); if (num_of_failed_send_requests >= FAILEDSENDATTEMPTSALLOWED) { Serial.println(F("Resetting the device")); resetFunc(); } break; } } } void setup () { #ifdef DEBUG Serial.begin(9600); Serial.println(F("Entered setup")); #endif pipe.begin(0, RECEIVEPIN); #ifdef DEBUG Serial.print("Sensor id:"); Serial.println(pipe.id()); #endif dht.begin(); bmp.begin(); if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) { Serial.println(F("Failed to access Ethernet controller")); resetFunc(); } if (!ether.dhcpSetup()) { Serial.println(F("DHCP failed")); resetFunc(); } ether.printIp(F("IP: "), ether.myip); ether.printIp(F("GW: "), ether.gwip); ether.printIp(F("DNS: "), ether.dnsip); if (!ether.dnsLookup(websrvip_str)) { Serial.println(F("DNS failed")); resetFunc(); } ether.printIp(F("SRV: "), ether.hisip); } time_t previous_measure_time = -1; void loop() { time_t current_time = now(); if(current_time - previous_measure_time > MEASUREUPDATEPERIOD) { float dhttemperature = dht.readTemperature() + TCORRECTION; float humidity = dht.readHumidity() + HCORRECTION; float temperature = bmp.readTemperature(); float pressure = bmp.readPressure()/133.33; sendSensorData(pipe.id(), 500, temperature); sendSensorData(pipe.id(), WirelessSensorPipe::TEMPERATURE, dhttemperature); sendSensorData(pipe.id(), WirelessSensorPipe::HUMIDITY, humidity); sendSensorData(pipe.id(), WirelessSensorPipe::PRESSURE, pressure); previous_measure_time = current_time; } WirelessSensorPipe::Packet packet; if (pipe.receive(packet, RECEIVETIMEOUT * 1000)) { sendSensorData(packet.id, packet.type, packet.value); } }
      
      







完成したデバむスの写真
画像

画像



ご芧のずおり、DHT22は偎面にぶら䞋がり、ケヌスに配眮するこずはできたせん。さらに、ケヌス内に配眮するこずはできたせん。デバむスは、枩床センサヌを配眮するのに十分な少量の熱を生成するためです。䟋ずしお、ケヌス内にあるBMP085センサヌの枩床枬定倀は、正しい倀より2床安定しおいたす。



サヌバヌ偎



埌で衚瀺する数字を保存するためのものを䜜成するずきに頭に浮かぶ最初の考えは、おそらくこのホむヌルを発明しようずしおいる最初の人ではないでしょう。むンタヌネットの簡単な調査は、゜リュヌションの範囲が「プログラマヌのchtoliではなく、䜕から」ず非垞に広いこずを瀺したした。ここにあなたのVisualBasicがあり、それをプログラムし、ここで、ここで少し調敎しお、すべおが箱から出しお動䜜したす。真実は、い぀ものように、䞭間のどこかにありたす。䞀方では、すべおを矎しく行うためには、コヌドに培底的に投資する必芁があり、熱意を簡単に消すこずができるこずは明らかです。䞀方、ボックス化された゜リュヌションは、圌らが望むものを決しお実行したせん、圌らはカスタマむズに欠けおいたす。 Majordomosmartliving.ruずいう玠晎らしいプロゞェクトがあり、その目的はスマヌトホヌム甚のプラットフォヌムを䜜成するこずであるずいう事実に、私はゆっくりず導かれたした。「なぜ十分に賢い気象芳枬所がスマヌトホヌムの䞀郚ではないのですか」私は考えお座っお問題を研究したした。 Majordomo IMHOの矎しさは、非垞にシンプルで兞型的なものが、少しカスタマむズしおすぐに䜿甚できるこずです。しかし、䜕か気に入らない堎合は、远加するPHPによく開発されたスクリプトツヌルがあるためか、曞き盎すプラットフォヌムが開いおいる、゜ヌスコヌドが利甚できる機䌚が垞にありたす。 Majordomoでサポヌトされおいるツヌルのうち、オブゞェクトは有甚であり、HTTPリク゚ストずホヌムペヌゞを介しお倖郚から曎新できるデヌタで、HTML / JS / CSSおよびその他のWebテクノロゞヌ動物園で奜きなものを描画しおサポヌトできたす。しかし、䜕か気に入らない堎合は、远加するPHPによく開発されたスクリプトツヌルがあるためか、曞き盎すプラットフォヌムが開いおいる、゜ヌスコヌドが利甚できる機䌚が垞にありたす。 Majordomoでサポヌトされおいるツヌルのうち、オブゞェクトは有甚であり、HTTPリク゚ストずホヌムペヌゞを介しお倖郚から曎新できるデヌタで、HTML / JS / CSSおよびその他のWebテクノロゞヌ動物園で奜きなものを描画しおサポヌトできたす。しかし、䜕か気に入らない堎合は、远加するPHPによく開発されたスクリプトツヌルがあるためか、曞き盎すプラットフォヌムが開いおいる、゜ヌスコヌドが利甚できる機䌚が垞にありたす。 Majordomoでサポヌトされおいるツヌルのうち、オブゞェクトは有甚であり、HTTPリク゚ストずホヌムペヌゞを介しお倖郚から曎新できるデヌタで、HTML / JS / CSSおよびその他のWebテクノロゞヌ動物園で奜きなものを描画しおサポヌトできたす。

Arduinoのセンサヌ甚に、次の構造を持぀オブゞェクトの個別のクラスが線成されたした

画像

。DeviceIDは、マむクロプロトコルパケットに参加するデバむスのたさにアドレスです。残りのフィヌルドの説明は、それ自䜓を物語っおいたす。䜜業のロゞックは次のずおりです。

䞭倮ナニットがデヌタを送信するず、このクラスのオブゞェクトの䞭で、DeviceIDずSensorTypeが送信されたものず䞀臎するものが怜玢されたす。芋぀かったオブゞェクトに察しお、枡された倀microprotocolパケットのfloatフィヌルドの倀が蚭定され、UpdateTimeがNowに蚭定され、Actualが1に蚭定されたす。䞭倮ナニットたたはセンサヌ自䜓に䜕かが起こった堎合、センサヌは長時間曎新されおいないため、センサヌは無関係です。そのようなセンサヌがいく぀かありたす。

画像

これらのセンサヌの倀は、ホヌムペヌゞを䜿甚しお芖芚化されたす。異なるペヌゞを䜿甚しお、異なるデヌタたたは同じデヌタを、異なるデバむスでの衚瀺に最適化された圢匏で衚瀺したした。



ディスプレむデバむス



かなりの量のほこりで芆われた叀いDell Streak 5は、䞭倮ディスプレむデバむスずしお䜿甚されたした。[ディスプレむデバむスの遞択を含む段萜の蚘事の冒頭を参照]は、Arduinoに盎接ねじ蟌たれた1.8たたは2.2むンチスクリヌンよりもはるかに有益です最倧でテキストず8x8アむコンを衚瀺できたす。Dolphinブラりザを開始時に自動実行するようにセットアップされ、気象ペヌゞが開き、気象ステヌションの準備が敎った顔になりたした気象ステヌションだけでなく、枩床制埡に関する今埌の蚘事を再び発衚したす。察応するMajordomoホヌムペヌゞのテキストでは、ブラりザヌをフルスクリヌンモヌドにし、アドレスバヌやAndroidステヌタスバヌなどの䜙分なものをすべお隠すトリックに頌らなければならなかったこずに泚意しおください。

さらに、子䟛郚屋の気候状況を監芖するために、デヌタは䞻に配偶者によっおiPhoneおよびiPadで衚瀺されたす。

写真のこの技術的な寄せ集めの結果
Dell Streak:

画像



Streak:

画像



12 , :

画像



iPhone:

画像





テスト、結論、蚈画



珟圚たでに、システムは玄1か月半皌働しおいたす。 ENC28J60が完党にオフになっおいるリンクLEDずアクティビティLEDが点灯しなかった䞭倮ナニットが2回ホバリングするこずを陀いお、特に䞍満はありたせん。数秒間、ナニットの電源を切るこずで察凊したした。この振る舞いの理由は、家の車内ネットワヌクの電気の質があたり良くないこずが蚘録されおいたした。䞀瞬のうちに消えたす。このような条件䞋で電子機噚がどのように動䜜するかは䞍明です。この芁因の圱響を防ぐ手段ずしお、1Fに2぀のむオニスタ5Vコントロヌラの電源甚、むヌサネットアダプタ甚の3V3を蚭眮するこずが蚈画されおいたした。蓄電池をバッテリヌの圢で管理するこずは可胜でしたが、はるかに高䟡ですむオニスタのコストは数十ルヌブル、通垞のバッテリヌセットは500ドルかかりたすが、それはおもしろくありたせんバッテリヌを䜕床も芋たしたが、初めおむオン怜出噚を目にしたす、目暙を達成したせん目暙はネットワヌク内の短期の厄介な秒数の圱響を防ぐこずであり、電気がない状態でナニットに電力を䟛絊しないためです 

結論では、腺のセットはそのタスクに察凊し、次の方向に拡匵するための準備ができおいるず曞くこずができたす



近い将来の抂芁は次のずおりです。




All Articles