kayrlasのアイコン画像
kayrlas 2022年09月26日作成 © MIT
セットアップや使用方法 セットアップや使用方法 閲覧数 1316
kayrlas 2022年09月26日作成 © MIT セットアップや使用方法 セットアップや使用方法 閲覧数 1316

BME680の温湿度・気圧情報をELTRESに送信

BME680の温湿度・気圧情報をELTRESに送信

BME680使用 温湿度・気圧・ガスセンサモジュールキット (秋月電子通商[AE-BME680]通販コードK-14469)の温湿度・気圧情報を送信します。

説明

本プログラムは,BME680使用 温湿度・気圧・ガスセンサモジュールキット(秋月電子通商[AE-BME680]通販コードK-14469)を使って,温度,湿度,気圧を取得し,その値をCLIP Viewer Liteの温度・湿度・気圧ペイロードのフォーマット仕様に合わせてELTRES送信します.

ELTRESエラー,測定開始エラー時を除き,初回GNSS電波受信後にELTRES送信を開始し継続します.温度・湿度・気圧ペイロードに設定した値はシリアルモニタで確認することができます.また,ELTRESエラー,測定開始エラー時を除き,5秒毎に取得した温度,湿度,気圧をシリアルモニタへ出力します.

ELTRESエラー,測定開始エラー時は異常終了状態でループします.
LEDの動きについては補足事項を確認してください.

動作環境

Arduino IDEを利用するSpresense Arduino 開発環境(2.5.0)上で利用できます.
以下のArduinoライブラリを利用します.
・ELTRESアドオンボード用ライブラリ(1.1.0)
・Adafruit BME680 Library(2.0.2)
https://github.com/adafruit/Adafruit_BME680

利用方法

  1. ELTRESアドオンボード用ライブラリをArduino IDEにインストールします.
  2. Adafruit BME680 LibraryをArduino IDEにインストールします.
    以下の手順でインストールできます.
    2-1. Arduino IDEの上部メニューから「ツール」->「ライブラリの管理」を選択します.
    2-2. ライブラリマネージャを起動するので,検索バーに「BME680」を入力します.
    2-3. ライブラリの一覧が更新されると,「Adafruit BME680 Library」が表示されます.
    「Adafruit BME680 Library」の「インストール」ボタンをクリックします.
    2-4. Dependencies確認のウインドウが表示された場合,
    「Install all」ボタンをクリックします.
    ※他のライブラリのインストール状況により,
    この確認ウインドウは表示されない場合があります.
  3. 本プログラムをArduino IDEで開き,Spresenseに書き込みます.
  4. 電源を入れてプログラムを起動します.
    シリアルモニタを確認したい場合,Arduino IDEと接続し,
    Arduino IDEの上部メニューから「ツール」->「シリアルモニタ」を選択し,シリアルモニタを起動します.
    ・温度・湿度・気圧ペイロードに設定した値は"[setup_payload_temp_hum]","[setup_payload_pres]"から始まる出力で確認できます.
    ・取得した温度,湿度,気圧は"[measure]"から始まる出力で確認できます.

注意事項

本プログラムは,ELTRES送信間隔が1分であることを前提としてます.
3分契約の場合,EltresAddonBoard.begin()の引数 ELTRES_BOARD_SEND_MODE_1MIN を
ELTRES_BOARD_SEND_MODE_3MIN に変更してください.

補足事項

本プログラムは,下記のようにLEDを用いて状態を表現します.
LED0:[プログラム状態] 起動中:点灯,正常・異常終了:消灯
LED1:[GNSS電波状態] 受信中:点灯,未受信:消灯
LED2:[ELTRES状態] 送信中:点灯,待機中:消灯
LED3:[エラー状態] GNSS受信エラー:点滅,ELTRESエラー,測定開始エラー:点灯,エラー無し:消灯
※GNSS受信エラー発生時はGNSS電波受信するまで待ち続けます.(LED0は点灯,LED3は点滅)
※ELTRESエラー,測定開始エラー発生時は異常終了状態でループします.(LED0は消灯,LED3は点灯)

製品情報

BME680使用 温湿度・気圧・ガスセンサモジュールキット
https://akizukidenshi.com/catalog/g/gK-14469/

参考情報

温湿度・気圧・ガスセンサ(BOSCH製BME680)の詳細仕様については下記を参照してください.
https://akizukidenshi.com/download/ds/bosch/bme680.pdf

eltres_bme680.ino

