Arduinoホーム気象ステーション

導入する代わりに



ほとんどの労働者と同様に、自分のプロジェクトに従事することは、残りの唯一の自由時間を占めます。 そのため、私は長い間、何かをするために作成せず、「手をitchいた」。 この機会は奇妙に大学に現れました。 窓の外は、4年の9月であり、回路に関する差し迫ったコースです。 授業は、紙とハードウェアの2つのバリエーションで行うことができると言われました。



5年間、私たちの大学での紙の授業は「古いものを取りまとめて」という原則に基づいて行われました。 このアプローチはそのルーチンには適していないため、すぐにハードウェアのコースを選択しました。 Arduinoマイクロコントローラーは、学習が容易なため、授業の中心として提案されました。 コースワークのタイプを決定した後、もう1つの質問がありました。正確に何を行うかです。 マイクロコントローラのプログラミングの経験がなかったため、すぐにGoogleを開き、既存のプロジェクトの研究を始めました。 多くのプロジェクトがあり、そのうちのいくつかは非常に単純で、いくつかは素晴らしいものです(たとえば、3Dスキャナー)が、大部分は実用的ではありませんでした。 そして、私は棚の上に横たわり、そこにほこりを集めないものを正確に望みました。 Arduinoの世界に30分かけて行った後、自宅の気象観測所のトピックに興味があり、プロジェクトの実装はそれほど難しくないようでした(基本的に新参者を買収しました)。



それがコースのトピックが選ばれた方法であり、時間の経過とともに問題が概説されていないようでした。



コンポーネントの選択



さまざまなプロジェクトを見て、NanoまたはPro Miniで十分だと気づきましたが、Arduinoのプログラミングを希望し、将来は他のプロジェクトを実装することを期待してArduino Unoを選択しました。 はんだごては手に持ったことがないので、開発を容易にするために、Sensor Shield v4も購入することにしました。



詳細
このボードは、センサー、モジュール、サーボモーター、シリアルおよびI2Cインターフェースの迅速な接続を容易にし、Duemilanova / Unoフォームファクターコントローラーのすべてのポートも表示します(メガシリーズにも接続できますが、制限と結果があります)。 それ自体の上に他のシールドをサポートします。











気象データのソースとして次のセンサーを選択しました。



  1. BMP180圧力および温度センサー:



    詳細
    BMP180は、BMP085をさらに発展させたものです。 BMP180はサイズが小さくなり、消費電力が少なくなり、センサーの精度と安定性が向上しました。



    画像BMP180




    圧力測定範囲 300-1100 GPa
    圧力測定エラー 0.06 GPa(省エネモード)、0.02 GPa(高精度モード)
    高度精度 0.5メートル(省電力モード)、0.17メートル(高精度モード)
    絶対測定精度(p = 300.1100 GPa、t = 0..65 C 0 、電源3.3 V) 圧力:-4.0 ... + 2.0 GPa温度:±1 C 0
    平均消費電流(1 Hzのデータリフレッシュレートで) 3μA-省電力モード、32μA-拡張モード
    最大電流 650μA
    圧力測定時間 5 ms(通常モード)
    データレート 最大3.4 MHz




  2. DHT22温湿度センサー

    詳細
    温度および湿度センサーDHT-22(AM2302)は、その高い精度と湿度および温度の測定範囲においてDHT-11センサーとは異なります。 湿度と温度のアナログ値を変換するためのADC(アナログ-デジタルコンバーター)が含まれています。 センサーをマイクロコントローラーに接続するときは、VCCとSDA端子間に10 kOhmのプルアップ抵抗、および電源とグランド間に100 nFの容量のコンデンサを配置することをお勧めします。 しかし、何もはんだ付けする必要はなかったので、コンデンサと抵抗器を備えたボードにはんだ付けされたセンサーを見つけました。



    DHT22の画像








    供給電圧 3.3-5 V
    湿度測定範囲 2-5%の精度で0-100%
    温度測定範囲 -40-+ 125 C 0 ±0.5 C 0の精度
    センサーのポーリング頻度 2秒ごと以下




  3. 光センサーBH1750(ここでは脚のはんだ付け中にトラックの1つを燃やしたため、ここでは考慮しません)。



    BH1750の写真










センサーを決定しました。 しかし、センサーからのデータをどうするか。 展示することにしました。 カラー写真が欲しかったので、すぐにモノクロのソリューションを削除しました。 数分の検索の後、1.8インチのST7735 TFTディスプレイが選択されました。



詳細
ディスプレイは通信に4線SPIプロトコルを使用し、独自のピクセルアドレス可能なフレームバッファーを備えているため、あらゆる種類のマイクロコントローラーで使用できます。 1.8インチディスプレイには128x160カラーピクセルがあります。 microSDメモリカード用のスロットもあるため、microSDカードのFAT16 / FAT32ファイルシステムからフルカラーのビットマップイメージを簡単にダウンロードできます。



