2021年12月4日 星期六

ESP32 Plot Sensor Readings in Real Time Charts – Web Server

 ESP32 Plot Sensor Readings in Real Time Charts – Web Server

BME280 -->BMP280

BMP280 高精度大氣壓強傳感器模塊高度計


















/*********

  Rui Santos

  Complete project details at https://RandomNerdTutorials.com

  

  Permission is hereby granted, free of charge, to any person obtaining a copy

  of this software and associated documentation files.

  

  The above copyright notice and this permission notice shall be included in all

  copies or substantial portions of the Software.

*********/


// Import required libraries

//#ifdef ESP32

#include <WiFi.h>

#include <ESPAsyncWebServer.h>

#include <SPIFFS.h>

/*

#else

  #include <Arduino.h>

  #include <ESP8266WiFi.h>

  #include <Hash.h>

  #include <ESPAsyncTCP.h>

  #include <ESPAsyncWebServer.h>

  #include <FS.h>

#endif

*/

#include <Wire.h>

#include <Adafruit_Sensor.h>

//#include <Adafruit_BME280.h>

#include <Adafruit_BMP280.h>

/*#include <SPI.h>

#define BME_SCK 18

#define BME_MISO 19

#define BME_MOSI 23

#define BME_CS 5*/


#define SEALEVELPRESSURE_HPA (1013.25)

#define BMP280_I2C_ADDRESS  0x76

Adafruit_BMP280 bmp280; // I2C

//Adafruit_BME280 bme; // I2C


//Adafruit_BME280 bme(BME_CS); // hardware SPI

//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI


// Replace with your network credentials

//const char* ssid = "REPLACE_WITH_YOUR_SSID";

//const char* password = "REPLACE_WITH_YOUR_PASSWORD";

const char* ssid     = "PTS-2F";

const char* password = "PTS6662594";


// Create AsyncWebServer object on port 80

AsyncWebServer server(80);


String readBMP280Temperature() {

  // Read temperature as Celsius (the default)

  float t =  bmp280.readTemperature();  // get temperature

  // Convert temperature to Fahrenheit

  //t = 1.8 * t + 32;

  if (isnan(t)) {    

    Serial.println("Failed to read from BMP280 sensor!");

    return "";

  }

  else {

    Serial.println(t);

    return String(t);

  }

}


String readBMP280Altitude() {

  float h = bmp280.readAltitude(1013.25); // get altitude (this should be adjusted to your local forecast)

  if (isnan(h)) {

    Serial.println("Failed to read from BMP280 sensor!");

    return "";

  }

  else {

    Serial.println(h);

    return String(h);

  }

}


String readBMP280Pressure() {

  float p = bmp280.readPressure()/ 100.0F;     // get pressure ;

  if (isnan(p)) {

    Serial.println("Failed to read from BMP280 sensor!");

    return "";

  }

  else {

    Serial.println(p);

    return String(p);

  }

}


void setup(){

  // Serial port for debugging purposes

  Serial.begin(115200);

  

  // default settings

  // (you can also pass in a Wire library object like &Wire2)

  if (!bmp280.begin(BMP280_I2C_ADDRESS))

  {  

    Serial.println("Could not find a valid BMP280 sensor, check wiring!");

    while (1);

  }


  // Initialize SPIFFS

  if(!SPIFFS.begin()){

    Serial.println("An Error has occurred while mounting SPIFFS");

    return;

  }


  // Connect to Wi-Fi

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {

    delay(1000);

    Serial.println("Connecting to WiFi..");

  }


  // Print ESP32 Local IP Address

  Serial.println(WiFi.localIP());


  // Route for root / web page

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){

    request->send(SPIFFS, "/index.html");

  });

  server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){

    request->send_P(200, "text/plain", readBMP280Temperature().c_str());

  });

  server.on("/altitude", HTTP_GET, [](AsyncWebServerRequest *request){

    request->send_P(200, "text/plain", readBMP280Altitude().c_str());

  });

  server.on("/pressure", HTTP_GET, [](AsyncWebServerRequest *request){

    request->send_P(200, "text/plain", readBMP280Pressure().c_str());

  });


  // Start server

  server.begin();

}

 

void loop(){

  

}

the HTML File index.html

<!DOCTYPE HTML><html>
<!-- Rui Santos - Complete project details at https://RandomNerdTutorials.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. -->
<head>
  <meta charset="utf-8">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://code.highcharts.com/highcharts.js"></script>
  <style>
    body {
      min-width: 310px;
    	max-width: 800px;
    	height: 400px;
      margin: 0 auto;
    }
    h2 {
      font-family: Arial;
      font-size: 2.5rem;
      text-align: center;
    }
  </style>