#include <Wire.h> #include <SPI.h> #include <EltresAddonBoard.h> // BME680用ライブラリのインクルード #include <Adafruit_Sensor.h> #include "Adafruit_BME680.h" #define SEALEVELPRESSURE_HPA (1016.2) // 東京の海面気圧 Adafruit_BME680 bme; // I2C // PIN定義:LED(プログラム状態) #define LED_RUN PIN_LED0 // PIN定義:LED(GNSS電波状態) #define LED_GNSS PIN_LED1 // PIN定義:LED(ELTRES状態) #define LED_SND PIN_LED2 // PIN定義:LED(エラー状態) #define LED_ERR PIN_LED3 // プログラム内部状態:初期状態 #define PROGRAM_STS_INIT (0) // プログラム内部状態:起動中 #define PROGRAM_STS_RUNNING (1) // プログラム内部状態:終了 #define PROGRAM_STS_STOPPED (3) // プログラム内部状態 int program_sts = PROGRAM_STS_INIT; // GNSS電波受信タイムアウト(GNSS受信エラー)発生フラグ bool gnss_recevie_timeout = false; // 点滅処理で最後に変更した時間 uint64_t last_change_blink_time = 0; // イベント通知での送信直前通知(5秒前)受信フラグ bool event_send_ready = false; // ペイロードデータ格納場所 uint8_t payload[16]; // ペイロードデータの内容 bool send_temp_hum = true; // 最新値(温度) float last_temp = 0; // 最新値(湿度) float last_hum = 0; // 最新値(気圧) float last_pres = 0; /** * @brief イベント通知受信コールバック * @param event イベント種別 */ void eltres_event_cb(eltres_board_event event) { switch (event) { case ELTRES_BOARD_EVT_GNSS_TMOUT: // GNSS電波受信タイムアウト Serial.println("gnss wait timeout error."); gnss_recevie_timeout = true; break; case ELTRES_BOARD_EVT_IDLE: // アイドル状態 Serial.println("waiting sending timings."); digitalWrite(LED_SND, LOW); break; case ELTRES_BOARD_EVT_SEND_READY: // 送信直前通知(5秒前) Serial.println("Shortly before sending, so setup payload if need."); event_send_ready = true; break; case ELTRES_BOARD_EVT_SENDING: // 送信開始 Serial.println("start sending."); digitalWrite(LED_SND, HIGH); break; case ELTRES_BOARD_EVT_GNSS_UNRECEIVE: // GNSS電波未受信 Serial.println("gnss wave has not been received."); digitalWrite(LED_GNSS, LOW); break; case ELTRES_BOARD_EVT_GNSS_RECEIVE: // GNSS電波受信 Serial.println("gnss wave has been received."); digitalWrite(LED_GNSS, HIGH); gnss_recevie_timeout = false; break; case ELTRES_BOARD_EVT_FAULT: // 内部エラー発生 Serial.println("internal error."); break; } } /** * @brief setup()関数 */ void setup() { // シリアルモニタ出力設定 Serial.begin(115200); while (!Serial); Serial.println(F("ELTRES BME680 program")); // LED初期設定 pinMode(LED_RUN, OUTPUT); digitalWrite(LED_RUN, HIGH); pinMode(LED_GNSS, OUTPUT); digitalWrite(LED_GNSS, LOW); pinMode(LED_SND, OUTPUT); digitalWrite(LED_SND, LOW); pinMode(LED_ERR, OUTPUT); digitalWrite(LED_ERR, LOW); // ELTRES起動処理 eltres_board_result ret = EltresAddonBoard.begin(ELTRES_BOARD_SEND_MODE_1MIN,eltres_event_cb, NULL); if (ret != ELTRES_BOARD_RESULT_OK) { // ELTRESエラー発生 digitalWrite(LED_RUN, LOW); digitalWrite(LED_ERR, HIGH); program_sts = PROGRAM_STS_STOPPED; Serial.print("cannot start eltres board ("); Serial.print(ret); Serial.println(")."); return; } // 測定開始 if (!bme.begin()) { // 測定開始エラー Serial.println("Could not find a valid BME680 sensor, check wiring!"); EltresAddonBoard.end(); digitalWrite(LED_RUN, LOW); digitalWrite(LED_ERR, HIGH); program_sts = PROGRAM_STS_STOPPED; return; } // 正常 program_sts = PROGRAM_STS_RUNNING; // オーバーサンプリングのセットアップとフィルタ初期化 bme.setTemperatureOversampling(BME680_OS_8X); bme.setHumidityOversampling(BME680_OS_2X); bme.setPressureOversampling(BME680_OS_4X); bme.setIIRFilterSize(BME680_FILTER_SIZE_3); bme.setGasHeater(320, 150); // 320*C for 150 ms } /** * @brief loop()関数 */ void loop() { if (! bme.performReading()) { Serial.println("Failed to perform reading :("); return; } switch (program_sts) { case PROGRAM_STS_RUNNING: // プログラム内部状態:起動中 if (gnss_recevie_timeout) { // GNSS電波受信タイムアウト(GNSS受信エラー)時の点滅処理 uint64_t now_time = millis(); if ((now_time - last_change_blink_time) >= 1000) { last_change_blink_time = now_time; bool set_value = digitalRead(LED_ERR); bool next_value = (set_value == LOW) ? HIGH : LOW; digitalWrite(LED_ERR, next_value); } } else { digitalWrite(LED_ERR, LOW); } if (event_send_ready) { // 送信直前通知時の処理 event_send_ready = false; if (send_temp_hum){ setup_payload_temp_hum(last_temp, last_hum); // 気温,湿度送信ペイロードの設定 EltresAddonBoard.set_payload(payload); send_temp_hum = false; } else { setup_payload_pres(last_pres); // 気圧ペイロードの設定 EltresAddonBoard.set_payload(payload); send_temp_hum = true; } } // BME680から値を取得し,最新値を更新 measure_bme680(); break; case PROGRAM_STS_STOPPED: // プログラム内部状態:終了 break; } // 次のループ処理まで100ミリ秒待機 delay(100); } /** * @brief 温度・湿度 ペイロード設定 * @param temp 温度 * @param hum 湿度 */ void setup_payload_temp_hum(float temp, float hum) { // 設定情報をシリアルモニタへ出力 Serial.print("[setup_payload_temp_hum]"); Serial.print("tem:"); Serial.print(temp, 6); Serial.print(",hum:"); Serial.print(hum, 6); Serial.println(); // ペイロード領域初期化 memset(payload, 0x00, sizeof(payload)); // ペイロード種別[温度・湿度・CO2ペイロード]設定 payload[0] = 0x82; // 温度設定 uint32_t raw; raw = *((uint32_t*)&temp); payload[1] = (uint8_t)((raw >> 24) & 0xff); payload[2] = (uint8_t)((raw >> 16) & 0xff); payload[3] = (uint8_t)((raw >> 8) & 0xff); payload[4] = (uint8_t)((raw >> 0) & 0xff); // 湿度設定 raw = *((uint32_t*)&hum); payload[5] = (uint8_t)((raw >> 24) & 0xff); payload[6] = (uint8_t)((raw >> 16) & 0xff); payload[7] = (uint8_t)((raw >> 8) & 0xff); payload[8] = (uint8_t)((raw >> 0) & 0xff); } /** * @brief 気圧 ペイロード設定 * @param pres 気圧 */ void setup_payload_pres(float pres) { // 設定情報をシリアルモニタへ出力 Serial.print("[setup_payload_pres]"); Serial.print("pres:"); Serial.print(pres, 6); Serial.println(); // ペイロード領域初期化 memset(payload, 0x00, sizeof(payload)); // ペイロード種別[気圧・圧力・照度・距離ペイロード]設定 payload[0] = 0x85; // 気圧設定 uint32_t raw; raw = *((uint32_t*)&pres); payload[1] = (uint8_t)((raw >> 24) & 0xff); payload[2] = (uint8_t)((raw >> 16) & 0xff); payload[3] = (uint8_t)((raw >> 8) & 0xff); payload[4] = (uint8_t)((raw >> 0) & 0xff); } /** * @brief BME680から温度,湿度,気圧を取得し,最新値を更新 */ void measure_bme680() { // 最新値の更新 last_temp = bme.temperature; last_hum = bme.humidity; last_pres = bme.pressure / 100.0; // 最新値をシリアルモニタへ出力 Serial.println("[measure]:"); Serial.print("Temperature = "); Serial.print(last_temp, 6); Serial.println(" °C"); Serial.print("Humidity = "); Serial.print(last_hum, 6); Serial.println(" %"); Serial.print("Pressure = "); Serial.print(last_pres, 6); Serial.println(" hPa"); Serial.println(); }
kayrlasのアイコン画像
Space Engineering, Human Informatics, Robotics, xR.
  • kayrlas さんが 2022/09/26 に 編集 をしました。 (メッセージ: 初版)
ログインしてコメントを投稿する