BME280
BME280は温度、湿度、気圧が測れるセンサーです。Aliexpressにて2.23ドルで買いました。Amazonでも日本発送のPrime対象商品が売っているので、Aliに抵抗があったり直ぐに欲しい場合はAmazonでもいいかもしれません。
似たような名前ですが、BMP280には湿度センサーが付属していないので注意してください。値段がぜんぜん違うので調べててわかるとは思いますが。BMPの方だと0.75ドルくらいです。
このモジュールボードには3.3V版と5V版が存在し、今回は5V版を購入しました。 センサー自体は3.3V駆動なので、5V版にはレギュレータが乗っています。I2Cバスにもレベルコンバータがちゃんと乗っていました。
ところが訳あって購入後にボードを3.3Vで動かす必要が出たので、5V版が3.3Vで動くか心配でしたが、結局の所全然問題ありませんでした。何故か私が買ったところでは3.3Vも5Vも値段が同じなので、迷うなら5V版を買っておいてもいいかもしれません。
なお5V版は両面実装で、センサー以外は全て裏面に乗ってます。
BH1750
BH1750は照度(ルクス)が測れるセンサーです。同じくAliexpressにて0.83ドルで買いました。こちらもAmazonでPrime対象商品が売っています。
このモジュールボードは3.3V~5V対応と謳っています。センサーは5Vに耐えられないので、3.3Vのレギュレータが乗っていましたが、問題はI2Cバスです。
そこにレベルコンバータはなく、3.3Vラインにプルアップされているだけでした。マイコン側で内部プルアップを用いず、他にI2Cデバイスをぶら下げないならコレでも問題ありませんが、他のデバイスで5Vラインにプルアップされていると、I2Cラインが3.3Vよりも上がってしまい、最悪、BH1750を破損してしまう可能性があります。5V駆動のプルアップ抵抗には注意が必要です。
ということで、無用なトラブルを避けるためにも、複数のI2Cデバイスをぶら下げるときは全て3.3V駆動にするのが安全でしょう。 私はBME280と共存させる予定なので、BME280も3.3V駆動してもらうことにしました。
ArudinoでBME280
ちゃんと先人の手によるライブラリがあります。感謝。https://github.com/finitespace/BME280
Arduino Library List にて検索して出てくるものと同じです。
ライブラリの導入法を軽く書いておくと、Githubの「Clone or download」から「Download ZIP」して、解凍して、ArduinoIDEがインストールされてる階層にある「libraries」フォルダに、「~~master」フォルダごとすべてコピーすれば完了です。中にexampleフォルダがあろうと問題ありません。
ArduinoUnoのピンアサインは、
A4ピンがI2CのSDA
A5ピンがI2CのSCL
となっています。
また、前述の理由から、今回は5Vボードですが3.3V駆動します。ということでUnoの3.3V出力をセンサーボードに供給します。
動作チェック用のサンプルスケッチです。提供されているexampleとほぼ同じです。
// @Uno // A4 = SDA // A5 = SCL // 3.3V = VIN #include <BME280I2C.h> #include <Wire.h> BME280I2C::Settings settings( // Temp BME280::OSR_X1, // Hum BME280::OSR_X1, // Pres BME280::OSR_X1, BME280::Mode_Forced, BME280::StandbyTime_1000ms, BME280::Filter_Off, BME280::SpiEnable_False, BME280I2C::I2CAddr_0x76 ); BME280I2C bme280(settings); void setup() { Serial.begin(115200); while(!Serial) {} // Wait Wire.begin(); while(!bme280.begin()) { Serial.println("Could not find BME280 sensor!"); delay(1000); } } float temp, hum, pres; void loop() { bme280.read(pres, temp, hum, BME280::TempUnit_Celsius, BME280::PresUnit_hPa); Serial.print("Temperature: "); Serial.print(temp); Serial.print("℃"); Serial.print(" Humidity: "); Serial.print(hum); Serial.print("%"); Serial.print(" Pressure: "); Serial.print(pres); Serial.println("hPa"); delay(1000); }書き込み終わったら、IDEのツール→シリアルモニタで確認してみましょう。
いい感じですね。値も結構安定していて優秀です。現実との誤差に関しては比較できませんが。
試しに1m先から息を吹きかけてみましたが、湿度が顕著に上昇し、数秒で元に戻りました。結構鋭敏です。
ArudinoでBH1750
こちらもちゃんと先人の手によるライブラリがあります。感謝。https://github.com/claws/BH1750
なお、これは、Arduino Library List にて検索して出てくるライブラリと異なります。こちらのライブラリは、私の確認した時点では、ACKのチェックを行っておらず、BH1750の計測時間レジスタの書き込みに対応していなかったので、使用しませんでした。
ライブラリ導入法はBME280と同じ。
再度書きますが、ArduinoUnoのピンアサインは、
A4ピンがI2CのSDA
A5ピンがI2CのSCL
です。
前述の理由から、3.3V駆動とします。
また、ボードにはADDRピンがありますが、これをLowにするかHighにするかでI2Cアドレスを変えられるようです。マイコンのIOピンに接続すれば、送りたいアドレスだけLなりHにすることで、実質的に何台だろうとBH1750を接続できるということですね。便利です。
ちなみにボードのADDRピンは1kΩでプルダウンされていたので、何も接続しなければLowになるようです。ライブラリも、デフォルト設定では、このLowのときのアドレスを勝手に使ってくれるようです。
動作チェック用のサンプルスケッチです。提供されているexampleとほぼ同じです。
// @Uno // A4 = SDA // A5 = SCL // 3.3V = VIN #include <BH1750.h> #include <Wire.h> BH1750 bh1750; void setup() { Serial.begin(115200); while(!Serial) {} // Wait Wire.begin(); bh1750.begin(BH1750::ONE_TIME_HIGH_RES_MODE); } void loop() { float lux = bh1750.readLightLevel(true); Serial.print("Luminosity: "); if(lux < 0){ Serial.println("Error"); } else{ Serial.print(lux); Serial.println("lx"); } delay(1000); }書き込み終わったら、IDEのツール→シリアルモニタで確認してみましょう。
いい感じですね。
こちらも、値が結構安定していて優秀です。誤差は知りえません。
受光部を一切遮らずに、1m程度離れた場所で人間が動くだけでも数lx変動するようです。人間が反射・遮断する光の量が変化するためだと思われますが、この敏感さには驚きました。
ArduinoでBME280とBH1750を同時に動かす
さて本命です。といってもI2Cなので並列するだけです。個々で動いたのだから、まぁ普通に動きます。
サンプルスケッチです。合わせただけ。
// @Uno // A4 = SDA // A5 = SCL // 3.3V = VIN #include <BME280I2C.h> #include <BH1750.h> #include <Wire.h> BME280I2C::Settings settings( // Temp BME280::OSR_X1, // Hum BME280::OSR_X1, // Pres BME280::OSR_X1, BME280::Mode_Forced, BME280::StandbyTime_1000ms, BME280::Filter_Off, BME280::SpiEnable_False, BME280I2C::I2CAddr_0x76 // I2C address. I2C specific. ); BME280I2C bme280(settings); BH1750 bh1750; void setup() { Serial.begin(115200); while(!Serial) {} // Wait Wire.begin(); while(!bme280.begin()) { Serial.println("Could not find BME280 sensor!"); delay(1000); } bh1750.begin(BH1750::ONE_TIME_HIGH_RES_MODE); } float temp, hum, pres; void loop() { bme280.read(pres, temp, hum, BME280::TempUnit_Celsius, BME280::PresUnit_hPa); Serial.print("Temperature: "); Serial.print(temp); Serial.print("℃"); Serial.print(" Humidity: "); Serial.print(hum); Serial.print("%"); Serial.print(" Pressure: "); Serial.print(pres); Serial.print("hPa"); float lux = bh1750.readLightLevel(true); Serial.print(" Luminosity: "); if(lux < 0){ Serial.println("Error"); } else{ Serial.print(lux); Serial.println("lx"); } delay(1000); }結果がこちら。
完璧です。
0 件のコメント:
コメントを投稿