記事の推し
・ESP32のWiFi利用でWebServerに温度湿度気圧を表示した
・ESP32に給電すれば、WiFiの到達範囲なら測定値がリアルタイムでブラウザに表示できる
測定コード
# include <WiFi.h>
# include <WebServer.h>
# include "Seeed_BME280.h"
# include <Wire.h>
# include <string>
BME280 bme280;
float gT, gH, gP;
// アクセスポイントのESSIDとパスワード
const char* ssid = "********";
const char* pass = "********";
//表示用
const String sokutei_jp[] = { "気圧", "温度", "湿度" };
// WebServerクラスの変数
WebServer server(80);
void setup() {
// シリアルポートの初期化
Serial.begin(115200);
if (!bme280.init()) {
Serial.println("Device error!");
}
Serial.println("Device init");
// アクセスポイントに接続
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
// ESP32のIPアドレスを出力
Serial.println("WiFi Connected.");
Serial.print("IP = ");
Serial.println(WiFi.localIP());
// 処理するアドレスを定義
server.on("/", handleRoot);
server.onNotFound(handleNotFound);
// Webサーバーを起動
server.begin();
}
void loop() {
//web出力
server.handleClient();
delay(1000);
}
void handleRoot() {
String html;
int i;
char text_gP[20], text_gT[20], text_gH[20];
gP = bme280.getPressure();
Serial.print(gP);
Serial.print("\n");
sprintf(text_gP, " %d Pa", int(gP));
gT = bme280.getTemperature();
Serial.print(gT);
Serial.print("\n");
sprintf(text_gT, " %3.2f C", gT);
gH = bme280.getHumidity();
Serial.print(gH);
Serial.print("\n");
sprintf(text_gH, " %3.2f %", gH);
// HTMLを組み立てる
html = "<!DOCTYPE html>";
html += "<html>";
html += "<head>";
html += "<meta charset=\"utf-8\">";
html += "<title>測定する</title>";
html += "</head>";
html += "<body>";
html += "<p>現在の測定値</p>";
html += "<ul>";
for (i = 0; i < 3; i++) {
html += "<li>";
html += sokutei_jp[i];
if (i==0){
html += text_gP;
}
if (i==1){
html += text_gT;
}
if (i==2){
html += text_gH;
}
html += "</a></li>";
}
html += "</ul>";
html += "</body>";
html += "</html>";
// HTMLを出力する
server.send(200, "text/html", html);
}
void handleNotFound(void) {
server.send(404, "text/plain", "Not Found");
}
BME280のcppと.hファイル
Seeed_BME280.cpp
Seeed_BME280.cpp
# include "Seeed_BME280.h"
bool BME280::init(int i2c_addr) {
uint8_t retry = 0;
uint8_t chip_id = 0;
_devAddr = i2c_addr;
Wire.begin();
while ((retry++ < 5) && (chip_id != 0x60)) {
chip_id = BME280Read8(BME280_REG_CHIPID);
#ifdef BMP280_DEBUG_PRINT
Serial.print("Read chip ID: ");
Serial.println(chip_id);
#endif
delay(100);
}
if (chip_id != 0x60){
Serial.println("Read Chip ID fail!");
return false;
}
dig_T1 = BME280Read16LE(BME280_REG_DIG_T1);
dig_T2 = BME280ReadS16LE(BME280_REG_DIG_T2);
dig_T3 = BME280ReadS16LE(BME280_REG_DIG_T3);
dig_P1 = BME280Read16LE(BME280_REG_DIG_P1);
dig_P2 = BME280ReadS16LE(BME280_REG_DIG_P2);
dig_P3 = BME280ReadS16LE(BME280_REG_DIG_P3);
dig_P4 = BME280ReadS16LE(BME280_REG_DIG_P4);
dig_P5 = BME280ReadS16LE(BME280_REG_DIG_P5);
dig_P6 = BME280ReadS16LE(BME280_REG_DIG_P6);
dig_P7 = BME280ReadS16LE(BME280_REG_DIG_P7);
dig_P8 = BME280ReadS16LE(BME280_REG_DIG_P8);
dig_P9 = BME280ReadS16LE(BME280_REG_DIG_P9);
dig_H1 = BME280Read8(BME280_REG_DIG_H1);
dig_H2 = BME280Read16LE(BME280_REG_DIG_H2);
dig_H3 = BME280Read8(BME280_REG_DIG_H3);
dig_H4 = (BME280Read8(BME280_REG_DIG_H4) << 4) | (0x0F & BME280Read8(BME280_REG_DIG_H4 + 1));
dig_H5 = (BME280Read8(BME280_REG_DIG_H5 + 1) << 4) | (0x0F & BME280Read8(BME280_REG_DIG_H5) >> 4);
dig_H6 = (int8_t)BME280Read8(BME280_REG_DIG_H6);
writeRegister(BME280_REG_CONTROLHUMID, 0x05); //Choose 16X oversampling
writeRegister(BME280_REG_CONTROL, 0xB7); //Choose 16X oversampling
return true;
}
float BME280::getTemperature(void) {
int32_t var1, var2;
int32_t adc_T = BME280Read24(BME280_REG_TEMPDATA);
// Check if the last transport successed
if (!isTransport_OK) {
return 0;
}
adc_T >>= 4;
var1 = (((adc_T >> 3) - ((int32_t)(dig_T1 << 1))) *
((int32_t)dig_T2)) >> 11;
var2 = (((((adc_T >> 4) - ((int32_t)dig_T1)) *
((adc_T >> 4) - ((int32_t)dig_T1))) >> 12) *
((int32_t)dig_T3)) >> 14;
t_fine = var1 + var2;
float T = (t_fine * 5 + 128) >> 8;
return T / 100;
}
uint32_t BME280::getPressure(void) {
int64_t var1, var2, p;
// Call getTemperature to get t_fine
getTemperature();
// Check if the last transport successed
if (!isTransport_OK) {
return 0;
}
int32_t adc_P = BME280Read24(BME280_REG_PRESSUREDATA);
adc_P >>= 4;
var1 = ((int64_t)t_fine) - 128000;
var2 = var1 * var1 * (int64_t)dig_P6;
var2 = var2 + ((var1 * (int64_t)dig_P5) << 17);
var2 = var2 + (((int64_t)dig_P4) << 35);
var1 = ((var1 * var1 * (int64_t)dig_P3) >> 8) + ((var1 * (int64_t)dig_P2) << 12);
var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)dig_P1) >> 33;
if (var1 == 0) {
return 0; // avoid exception caused by division by zero
}
p = 1048576 - adc_P;
p = (((p << 31) - var2) * 3125) / var1;
var1 = (((int64_t)dig_P9) * (p >> 13) * (p >> 13)) >> 25;
var2 = (((int64_t)dig_P8) * p) >> 19;
p = ((p + var1 + var2) >> 8) + (((int64_t)dig_P7) << 4);
return (uint32_t)p / 256;
}
uint32_t BME280::getHumidity(void) {
int32_t v_x1_u32r, adc_H;
// Call getTemperature to get t_fine
getTemperature();
// Check if the last transport successed
if (!isTransport_OK) {
return 0;
}
adc_H = BME280Read16(BME280_REG_HUMIDITYDATA);
v_x1_u32r = (t_fine - ((int32_t)76800));
v_x1_u32r = (((((adc_H << 14) - (((int32_t)dig_H4) << 20) - (((int32_t)dig_H5) * v_x1_u32r)) + ((
int32_t)16384)) >> 15) * (((((((v_x1_u32r * ((int32_t)dig_H6)) >> 10) * (((v_x1_u32r * ((int32_t)dig_H3)) >> 11) + ((
int32_t)32768))) >> 10) + ((int32_t)2097152)) * ((int32_t)dig_H2) + 8192) >> 14));
v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int32_t)dig_H1)) >> 4));
v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r);
v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r);
return (uint32_t)(v_x1_u32r >> 12) / 1024.0;
}
float BME280::calcAltitude(float pressure) {
if (!isTransport_OK) {
return 0;
}
float A = pressure / 101325;
float B = 1 / 5.25588;
float C = pow(A, B);
C = 1.0 - C;
C = C / 0.0000225577;
return C;
}
uint8_t BME280::BME280Read8(uint8_t reg) {
Wire.beginTransmission(_devAddr);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(_devAddr, 1);
// return 0 if slave didn't response
if (Wire.available() < 1) {
isTransport_OK = false;
return 0;
} else {
isTransport_OK = true;
}
return Wire.read();
}
uint16_t BME280::BME280Read16(uint8_t reg) {
uint8_t msb, lsb;
Wire.beginTransmission(_devAddr);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(_devAddr, 2);
// return 0 if slave didn't response
if (Wire.available() < 2) {
isTransport_OK = false;
return 0;
} else {
isTransport_OK = true;
}
msb = Wire.read();
lsb = Wire.read();
return (uint16_t) msb << 8 | lsb;
}
uint16_t BME280::BME280Read16LE(uint8_t reg) {
uint16_t data = BME280Read16(reg);
return (data >> 8) | (data << 8);
}
int16_t BME280::BME280ReadS16(uint8_t reg) {
return (int16_t)BME280Read16(reg);
}
int16_t BME280::BME280ReadS16LE(uint8_t reg) {
return (int16_t)BME280Read16LE(reg);
}
uint32_t BME280::BME280Read24(uint8_t reg) {
uint32_t data;
Wire.beginTransmission(_devAddr);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(_devAddr, 3);
// return 0 if slave didn't response
if (Wire.available() < 3) {
isTransport_OK = false;
return 0;
} else if (isTransport_OK == false) {
isTransport_OK = true;
if (!init(_devAddr)) {
#ifdef BMP280_DEBUG_PRINT
Serial.println("Device not connected or broken!");
#endif
}
}
data = Wire.read();
data <<= 8;
data |= Wire.read();
data <<= 8;
data |= Wire.read();
return data;
}
void BME280::writeRegister(uint8_t reg, uint8_t val) {
Wire.beginTransmission(_devAddr); // start transmission to device
Wire.write(reg); // send register address
Wire.write(val); // send value to write
Wire.endTransmission(); // end transmission
}
Seeed_BME280.h
Seeed_BME280.h
# pragma once
# ifndef _SEEED_BME280_H_
# define _SEEED_BME280_H_
# include <Arduino.h>
# include <Wire.h>
# define BME280_ADDRESS 0x76
# define BME280_REG_DIG_T1 0x88
# define BME280_REG_DIG_T2 0x8A
# define BME280_REG_DIG_T3 0x8C
# define BME280_REG_DIG_P1 0x8E
# define BME280_REG_DIG_P2 0x90
# define BME280_REG_DIG_P3 0x92
# define BME280_REG_DIG_P4 0x94
# define BME280_REG_DIG_P5 0x96
# define BME280_REG_DIG_P6 0x98
# define BME280_REG_DIG_P7 0x9A
# define BME280_REG_DIG_P8 0x9C
# define BME280_REG_DIG_P9 0x9E
# define BME280_REG_DIG_H1 0xA1
# define BME280_REG_DIG_H2 0xE1
# define BME280_REG_DIG_H3 0xE3
# define BME280_REG_DIG_H4 0xE4
# define BME280_REG_DIG_H5 0xE5
# define BME280_REG_DIG_H6 0xE7
# define BME280_REG_CHIPID 0xD0
# define BME280_REG_VERSION 0xD1
# define BME280_REG_SOFTRESET 0xE0
# define BME280_REG_CAL26 0xE1
# define BME280_REG_CONTROLHUMID 0xF2
# define BME280_REG_CONTROL 0xF4
# define BME280_REG_CONFIG 0xF5
# define BME280_REG_PRESSUREDATA 0xF7
# define BME280_REG_TEMPDATA 0xFA
# define BME280_REG_HUMIDITYDATA 0xFD
class BME280 {
public:
bool init(int i2c_addr = BME280_ADDRESS);
float getTemperature(void);
uint32_t getPressure(void);
uint32_t getHumidity(void);
float calcAltitude(float pressure);
private:
int _devAddr;
bool isTransport_OK;
// Calibration data
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
uint16_t dig_P1;
int16_t dig_P2;
int16_t dig_P3;
int16_t dig_P4;
int16_t dig_P5;
int16_t dig_P6;
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;
uint8_t dig_H1;
int16_t dig_H2;
uint8_t dig_H3;
int16_t dig_H4;
int16_t dig_H5;
int8_t dig_H6;
int32_t t_fine;
// private functions
uint8_t BME280Read8(uint8_t reg);
uint16_t BME280Read16(uint8_t reg);
uint16_t BME280Read16LE(uint8_t reg);
int16_t BME280ReadS16(uint8_t reg);
int16_t BME280ReadS16LE(uint8_t reg);
uint32_t BME280Read24(uint8_t reg);
void writeRegister(uint8_t reg, uint8_t val);
};
# endif