0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

温湿度・気圧のロガーを作る #2

Last updated at Posted at 2020-11-16

1話 センサー1つ+Ambient編 / 2話 センサー2つ+Ambient編 / 3話 センサー4つ編
4話 SDカード記録編 / 5話 システム時刻・NTP編

qiitaって30分くらいあけないと投稿できないんですね。

一気に書こうとしていた小生、この2話をコピーして、そのエラーに気づき

エラーをググってたら貼り付けるの忘れて消失させました。ちゃんちゃん。

2話

ボスが4つくらい付けてほしいというので、とりあえず2つからチャレンジしました。

用意したもの

やったこと

とりあえず、ググって見つかったのがこちらの記事。

​ ESP8266 with two BME280 Sensors over SPI – Robot Zero OneRobot Zero One

https://robotzero.one/esp8266-two-bme280-sensors-spi/

多少プログラムは違えどやってることは同じなので、1話のプログラムに少し追加します。

あと、ここでSPI接続の仕組みを少し理解します。1話の参考HPの表を真似るとこんな感じにつなげました。

SPI接続 ESPr Developer BME280
MISO IO12 SDO
CLK IO14 SCK
MOSI IO13 SDI
CS IO15 CSB (BME(1))
CS IO16 CSB (BME(2))
GND GND GND
+3.3V 3v3 Vcore
+3.3V 3v3 Vio

このように、SPI接続はCSが判別子みたいになっていて、プログラム内で指定したCSのセンサーから情報をとって来ることができるとわかりました。

それに合わせてプログラムも書き換え。
プログラムの云っていることの記事は別に書きます(投稿予定)
BM280が2個になったので

defineでBME_CS2を16に指定。つまり、2個めのBME280のCSを16番につなげたぜと。
それに伴い、BME280クラスをbme2として定義(?これ何というのかわかりません)
bme2.begin(BME_CS2)で、bme2はBME_CS2のCSを使って計測開始してねってします。
そして、bme2について各プログラムを同じ様に動くように増やして完成。
本当はループでうまくやりたいけど、試行錯誤の結果できませんでした。

/*
 * BME280で5秒毎に温度、湿度、気圧を測定し、シリアルモニタに出力する
 */

# include <ESP8266WiFi.h>
# include <SPI.h>
# include "BME280_SPI.h"

# define BME_CS1 15
# define BME_CS2 16

# define PERIOD 5

BME280 bme1;
BME280 bme2;

void setup()
{
    Serial.begin(115200);
    delay(10);

    Serial.println("Start");

    bme1.begin(BME_CS1);
    bme2.begin(BME_CS2);
}

void loop()
{
    double temp, humid, pressure;

    temp = bme1.readTemperature();
    humid = bme1.readHumidity();
    pressure = bme1.readPressure();

    Serial.print("BME1:: ");
    Serial.print("temp: ");
    Serial.print(temp);
    Serial.print(", humid: ");
    Serial.print(humid);
    Serial.print(", pressure: ");
    Serial.println(pressure);

    temp = bme2.readTemperature();
    humid = bme2.readHumidity();
    pressure = bme2.readPressure();

    Serial.print("BME2:: ");
    Serial.print("temp: ");
    Serial.print(temp);
    Serial.print(", humid: ");
    Serial.print(humid);
    Serial.print(", pressure: ");
    Serial.println(pressure);

    delay(PERIOD * 1000);
}

これに、Ambientの機能を追加します。追加したものがこちら。

/*
 * BME280で5秒毎に温度、湿度、気圧を測定し、シリアルモニタに出力する
 */

# include <ESP8266WiFi.h>
# include <SPI.h>
# include "BME280_SPI.h"
# include "Ambient.h"

# define BME_CS1 15
# define BME_CS2 16

# define PERIOD 10

BME280 bme1;
BME280 bme2;


WiFiClient client;
Ambient ambient;

const char* ssid = "hogehoge";
const char* password = "hogehoge";

