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

**[1話 センサー1つ+Ambient編](https://qiita.com/after-a-rain/items/20d337702f93cd589044)** / **[2話 センサー2つ+Ambient編](https://qiita.com/after-a-rain/items/80fe94cb3b2870ea9f0c)** / **[3話 センサー4つ編](https://qiita.com/after-a-rain/items/f64626f3f72e62b783c0)**
**[4話 SDカード記録編](https://qiita.com/after-a-rain/items/d736854791fa27aea543)** / **[5話 システム時刻・NTP編](https://qiita.com/after-a-rain/items/ec9e772df0c6ea029e84)**

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

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

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

# 2話

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

## 用意したもの

- Arduino的なもの ESP-WROOM-02開発ボード (SwitchScience)  ×1  
  https://www.switch-science.com/catalog/2500/
- 温湿度・気圧センサー BME280 (SwitchScience)  ×2  
  https://www.switch-science.com/catalog/2236/



## やったこと

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

​	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について各プログラムを同じ様に動くように増やして完成。
本当はループでうまくやりたいけど、試行錯誤の結果できませんでした。

```c#
/*
 * 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の機能を追加します。追加したものがこちら。

```C#
/*
 * 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話に続きます**](https://qiita.com/after-a-rain/items/f64626f3f72e62b783c0)

## 参考文献

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

+ ESP8266 with two BME280 Sensors over SPI – Robot Zero OneRobot Zero One  
  https://robotzero.one/esp8266-two-bme280-sensors-spi/
+ 温度、湿度、気圧を測定し、記録する - AmbientでIoTをはじめよう  
  https://pages.switch-science.com/letsiot/temphumidpress/