|
// 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" |
|
} |
|
|
|
|
|
// |
|
// BME280 |
|
// |
|
float averageHumidity; // 湿度の計測値はわりとフラフラするので簡単な移動平均を取る |
|
|
|
|
|
// |
|
// OLED / SSD1306 |
|
// |
|
SSD1306 display(0x3c, 4, 5); |
|
|
|
|
|
// |
|
// Wifi |
|
// |
|
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(); |
|
} |
|
|
|
|
|
// |
|
// loop |
|
// |
|
void loop() { |
|
draw(); |
|
delay(1000); |
|
} |
|
|
|
int prevMinute = minute(); // 分ごとに送信するためのフラグ |
|
|
|
|
|
// |
|
// OLEDへの描画 |
|
// |
|
void draw() { |
|
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(); |
|
|
|
// 湿度の値を平準化 |
|
averageHumidity = (averageHumidity * 9.0 + humidityMostAccurate) / 10.0; |
|
|
|
// 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(averageHumidity, 7, 2, buffer); |
|
display.drawString(127, 28, buffer); |
|
|
|
dtostrf(pressureMostAccurate, 7, 2, buffer); |
|
display.drawString(127, 44, buffer); |
|
|
|
display.display(); |
|
|
|
// ThingSpeak.comへ送信 |
|
if (minute() != prevMinute) { |
|
sendTHP(tempMostAccurate, averageHumidity, pressureMostAccurate); |
|
prevMinute = minute(); |
|
} |
|
} |
|
|
|
|
|
// |
|
// 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(); |
|
} |