unsigned int channelId = 000000; // AmbientのチャネルID
const char* writeKey = "00000abcdef"; // ライトキー

float temperature = 0.0;
float humidity    = 0.0;
float pressure    = 0.0;

void setup()
{
    Serial.begin(115200);
    delay(10);

    Serial.println("Start");

    WiFi.begin(ssid, password);  //  Wi-Fi APに接続
    while (WiFi.status() != WL_CONNECTED) {  //  Wi-Fi AP接続待ち
        delay(100);
    }

    Serial.print("WiFi connected\r\nIP address: ");
    Serial.println(WiFi.localIP());
    
    bme1.begin(BME_CS1);
    bme2.begin(BME_CS2);

    ambient.begin(channelId, writeKey, &client); // チャネルIDとライトキーを指定してAmbientの初期化
}

void loop()
{
  
    double temp, humid, pressure;

    temp = bme1.readTemperature();
    humid = bme1.readHumidity();
    pressure = bme1.readPressure();

    Serial.print("BME1:: ");
    Serial.print("temp: ");
    Serial.print(temp);
    Serial.print(", humid: ");
    Serial.print(humid);
    Serial.print(", pressure: ");
    Serial.println(pressure);


    ambient.set(1, temp); // 温度をデータ1にセット
    ambient.set(2, humid); // 湿度をデータ2にセット
    ambient.set(3, pressure); // 気圧をデータ3にセット

    temp = bme2.readTemperature();
    humid = bme2.readHumidity();
    pressure = bme2.readPressure();

    Serial.print("BME2:: ");
    Serial.print("temp: ");
    Serial.print(temp);
    Serial.print(", humid: ");
    Serial.print(humid);
    Serial.print(", pressure: ");
    Serial.println(pressure);

    ambient.set(4, temp); // 温度をデータ4にセット
    ambient.set(5, humid); // 湿度をデータ5にセット
    ambient.set(6, pressure); // 気圧をデータ6にセット

    ambient.send(); // データをAmbientに送信

    delay(PERIOD * 1000);
}

やっていることは
BME1から読み取る→モニタに表示→Ambientのデータ1~3にset →BME2から読み取る→モニタに表示→Ambientのデータ4~6にset→Ambient送信
です。

ここで問題発生しました。(このソースコードは問題解決後)
シリアルモニタに表示される、temp, humid, pressureの値がすべて0.00になってしまいました。
ここでボスが、SPI接続が2個になって、Wi-FiモジュールもSPI接続で多すぎて干渉してるのでは?ということを言いその線で考えました。(結論:SPIなんでそんなはずはありません。ボスは昔I2Cでやっていたので、番地で苦労した過去がありこの発想になったそう。納得。)
うーん、とりあえず、問題を切り分けます。

  • Ambientあり + BME280×1 → ◎ (1話:更新予定)
  • Ambientなし + BME280×2 → ◎ (これ)
  • Ambientなし + BME280×4 → ◎ (3話:投稿予定)
  • Ambientあり + BME280×2 → × (これ)

なので、これによって

  • "SPI接続3つだからダメ" ということはなさそう
  • Ambientもきちんと動く。
  • え、じゃあ接続ではなくコードに問題があるんじゃん?

となり、なんやかんやして、グローバル変数のほうでtemp, humid, pressureをfloat型にすることで解決しました。(結果論)
(ここはもう少し追求する必要があると思っています。float型とdouble型の問題なのか、グローバルの問題なのか解っていないので)

次に、Ambientの制約について考えました。
Ambientは(ななめ読みしたところ)、1チャネルにつき8チャンネル、8つしかデータを送れないのです。
つまり、今後4つや8つもデータを飛ばす場合、チャネルを増やして行かなきゃいけない事になります。
これはまだ試していないので、今後の課題です。

3話に続きます

参考文献

勝手にソースコードを拝借しています。すみません。ありがとうございます。
何かあればお申し付けください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?