ガイガーカウンターにOLED(有機ELディスプレイ)を付けたら思いの外良かったので、温湿度計にも付けてみました。OLEDって物凄く明るいので、常時部屋置きするためにCDSセル(光センサー)も付けて、周りが暗いとOLEDも消えるようにしました。
ハーフサイズのブレッドボードに収めることができました。
使っているもの
- 左上:BOSCH BME280 温湿度・気圧計モジュール
- 右:ESP8266 WiFiマイコン WeMos D1 mini (写真のはバージョン3)
- 真ん中:OLEDモジュール
- 左下:CDSセル(φ7)
安いものが多いので、今回は全てaitendoさんで揃えてみました。
回路図
回路図はこんな感じです。
「SSD1036」と書いてあるのがOLEDです。OLEDとBME280はI2C接続なので「SCL」を「D1(GPIO5)」に「SDA」を「D2(GPIO4)」に繋ぎます。
WeMos D1 miniの端子とArduinoの対応表をホームページから抜粋しました。
WeMos D1 miniのアナログ入力端子「A0」は、分圧用の抵抗が内蔵されていて3.3V(電源電圧)まで加えることができるのでとっても便利です。
CDSセルと直列に10kΩの抵抗を繋げて、中間の電圧を測ることで明るさを検出しています。
Blynk
今回もIoTプラットフォームにはBlynkを使っています。機器側にもOLEDを付けているので、ネットに繋がずにスタンドアローンで動作できるように、D7(GPIO13)端子をGND(LOW)にするとWiFiが無くても動くようにしました。
実行時の画面
今回使ったWidgetはお馴染みのGaugeとお高いSuperChartです。設定は次のようにしています。
温度設定(Gauge)
「#」の数で小数点以下の桁数を指定できるのですが、今回は全て少数第2位までにしています。気圧を少数第2位まで表示すると、機器を高く持ち上げるだけでも数値が変化するのが面白かったので、全て揃えてみました。
湿度設定(Gauge)
気圧設定(Gauge)
グラフ設定(SuperChart)
高機能でお高いSuperChartは設定がちょっと面倒です。4つまでのデータを同じグラフに表示できるようになっていて、「+ Add DataStrem」で表示するデータを追加していきます。追加したら、右側の設定アイコンで各データの設定を行います。
「DECIMALS」で小数点以下の桁数を指定できそうなんですが、何故かできないみたいです。
スケッチ 2019/2/24 OLEDの表示がズレることがあったバグを修正
2019/5/29 ヘッダーファイルの修正が必要ない記述に修正
今回のスケッチはこんな感じです。
/*
* BME280BlynkOLED
* May 29, 2019
* By Hiroyuki ITO
* http://intellectualcuriosity.hatenablog.com/
* MIT Licensed.
*/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Wire.h>
#include <Adafruit_BME280.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define NETWORK_MODE 1
#define STANDALONE_MODE 2
#define MODE_PIN 13
#define ILLUMINANCE 50
// Set Blynk Auth Token and WiFi credentials.
const char *auth = "YourAuthToken";
const char *ssid = "YourNetworkName";
const char *pass = "YourPassword";
// for OLED
#define OLED_RESET -1
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_BME280 bme;
BlynkTimer timer;
int runmode;
/*
* Send Sensor Data to Blynk
*/
void sendSensor() {
// Get data from BME280 sensor
float t = bme.readTemperature(); // C
float h = bme.readHumidity(); // %
float p = bme.readPressure() / 100.0F; // hPa
Blynk.virtualWrite(V1, t);
Blynk.virtualWrite(V2, h);
Blynk.virtualWrite(V3, p);
BLYNK_LOG2("Temperature:", t);
BLYNK_LOG2("Humidity:", h);
BLYNK_LOG2("Pressure:", p);
BLYNK_LOG("");
// Display
int illuminance = analogRead(A0);
int color;
if (illuminance < ILLUMINANCE) {
color = BLACK;
} else {
color = WHITE;
}
display.setTextColor(color);
display.setCursor(0, 0);
display.fillRect(0, 0, 127, 7, BLACK);
display.setTextSize(1);
if (runmode == NETWORK_MODE) {
display.print("Network L:" + String(illuminance) + " \n\n");
} else {
display.print("Standalone L:" + String(illuminance) + " \n\n");
}
display.setCursor(0, 15);
display.setTextSize(2);
// Temperature
display.fillRect(0, 15, 127, 31, BLACK);
display.print(" " + String(t) + "C\n");
// Humidity
display.fillRect(0, 31, 127, 47, BLACK);
display.print(" " + String(h) + "%\n");
// Pressure
display.fillRect(0, 47, 127, 63, BLACK);
display.print(String(p) + "hPa");
display.display();
}
/*
* Setup
*/
void setup() {
delay(10);
Serial.begin(74880);
BLYNK_LOG2("Reset Reason: ", ESP.getResetReason());
pinMode(MODE_PIN, INPUT);
// Netowrk or Standalone
if (digitalRead(MODE_PIN) == HIGH) {
runmode = NETWORK_MODE;
Blynk.begin(auth, ssid, pass);
} else {
runmode = STANDALONE_MODE;
}
// setup BME280
if (!bme.begin()) {
BLYNK_LOG("Could not find a valid BME280 sensor, check wiring!");
while (1); // Hung up!
}
delay(100); // let sensor boot up
// Setup OLED
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
timer.setInterval(2000L, sendSensor); // 2 seconds
}
/*
* Loop
*/
void loop() {
if (runmode == NETWORK_MODE) {
Blynk.run();
}
timer.run();
}
追加ライブラリ
BME280で使ったライブラリは次の2つです。
OLEDモジュール「SSD1306」で使ったライブラリは次の2つです。
Adafruit SSD1306を使う上での注意点
ヘッダーファイルの修正 ※ライブラリが更新されて修正の必要なくなりました(2019/5/29)
「Adafruit SSD1306」ライブラリをこのOLEDモジュールで使う場合は、ヘッダーファイルを修正する必要があります。
修正するヘッダーファイル「Adafruit_SSD1306.h」は、スケッチフォルダの「libraries」の「Adarfuit_SSD1306」の中にあります。
73行目から75行目までが使用するSSD1306のサイズの選択で、使用するサイズのコメントを外して指定するようになっています。使用するOLEDモジュールは128x64ピクセルなので73行目のコメントを外して、他をコメントにします。
73: #define SSD1306_128_64
74:// #define SSD1306_128_32
75:// #define SSD1306_96_16
使い方を学ぶ方法
このライブラリの使い方は、Arduino IDEの[ファイル]-[スケッチ例]-[Adarfruit SSD1306]-[ssd1306_128x64_i2c]で表示できるサンプルスケッチから学びました。
サンプルスケッチを実行するには61行目のdisplay.begin(SSD1306_SWITCHCAPVCC, 0x3D);
をdisplay.begin(SSD1306_SWITCHCAPVCC, 0x3C);
に変更する必要があります。
書く前に消す
文字を書くのは簡単で、display.print("Hello!");
のようにSerial.print()
と同じような感じですが、この文で書かれる先はバッファです。バッファの内容を表示するためにはdisplay.display();
を実行する必要があります。また、display.print()
は紙に鉛筆で書くのと似ていて、消さないと文字が重ね書きされてしまいます。そのため予め書きたい場所を消しておく必要があるので注意してくださいね。
注意が必要な機能
ちょっと注意が必要なのが表示用のバッファをクリアするdisplay.clearDisplay();
で、どうもこれの実行に随分時間がかかるみたいなんです。最初、データの書き換え前にdisplay.clearDisplay();
を入れていたら、Blynkが正常に動作しなくなって頻繁に接続が切れていたんです。データを書き換える部分を黒の矩形で塗るように変更したら、ピタッと症状が出なくなりました。
おわり