動作確認
ブレッドボード配線図
まずはArduino Pro mini(3.3V/8MHz)版を使って単体で動作確認です。USB-UART変換の接続はこちら
3.3Vの電源は安定化電源から供給しています。
BME280のモジュール上でI2Cのプルアップが行われているので外付け抵抗は不要です。
プルアップが行われているだけではなく、MOS-FETを使ったI2Cのレベル変換回路も載っているようです。(中華製なので回路図は怪しいですが・・・)
BME280モジュールの回路図
ArduinoのライブラリはSparkFun BME280 Arduino Libraryを使いました。
スケッチ例のSparkfunBME280_Example1_BasicReadingsを一部書き換えれば動作しました。
mySensor.setI2CAddress(0x76); if (mySensor.beginI2C() == false) //Begin communication over I2C { Serial.println("The sensor did not respond. Please check wiring."); while(1); //Freeze }
ライブラリのデフォルトのI2Cアドレスは0x77ですが、モジュールのI2Cアドレスが0x76になっているようなので、mySensor.beginI2C() の前に、mySensor.setI2CAddress(0x76); を追加してI2Cアドレスを指定します。
I2Cアドレスをデフォルト(0x77)のままで動作させた場合のI2C信号
ch1:SDA ch2:SCK
動作させるとシリアルモニタにエラーメッセージが表示されますが、I2C信号は出力されています。
I2Cアドレスを0x76にして動作させた場合のI2C信号
ch1:SDA ch2:SCK
比較すると、I2Cアドレスが違っている場合は、マスターがI2Cアドレスを送信後、9ビット目のSDAがLに引っ張られていません。
スレーブが、受信したI2Cアドレスが自身のI2Cアドレスと一致していたとき9ビット目をLに引っ張り(ACK)、その後マスター・スレーブ間でデータの送受信が行われます。
また、スケッチの気温、高度の測定も単位が華氏、フィートになっているので摂氏、メートルに変更しました。
Serial.print(" Alt: "); Serial.print(mySensor.readFloatAltitudeMeters(), 1); //Serial.print(mySensor.readFloatAltitudeFeet(), 1); Serial.print(" Temp: "); Serial.print(mySensor.readTempC(), 2); //Serial.print(mySensor.readTempF(), 2);
SSD1306 128x64のOLEDに表示
SSD1306 128x64 SPIのOLEDも同時に購入したので測定値を表示させました。
ブレッドボード配線図
<追記:2018.08.26> ブレッドボード図のArduino Pro miniのSPI/SCKの位置がずれていたので修正しました。(D12→D13) </追記>
※ブレッドボード配線図と写真は180度回転しています。
Arduinoのスケッチ <BME280_TempMeter_u8g2.ino>
OLEDのライブラリはu8g2を使用しました。
#include <U8g2lib.h> #include <stdio.h> #include <Wire.h> #include "SparkFunBME280.h" #define TITLE_STR1 ("BME280 Temp Meter") #define TITLE_STR2 ("20180808") const int measureInterval = 500; //U8G2_SSD1306_128X32_UNIVISION_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // Adafruit ESP8266/32u4/ARM Boards + FeatherWing OLED U8G2_SSD1306_128X64_NONAME_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); BME280 bme280; void setup() { Serial.begin(9600); Serial.println(); Serial.println(TITLE_STR1); Serial.println(TITLE_STR2); // BME280 Wire.begin(); bme280.setI2CAddress(0x76); if (bme280.beginI2C() == false) //Begin communication over I2C { Serial.println("The bme280 did not respond. Please check wiring."); while(1); //Freeze } // u8g2 u8g2.begin(); u8g2.clearBuffer(); u8g2.firstPage(); u8g2.setFont(u8g2_font_8x13_tf); do { u8g2.drawStr(0,10,TITLE_STR1); u8g2.drawStr(0,25,TITLE_STR2); } while (u8g2.nextPage()); u8g2.sendBuffer(); delay(1000); } float calcDiscomfort(float temperature, float humidity) { return 0.81 * temperature + 0.01 * humidity * (0.99 * temperature - 14.3) + 46.3; } void loop() { char strBuffer[32]; char strBuffer2[32]; float humidity = bme280.readFloatHumidity(); float pressure = bme280.readFloatPressure(); float Altitude = bme280.readFloatAltitudeMeters(); float temperature = bme280.readTempC(); float discomfort = calcDiscomfort(temperature, humidity); u8g2.firstPage(); do { u8g2.setFont(u8g2_font_logisoso28_tf); sprintf(strBuffer2, "%s%cC", dtostrf(temperature, 2, 1, strBuffer), 0xb0); u8g2.drawStr(0,32, strBuffer2); u8g2.setFont(u8g2_font_logisoso20_tf); sprintf(strBuffer2, "%s%%", dtostrf(humidity, 2, 1, strBuffer)); u8g2.drawStr(0,64, strBuffer2); sprintf(strBuffer2, "%s", dtostrf(discomfort, 5, 1, strBuffer)); u8g2.drawStr(64,64, strBuffer2); } while (u8g2.nextPage()); Serial.print(temperature); Serial.print("\t"); Serial.print(humidity); Serial.print("\t"); Serial.print(pressure); Serial.println(""); delay(measureInterval); }
温度、湿度と不快指数を計算してOLEDに表示しています。
Serialには温度、湿度、気圧を出力しています。
電源電流はほぼ一定していて16mA程度です。
0 件のコメント:
コメントを投稿