特徴:



  • 対角表示-1.8インチ、解像度128x160ピクセル、18ビットカラー(262,144色)
  • ピクセルメモリアドレッシングが統合されたコントローラー
  • 内蔵microSDスロット-2本以上のデジタルラインを使用
  • 3.3および5Vに対応
  • 寸法:34 mm x 56 mm x 6.5 m










Arduinoコントローラーのプログラミング



気象ステーションのコンポーネントを決定したら、コントローラーのプログラミングを開始します。 Arduinoファームウェアの場合、Arduino IDE開発環境が使用されました。 Adafruitのライブラリも使用しました。



スケッチに進む前に、機能を検討します。





スケッチ
#include <Wire.h> // library for communication with I2C devices #include <Adafruit_Sensor.h> // Core library for all sensors #include <Adafruit_BMP085_U.h> // library for BMP180 #include <Adafruit_GFX.h> // Core graphics library #include <Adafruit_ST7735.h> // Hardware-specific library #include <SPI.h> // library for communication with SPI devices #include "dht.h" // library for DHT #define DHT22_PIN 2 // connect data pin of DHT22 to 2 digital pin #define TFT_CS 10 // connect CS pin of TFT to 10 digital pin #define TFT_RST 9 // connect RST pin of TFT to 9 digital pin // you can also connect this to the Arduino reset // in which case, set this #define pin to 0! #define TFT_DC 8 // connect DC pin of TFT to 8 digital pin Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); //initialize TFT #define TFT_SCLK 13 // connect SCLK pin of TFT to 13 digital pin #define TFT_MOSI 11 // connect MOSI pin of TFT to 11 digital pin dht DHT; Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10085); //initialize BMP180 int bmpFlag = 0; struct { uint32_t total; uint32_t ok; uint32_t crc_error; uint32_t time_out; uint32_t connect; uint32_t ack_l; uint32_t ack_h; uint32_t unknown; } stat = { 0,0,0,0,0,0,0,0}; // struct for dht status void setup(void) { Serial.begin(9600); Serial.println("Meteo Test"); Serial.println(""); if(!bmp.begin()) // check connection for BMP180 { Serial.print("Ooops, no BMP180 detected ... Check your wiring or I2C ADDR!"); bmpFlag = 1; } tft.initR(INITR_BLACKTAB); // Initialize TFT and fill with black color tft.fillScreen(ST7735_BLACK); tft.setRotation(tft.getRotation() + 1); tft.setTextSize(1.5); delay(500); // delay in order to ensure that TFT was initialized } // last measured data float oldTemperature = 0, oldAltitude = 0, oldPressure = 0, oldDHTHumidity = 0, oldDHTTemperature; bool wasUpdate = false; void loop(void) { if(Serial.available() > 0) // we have data is Serial port { Serial.read(); // read byte from serial port and send last measured data printValue("Pressure", oldPressure, " hPa", false); printValue("Temperature", oldTemperature, " C", false); printValue("Altitude", oldAltitude, " m", false); printValue("Humidity", oldDHTHumidity, "%", false); printValue("DHT_temperature", oldDHTTemperature, " C", false); Serial.println("END_TRANSMISSION"); } sensors_event_t event; float temperature, altitude; if(bmpFlag == 0){ bmp.getEvent(&event); // get data from BMP180 if (event.pressure) { bmp.getTemperature(&temperature); float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA; altitude = bmp.pressureToAltitude(seaLevelPressure, event.pressure, temperature); } else { Serial.println("Sensor error"); } } uint32_t start = micros(); int chk = DHT.read22(DHT22_PIN);// get data from DHT22 uint32_t stop = micros(); stat.total++; switch (chk) // check status of DHT22 { case DHTLIB_OK: stat.ok++; break; case DHTLIB_ERROR_CHECKSUM: stat.crc_error++; Serial.print("Checksum error,\t"); break; case DHTLIB_ERROR_TIMEOUT: stat.time_out++; Serial.print("Time out error,\t"); break; case DHTLIB_ERROR_CONNECT: stat.connect++; Serial.print("Connect error,\t"); break; case DHTLIB_ERROR_ACK_L: stat.ack_l++; Serial.print("Ack Low error,\t"); break; case DHTLIB_ERROR_ACK_H: stat.ack_h++; Serial.print("Ack High error,\t"); break; default: stat.unknown++; Serial.print("Unknown error,\t"); break; } if(bmpFlag != 0 || !event.pressure) // update data { tft.fillRect(0, 30, 160, 6, ST7735_BLACK); tft.setCursor(0, 30); tft.setTextColor(ST7735_RED); printValue("ERROR BMP INITIALIZATION", 0, "", true); } else { if(event.pressure != oldPressure) { tft.fillRect(0, 30, 160, 7, ST7735_BLACK); tft.setCursor(0, 30); tft.setTextColor(ST7735_RED); printValue("Pressure", event.pressure, " hPa", true); oldPressure = event.pressure; wasUpdate = true; } if(temperature != oldTemperature) { tft.fillRect(0, 38, 160, 7, ST7735_BLACK); tft.setCursor(0, 38); tft.setTextColor(ST7735_WHITE); printValue("Temperature", temperature, " C", true); oldTemperature = temperature; wasUpdate = true; } if(altitude != oldAltitude) { tft.fillRect(0, 46, 160, 7, ST7735_BLACK); tft.setCursor(0, 46); tft.setTextColor(ST7735_BLUE); printValue("Altitude", altitude, " m", true); oldAltitude = altitude; wasUpdate = true; } } if(DHT.humidity != oldDHTHumidity) { tft.fillRect(0, 54, 160, 7, ST7735_BLACK); tft.setCursor(0, 54); tft.setTextColor(ST7735_GREEN); printValue("Humidity", DHT.humidity, "%", true); oldDHTHumidity = DHT.humidity; wasUpdate = true; } if(DHT.temperature != oldDHTTemperature) { tft.fillRect(0, 80, 160, 7, ST7735_BLACK); tft.setCursor(0, 80); tft.setTextColor(ST7735_YELLOW); printValue("DHT_temperature", DHT.temperature, " C", true); oldDHTTemperature = DHT.temperature; wasUpdate = true; } if(wasUpdate) { Serial.println("END_TRANSMISSION"); } wasUpdate = false; delay(10000); } void printValue(char* title, double value, char* measure, bool tftPrint) { if(tftPrint) // print data to TFT { tft.print(title); tft.print(": "); tft.print(value); tft.println(measure); } Serial.print(title); // send data to Serial port Serial.print(": "); Serial.print(value); Serial.println(measure); }
      
      







