2016年3月23日水曜日

ESP-WROOM-02 + BME280、省エネ編

ベランダに置いてたけど、結構汚れるもんだ。

■Deep Sleep■

以前作ったESP-WROOM-02 + BME280の瓶入り気象?センサーを少し改良して、省エネルギー仕様にし、エネループ単3黒3本で駆動してみたところ、17日間動作しました。

ESP-WROOM-02はいつものTareObjects製Board1のプロトタイプ、deep sleepが働くようにIO16とRESETをつないであります。

プログラムは以下の通りです。

// ESP_BME280_SSD1306 by k.kurahashi 2016-01-24
//
// thanks:
// BME280 Library
// https://github.com/embeddedadventures/BME280
// OLED Library
// https://github.com/squix78/esp8266-oled-ssd1306
//
// ThingSpeak.com
// https://thingspeak.com/channels/81094
//
#include <Wire.h>
#include <Time.h>
#include <BME280_MOD-1022.h>
#include "SSD1306.h"
#include "SSD1306Ui.h"
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
extern "C" {
#include "user_interface.h"
}
//
// OLED / SSD1306
//
SSD1306 display(0x3c, 4, 5);
//
// Wifi
//
#include "../../private_ssid.h"
//const char *ssid = "*************";
//const char *password = "*************";
WiFiClient client;
//
// Setup BME280 ほぼサンプル, thanks for Embedded Adventures
//
void setup_BME280() {
uint8_t chipID;
Serial.println("Welcome to the BME280 MOD-1022 weather multi-sensor test sketch!");
Serial.println("Embedded Adventures (www.embeddedadventures.com)");
chipID = BME280.readChipId();
// find the chip ID out just for fun
Serial.print("ChipID = 0x");
Serial.print(chipID, HEX);
// need to read the NVM compensation parameters
BME280.readCompensationParams();
BME280.writeStandbyTime(tsb_0p5ms); // tsb = 0.5ms
BME280.writeFilterCoefficient(fc_16); // IIR Filter coefficient 16
BME280.writeOversamplingTemperature(os2x); // temperature x2
BME280.writeOversamplingHumidity(os1x); // humidity x1
BME280.writeOversamplingPressure(os16x); // pressure x16
BME280.writeMode(smNormal);
}
//
// setup
//
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println();
//
// Wifi
//
WiFi.begin ( ssid, password );
Serial.println("Started");
// Wait for connection
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 500 );
Serial.print ( "." );
}
Serial.println("Wifi Connected");
// BME and OLED
Wire.begin();
setup_BME280();
display.init();
display.flipScreenVertically();
display.displayOn();
display.clear();
drawAndSend();
ESP.deepSleep((60-second())*1000*1000, WAKE_RF_DEFAULT);
delay(1000);
}
//
// loop
//
void loop() {
delay(1000);
}
//
// OLEDへの描画と送信
//
void drawAndSend() {
float temp, humidity, pressure, pressureMoreAccurate;
double tempMostAccurate, humidityMostAccurate, pressureMostAccurate;
char buffer[80];
// BME280起動待ち
BME280.writeMode(smForced);
while (BME280.isMeasuring()) {
delay(50);
}
// BME280計測実行
BME280.readMeasurements();
// BME280各データ取り出し
temp = BME280.getTemperature();
humidity = BME280.getHumidity();
pressure = BME280.getPressure();
pressureMoreAccurate = BME280.getPressureMoreAccurate(); // t_fine already calculated from getTemperaure() above
tempMostAccurate = BME280.getTemperatureMostAccurate();
humidityMostAccurate = BME280.getHumidityMostAccurate();
pressureMostAccurate = BME280.getPressureMostAccurate();
// OLEDへ表示
display.clear();
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString( 0, 16, "Temperature");
display.drawString( 0, 32, "Humidity");
display.drawString( 0, 48, "Pressure");
display.setFont(ArialMT_Plain_16);
display.setTextAlignment(TEXT_ALIGN_RIGHT);
dtostrf(tempMostAccurate, 7, 2, buffer);
display.drawString(127, 12, buffer);
dtostrf(humidityMostAccurate, 7, 2, buffer);
display.drawString(127, 28, buffer);
dtostrf(pressureMostAccurate, 7, 2, buffer);
display.drawString(127, 44, buffer);
display.display();
// ThingSpeak.comへ送信
sendTHP(tempMostAccurate, humidityMostAccurate, pressureMostAccurate);
}
//
// ThingSpeakへのパラメータを作って送信
//
void sendTHP(float inTemperature, float inHumidity, float inPressure) {
char tBuf[10], hBuf[10], pBuf[10];
dtostrf(inTemperature, 7, 2, tBuf);
dtostrf(inHumidity, 7, 2, hBuf);
dtostrf(inPressure, 7, 2, pBuf);
String postStr = "&field1=" + String(tBuf) + "&field2=" + String(hBuf) + "&field3=" + String(pBuf);
send(postStr);
Serial.println(postStr);
}
// ThingSpeakへ送信
//
void send(String inPostStr) {
String apiKey = "*******************";
Serial.print("Connecting...");
if (client.connect("184.106.153.149", 80)) { // api.thingspeak.com
Serial.print("Connected....");
String postStr = apiKey + inPostStr + "\r\n\r\n";
client.print("POST /update HTTP/1.1\n");
client.print("Host: api.thingspeak.com\n");
client.print("Connection: close\n");
client.print("X-THINGSPEAKAPIKEY: " + apiKey + "\n");
client.print("Content-Type: application/x-www-form-urlencoded\n");
client.print("Content-Length: ");
client.print(postStr.length());
client.print("\n\n");
client.print(postStr);
Serial.println("posted.");
}
client.stop();
}


約1分ごとのデータ収集ですが、気象データならもっと低頻度で十分かもしれないですね。外に置きっぱなしなので、電池交換頻度は1ヶ月に一度として40日ぐらいは動いて欲しいです。となると3分に1回か…。

■追記6/11日

間隔を5分にしました。104行目を60から300に変えるだけです。あ、黒エネループで17日だったのか…白エネループ入れたので約2ヶ月ってところかしら。

0 件のコメント:

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。