</head>
<body>
  <h2>ESP Weather Station</h2>
  <div id="chart-temperature" class="container"></div>
  <div id="chart-altitude" class="container"></div>
  <div id="chart-pressure" class="container"></div>
</body>
<script>
var chartT = new Highcharts.Chart({
  chart:{ renderTo : 'chart-temperature' },
  title: { text: 'BME280 Temperature' },
  series: [{
    showInLegend: false,
    data: []
  }],
  plotOptions: {
    line: { animation: false,
      dataLabels: { enabled: true }
    },
    series: { color: '#059e8a' }
  },
  xAxis: { type: 'datetime',
    dateTimeLabelFormats: { second: '%H:%M:%S' }
  },
  yAxis: {
    title: { text: 'Temperature (Celsius)' }
    //title: { text: 'Temperature (Fahrenheit)' }
  },
  credits: { enabled: false }
});
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var x = (new Date()).getTime(),
          y = parseFloat(this.responseText);
      //console.log(this.responseText);
      if(chartT.series[0].data.length > 40) {
        chartT.series[0].addPoint([x, y], true, true, true);
      } else {
        chartT.series[0].addPoint([x, y], true, false, true);
      }
    }
  };
  xhttp.open("GET", "/temperature", true);
  xhttp.send();
}, 30000 ) ;

var chartH = new Highcharts.Chart({
  chart:{ renderTo:'chart-altitude' },
  title: { text: 'BME280 Altitude' },
  series: [{
    showInLegend: false,
    data: []
  }],
  plotOptions: {
    line: { animation: false,
      dataLabels: { enabled: true }
    }
  },
  xAxis: {
    type: 'datetime',
    dateTimeLabelFormats: { second: '%H:%M:%S' }
  },
  yAxis: {
    title: { text: 'Altitude (m)' }
  },
  credits: { enabled: false }
});
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var x = (new Date()).getTime(),
          y = parseFloat(this.responseText);
      //console.log(this.responseText);
      if(chartH.series[0].data.length > 40) {
        chartH.series[0].addPoint([x, y], true, true, true);
      } else {
        chartH.series[0].addPoint([x, y], true, false, true);
      }
    }
  };
  xhttp.open("GET", "/altitude", true);
  xhttp.send();
}, 30000 ) ;

var chartP = new Highcharts.Chart({
  chart:{ renderTo:'chart-pressure' },
  title: { text: 'BME280 Pressure' },
  series: [{
    showInLegend: false,
    data: []
  }],
  plotOptions: {
    line: { animation: false,
      dataLabels: { enabled: true }
    },
    series: { color: '#18009c' }
  },
  xAxis: {
    type: 'datetime',
    dateTimeLabelFormats: { second: '%H:%M:%S' }
  },
  yAxis: {
    title: { text: 'Pressure (hPa)' }
  },
  credits: { enabled: false }
});
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var x = (new Date()).getTime(),
          y = parseFloat(this.responseText);
      //console.log(this.responseText);
      if(chartP.series[0].data.length > 40) {
        chartP.series[0].addPoint([x, y], true, true, true);
      } else {
        chartP.series[0].addPoint([x, y], true, false, true);
      }
    }
  };
  xhttp.open("GET", "/pressure", true);
  xhttp.send();
}, 30000 ) ;
</script>
</html>

Uploading Code and Files

Save the code as ESP_Chart_Web_Server or download all project files here. Go to Sketch > Show Sketch Folder, and create a folder called data. Inside that folder you should save the HTML file created previously.





Now you need to upload the HTML file to the ESP32 or ESP8266 filesystem. Go to Tools ESP32/ESP8266 Data Sketch Upload and wait for the files to be uploaded.

ESP32/ESP8266 Data Sketch Upload filesystem Uploader

Then, upload the code to your board. Make sure you have the right board and COM port selected. Also, make sure you’ve inserted your networks credentials in the code.

Arduino IDE upload sketch button

When everything is successfully uploaded, open the Serial Monitor at a baud rate of 115200. Press the board “EN/RST” button, and it should print its IP address.

ESP32 ESP8266 IP Address Serial Monitor

沒有留言:

張貼留言

Messaging API作為替代方案

  LINE超好用功能要沒了!LINE Notify明年3月底終止服務,有什麼替代方案? LINE Notify將於2025年3月31日結束服務,官方建議改用Messaging API作為替代方案。 //CHANNEL_ACCESS_TOKEN = 'Messaging ...