ケースを組み立てる時間です



コースの主な条件は、提示可能な形式の作業プロトタイプでした。 そのため、船体を購入し、ファイルで武装して、気象ステーションを船体に配置する必要がありました。



ケースは地元の電器店で購入されました。



住宅
(写真では、ケースが少し異なります。蓋は透明です)











次に、ファイルを振って、センサーと電源の出力用の穴を開けました。 ケースなしのシステムのテスト中に、画面の背面が非常に高温であることに気付き、ケース内の温度に影響するため、センサーを取り出すことにしました。



センサーと電源用の穴のあるハウジング
















足を2つのセンサーにはんだ付けし、そのうちの1つでトラックを燃やさなければならなかったので、運命を誘惑せずにセンサーにワイヤーをはんだ付けしないことにしました(私は何か他のもので練習します)が、接続を多少信頼できるようにするために、巻き戻すことにしました電気テープ。



住宅に「詰め込む」前のシステム








ケースはArduinoよりもはるかに大きいため(それほどではありませんでした)、ボードがケース内に入らないようにサポートを考え出す必要がありました。 また、図はパラロンから切り取られ、その中にはケースの内側を隠すために画面用の長方形がありました。 Superglueは手元になかったので、両面テープの上に座らなければなりませんでした。



不思議の国のクジラの魚








ふたを締め、電源を接続して待ちます。



建物内の完成した気象観測所
























結果が画面に表示された後、水分の測定における不快なエラーが明らかになります。DHT22は、99.90%という数値をめったに与えません(めったに1.00%)。 問題が何であるかを理解し始めます。 最初に行うことは、COMポートへの値の出力を確認することです。 すべてがうまくいくようです。 数回の詰め替え、解体、ケースの組み立ての後、Googleで答えを探すというアイデアが浮かんできました。 予想通り、ロシアのGoogleは賢明なことを何も言わなかった。 わかった 私たちは英語で検索を開始し、同様の問題を抱えている人に出会うフォーラムの1つで検索を開始します。 ディスカッションの最初の4ページは意味のあるものではありません。5ページ目には質問に対する答えがあります。

湿度センサーは、間違ったガスや高湿度のIIRCへの非常に長い暴露によって簡単に影響を受ける可能性があります。 データシートには、センサーを「リセット」する手順があります。試してみてください。



問題は、DHT22をいつどのように害したかだけでした。 しかし、それはコースを取る時間であったので、私はこの問題の解決策を後のために残しました。



あとがき



授業は合格しました。 気象ステーションは、大学ですべての尾が閉じられるまで無期限に延期されます。 しかし、思ったより早く気象観測所に戻らなければなりませんでした。 11月中旬に職場を変更し、新しいチームでArduinoプラットフォームなどに興味のある人に会ったことがありました。 そのため、このプラットフォームに対する私の興味は、冷却する時間がないため、再び燃え上がりました。 気象観測所を取り出してコンピューターに接続し、COMポート経由でArduinoからデータ転送を実装していたことを思い出しました。 そして、ArduinoからCOMポートを介してデータを受信し、このデータを一般的な監視に転送するプログラムを作成するというアイデアを得ましたが、これはまったく別の話です。



また、ワイヤレスセンサーを持ち、Arduino Pro Miniに気象ステーションを実装したいと考えています。 そのため、3.3V、4 nRF24L01 +無線モジュール、その他のセンサーを搭載したArduino Pro Miniを4個注文しました。これについては、次回も説明します。 その間、私は小包を待っています、COMポートを介したクライアントへの接続がない場合、microSDカード上のデータとデータ自体を更新する時間を節約するために、リアルタイムクロックの接続を実装する予定です。



All Articles