Home

The ESP8266 WiFi barometer with
BMP280 sensor and Arduino software


Barometer Glass and Brass
// Arduino WiFi Barometer as HTTP server -  V2.3 / 2018-01-17
// For ESP8266 and BMP280 sensor
// Copyright 2018 Pavel Janko, www.fancon.cz
// MIT license, http://opensource.org/licenses/MIT
// Tested with ARDUINO IDE 1.8.5, Arduino-ESP8266 2.4.0
// - WiFi Protected Setup with PBC ready
// - mDNS responder for connect by name
// - HTTP BASIC authentication
// - Supports simply OTA from browser with password
//   (with at least 1MB of memory for OTA)
//
// Added libraries:
// Adafruit Unified Sensor by Adafruit 1.0.2
// Adafruit BMP280 Library by Adafruit 1.0.2
// After flash restart the device !!!
//
// Connection :
// ESP8266-12   ------------------------------------------
// Vcc    -> Power 3.3V
// GND    -> Power GND
// CH_PD  -> Vcc
// RESET  -> resistor 10Kohms to Vcc and switch to GND
// GPIO0  -> resistor 10Kohms to Vcc and switch with
//           serial resistor around 330ohms to GND
// GPIO2  -> resistor 10Kohms to Vcc
// GPIO13 -> LED with serial resistor around 330ohms to GND
// GPIO15 -> resistor 10Kohms to GND
// Vcc    -> Vcc BMP280
// GND    -> GND BMP280
// GPIO4  -> SDA BMP280
// GPIO5  -> SCL BMP280
// --------------------------------------------------------
//
// To connect to an access point, hold down the button (switch on GPIO0) for about
// three seconds (LED on GPIO13 is lit permanently) and activate WPS
// (Wi-Fi Protected Setup) with PBC (Push Button Configuration) on your Access point.
//
// For mDNS install Bonjour to your Windows - https://support.apple.com/bonjour
// or Avahi for your Linux - https://www.avahi.org/
// mDNS name is defined as "barometer" below here. Just enter http://barometer.local
// into the browser. But in my case, mDNS is sometimes
// slower than a direct IP address.
//
// For web authentication set #define WWWAUTHENTI true and
// your WWWUSERNAME and WWWPASSWORD below only.
//
// For OTA activation set OTAUSER, OTAPASSWORD and then in operation
// write to browser address row http://barometer.local/firmware and upload your *.bin
// file.
// Default users and passwords are all "admin"
//
//   |--------------------------------------------------------------------|
//   |  Button - GPIO0    | LED - GPIO13|           Action                |
//   |--------------------------------------------------------------------|
//   | short press        |  ON or OFF  |              ---                |
//   | long press > 3sec. |     ON      | wait for WPS from Access point  |
//   |      ---           | flashes 4Hz | connection to WiFi              |
//   | before power on    |     ---     | flash mode                      |
//   |--------------------------------------------------------------------|
//
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#include <Wire.h>
#include <Ticker.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPUpdateServer.h>
#define LOCALALTUD      208.0      // Set your local altitude in meters
#define STDPRESSURE     1013.25    // Standard atmosferic pressure in hPa
#define WWWPAGEREFR     30         // Web page refresh time
#define WWWAUTHENTI      false     // Set true for web authentication
#define WWWUSERNAME     "admin"    // Set www user name
#define WWWPASSWORD     "admin"    // Set www user password
#define OTAUSER         "admin"    // Set OTA user
#define OTAPASSWORD     "admin"    // Set OTA password
#define OTAPATH         "/firmware"// Set path for update
#define MDNSNAME        "barometer"   // Set local mDNS name
#define BUTTONPIN       0          // GPIO0   button pin
#define SDAI2CPIN       4          // GPIO4   I2C SDA bus
#define SCLI2CPIN       5          // GPIO5   I2C SCL bus
#define BMP280ADDR      0x76       // Set BMP280 I2C address
#define LEDPIN          13         // GPIO13  LED 
#define BUTTONTIME      0.25       // Periodic time 0.25s for button read
#define WIFITIME        10         // Periodic time 10s for WiFi test
#define SENSORTIME      10         // Periodic time 10s for sensor read
#define SERVERPORT      80         // Server port
#define ROUDING         1
bool    LedState        = false;    // LED off
bool    ButtonFlag      = true;
bool    SensorFlag      = true;
bool    WifiFlag        = false;
char    ButtonCount     = 0;
float   SeaPressure     = 0;
float   Temperature     = 0;
float   PointerAngle    = 0;
float   TrendAngle      = 0;
ESP8266WebServer HttpServer(SERVERPORT);
ESP8266HTTPUpdateServer httpUpdater;
Ticker ButtonTick;           // Preparing for periodic button reading
Ticker WifiTick;             // preparing for periodic test WiFi connection
Ticker SensorTick;           // preparing for periodic sensor reading
Adafruit_BMP280 bmp280;
//-----------------------------------------------------------------
void setup(void) {
  WiFi.begin();
  Wire.begin(SDAI2CPIN, SCLI2CPIN);
  bmp280.begin(BMP280ADDR);
  pinMode(LEDPIN, OUTPUT);
  digitalWrite(LEDPIN, LedState);
  pinMode(BUTTONPIN, INPUT);
  /* wait for WiFi connect */
  while (WiFi.status() != WL_CONNECTED) {
    GetButton();
    delay(200);
    digitalWrite(LEDPIN, !LedState);
    delay(50);
    digitalWrite(LEDPIN, LedState);
  }
  ButtonTick.attach(BUTTONTIME, ButtonFlagSet);
  WifiTick.attach(WIFITIME, WifiFlagSet);
  SensorTick.attach(SENSORTIME, SensorFlagSet);
  httpUpdater.setup(&HttpServer, OTAPATH, OTAUSER, OTAPASSWORD);
  MDNS.begin(MDNSNAME);
  HttpServer.on("/", HTTP_GET, ModifySendPage);
  HttpServer.onNotFound(handleNotFound);
  HttpServer.begin();
}
//-----------------------------------------------------------------
void loop(void) {
  HttpServer.handleClient();       // Listen for HTTP requests from clients
  if (ButtonFlag) GetButton();     // Periodic serve button
  if (WifiFlag) WifiTest();        // Periodic test WiFi connection
  if (SensorFlag) SensorRead();    // Periodic sensor  reading
}//-----------------------------------------------------------------
void ModifySendPage(void) {
  if (WWWAUTHENTI == true) {
    /* request for www user/password from client */
    if (!HttpServer.authenticate(WWWUSERNAME, WWWPASSWORD))
      return HttpServer.requestAuthentication();
  }
  SendPage();
}
void SendPage() {
  String buff  = "<!DOCTYPE HTML><html><head><meta charset=\"UTF-8\"><meta http-equiv=\"refresh\" content=\"" + String(WWWPAGEREFR) + "\">\n";
  buff += "<title>Barometer</title></head><body style=\"background:skyblue\">\n";
  buff += "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"1000\" height=\"1000\">\n";
  buff += "<circle cx=\"500\" cy=\"500\" r=\"265\" fill=\"white\" stroke=\"#b46b41\" stroke-width=\"16\"/>\n";
  buff += "<circle cx=\"500\" cy=\"500\" r=\"265\" fill-opacity=\"0\" stroke=\"#c68762\" stroke-width=\"4\"/>\n";
  buff += "<g stroke=\"black\" stroke-width=\"2\" fill=\"none\">\n";
  buff += "<path id=\"SU\" d=\"M600 445a15 15 0 1 1 0 1h-15m45 0h15m-30 15v15m0-45v-15m11 41l10 10m-32-32l-10-10m10 32l-11 11m33-33l10-10\"/>\n";
  buff += "<path id=\"CL\" fill=\"white\" d=\"M350 455h70a-15-15 0 1 0-15-30a-15-10 0 1 0-40 0a5 5 0 0 0-15 30\"/>\n";
  buff += "<path id=\"RA\" d=\"M350 460l-5 10m20-10l-5 10m20-10l-5 10m20-10l-5 10m20-10l-5 10\"/>\n";
  buff += "<rect x=\"450\" y=\"590\" rx=\"5\" ry=\"5\" width=\"100\" height=\"40\"/>\n";
  buff += "<rect x=\"450\" y=\"635\" rx=\"5\" ry=\"5\" width=\"100\" height=\"40\"/>\n";
  buff += "</g><defs>\n";
  buff += "<g id=\"PO\">\n";
  buff += "<path d=\"M495 440A12 12 0 1 1 505 440L505 440 503 710 500 720 497 710z\" fill=\"black\"/>\n";
  buff += "<circle cx=\"500\" cy=\"500\" r=\"10\" stroke=\"black\" stroke-width=\"3\" fill=\"#CD7F32\"/>\n";
  buff += "<circle cx=\"500\" cy=\"500\" r=\"5\" fill=\"grey\"/>\n";
  buff += "<line stroke-width=\"2\" id=\"S\" x1=\"500\" y1=\"725\" x2=\"500\" y2=\"750\"/>\n";
  buff += "<line stroke-width=\"2\" id=\"M\" x1=\"500\" y1=\"720\" x2=\"500\" y2=\"750\"/>\n";
  buff += "<line stroke-width=\"2\" id=\"L\" x1=\"500\" y1=\"705\" x2=\"500\" y2=\"750\"/></g>\n";
  buff += "<g id=\"T\">\n";
  buff += "<use xlink:href=\"#L\" transform=\"rotate(30,500,500)\"/>\n";
  buff += "<g id=\"D\">\n";
  buff += "<use xlink:href=\"#S\" transform=\"rotate(33,500,500)\"/>\n";
  buff += "<use xlink:href=\"#S\" transform=\"rotate(36,500,500)\"/>\n";
  buff += "<use xlink:href=\"#S\" transform=\"rotate(39,500,500)\"/></g>\n";
  buff += "<use xlink:href=\"#S\" transform=\"rotate(42,500,500)\"/>\n";
  buff += "<use xlink:href=\"#M\" transform=\"rotate(45,500,500)\"/>\n";
  buff += "<use xlink:href=\"#S\" transform=\"rotate(48,500,500)\"/>\n";
  buff += "<use xlink:href=\"#D\" transform=\"rotate(18,500,500)\"/></g></defs>\n";
  buff += "<g stroke=\"black\">\n";
  buff += "<use xlink:href=\"#D\" transform=\"rotate(-12,500,500)\"/>\n";
  buff += "<g id=\"TT\">\n";
  buff += "<use xlink:href=\"#T\"/>\n";
  buff += "<use xlink:href=\"#T\" transform=\"rotate(30,500,500)\"/>\n";
  buff += "<use xlink:href=\"#T\" transform=\"rotate(60,500,500)\"/>\n";
  buff += "<use xlink:href=\"#T\" transform=\"rotate(90,500,500)\"/>\n";
  buff += "<use xlink:href=\"#T\" transform=\"rotate(120,500,500)\"/></g>\n";
  buff += "<use xlink:href=\"#TT\" transform=\"rotate(150,500,500)\"/>\n";
  buff += "<use xlink:href=\"#L\" transform=\"rotate(330,500,500)\"/>\n";
  buff += "<use xlink:href=\"#D\" transform=\"rotate(300,500,500)\"/></g>\n";
  buff += "<g font-family=\"arial\" font-size=\"28\" font-weight=\"normal\" font-style=\"italic\" fill=\"black\" >\n";
  buff += "<text x=\"330\" y=\"600\">970</text>\n";
  buff += "<text x=\"305\" y=\"500\">980</text>\n";
  buff += "<text x=\"330\" y=\"400\">990</text>\n";
  buff += "<text x=\"390\" y=\"350\">1000</text>\n";
  buff += "<text x=\"465\" y=\"320\">1010</text>\n";
  buff += "<text x=\"540\" y=\"350\">1020</text>\n";
  buff += "<text x=\"605\" y=\"400\">1030</text>\n";
  buff += "<text x=\"635\" y=\"500\">1040</text>\n";
  buff += "<text x=\"610\" y=\"600\">1050</text>\n";
  buff += "<text x=\"470\" y=\"740\">hPa</text>\n";
  buff += "<text x=\"455\" y=\"620\" fill=\"green\">" + String(SeaPressure / 100, ROUDING) + "</text>\n";
  buff += "<text x=\"555\" y=\"620\" font-size=\"24\" >hPa</text>\n";
  buff += "<text x=\"455\" y=\"665\" fill=\"red\">" + String(Temperature, ROUDING) + "</text>\n";
  buff += "<text x=\"560\" y=\"665\" font-size=\"24\">C</text>\n";
  buff += "<circle cx=\"560\" cy=\"645\" r=\"3\" fill=\"white\" stroke=\"black\" stroke-width=\"2\"/></g>\n";
  buff += "<g stroke=\"black\" stroke-width=\"2\" fill=\"none\">\n";
  buff += "<use xlink:href=\"#SU\" transform=\"translate(-127,-90)\"/>\n";
  buff += "<use xlink:href=\"#CL\" transform=\"translate(123,-65)\"/></g>\n";
  buff += "<use xlink:href=\"#S\" stroke=\"green\" transform=\"rotate(" + String(TrendAngle) + ",500,500)\"/>\n";
  buff += "<use xlink:href=\"#PO\" transform=\"rotate(" + String(PointerAngle) + ",500,500)\"/>\n";
  buff += "</svg></body></html>";
  HttpServer.send(200, "text/html", buff);
}
/* Send HTTP status 404 Not Found */
void handleNotFound() {
  HttpServer.send(404, "text/plain", "404: Not found");
}
/* Read button on GPIO0*/
void GetButton(void) {
  /* short press butoon to change state of LED */
  if (digitalRead(BUTTONPIN) == false ) ++ButtonCount;
  if (digitalRead(BUTTONPIN) == true && ButtonCount > 1 && ButtonCount < 12 ) {
    LedState = !LedState;  //  change LED
    digitalWrite(LEDPIN, LedState);
    ButtonCount = 0;
  }
  /* long press button - WPS mode */
  if (ButtonCount > 12) {
    LedState = true;        //  LED ON
    digitalWrite(LEDPIN, LedState);
    ButtonTick.detach();    // Stop Tickers
    WifiTick.detach();
    SensorTick.detach();
    /* Wait for release button */
    while (!digitalRead(BUTTONPIN))yield();
    delay(100);
    StartWpsWaiting();
  }
  if (digitalRead(BUTTONPIN) == true ) ButtonCount = 0;
  ButtonFlag = false;
}
/* Service Wi-Fi Protected Setup with Push Button Configuration */
void StartWpsWaiting(void) {
  WiFi.persistent(false);
  WiFi.mode(WIFI_STA);
  bool    RafHo = false;
  String  HowDelka = "";
  /* Wait for access point WPS */
  do {
    RafHo = WiFi.beginWPSConfig();
    HowDelka = WiFi.SSID();
  }
  while (RafHo == false || HowDelka.length() == 0);
  delay(500);
  ESP.restart();
}
/* If disconnected WiFi then restart */
void WifiTest(void) {
  if (WiFi.status() != WL_CONNECTED)ESP.restart();
  WifiFlag = false;
}
void SensorRead(void) {
  Temperature = bmp280.readTemperature();
  float Pressure = bmp280.readPressure();
  SeaPressure = Pressure / pow(1 - (LOCALALTUD / 44330), 5.255);
  PointerAngle = (30 + (SeaPressure / 100 - 960) * 3);
  TrendAngle = (30 + (STDPRESSURE - 960) * 3);
  SensorFlag = false;
}
void ButtonFlagSet(void) {
  ButtonFlag = true;
}
void WifiFlagSet(void) {
  WifiFlag = true;
}
void SensorFlagSet(void) {
  SensorFlag = true;
}

Here is Arduino sketch for download

Forum

Jan / 2018

UP