1話 センサー1つ+Ambient編 / 2話 センサー2つ+Ambient編 / 3話 センサー4つ編
4話 SDカード記録編 / 5話 システム時刻・NTP編
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について各プログラムを同じ様に動くように増やして完成。
本当はループでうまくやりたいけど、試行錯誤の結果できませんでした。
/*
* 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つもデータを飛ばす場合、チャネルを増やして行かなきゃいけない事になります。
これはまだ試していないので、今後の課題です。
参考文献
勝手にソースコードを拝借しています。すみません。ありがとうございます。
何かあればお申し付けください。
- 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/