I am trying to use a pressure sensor on an ESP32 and then plot a live updating graph. The code I used worked perfectly when using my home network but when making the switch to creating my own network and then sending the data it fails.
FIX - since the softAP can't access the internet, the online script resource I was referring to failed to load.
Changes to the HTML files are reflected after using LittleFS to upload the data and the Javascript file runs when running the HTML file independently, but when running it through the ESP32 there is nothing. I have attached the .ino,.html and the .js files.
I can even see live data sent to the html when i go the the IP address/readings as coded. It's just the js file that doesn't run
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <LittleFS.h>
#include <Arduino_JSON.h>
#define ZERO_SAMPLES 50
#define COUNTS_PER_PSI 735990 // Increased to further scale down PSI values
#define PSI_TO_CMH2O 70.307 // Conversion factor from PSI to cmH2O
#define DRIFT_THRESHOLD 0.1 // PSI threshold to consider as "no pressure"
#define STABLE_TIME 3000 // Time in ms that readings need to be stable for re-zeroing
#define DRIFT_SAMPLES 10
// Replace with your network credentials
const char* ssid = "ESP32";
const char* password = NULL;
long zeroOffset = 8290303;
bool isCalibrated = false;
int sampleCount = 0;
long calibrationSum = 0;
// Drift compensation variables
unsigned long stableStartTime = 0;
bool isStable = false;
float lastPSI = 0;
int stableSampleCount = 0;
const int inputpin = 15;
const int outputpin = 2;
char pressuredata[40];
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
// Create an Event Source on /events
AsyncEventSource events("/events");
// Json Variable to Hold Sensor Readings
JSONVar readings;
// Timer variables
unsigned long lastTime = 0;
unsigned long timerDelay = 750;
// GPIO where the DS18B20 sensors are connected to
// Setup a oneWire instance to communicate with OneWire devices (DS18B20)
// Pass our oneWire reference to Dallas Temperature sensor
// Initialize LittleFS
void initLittleFS() {
if (!LittleFS.begin()) {
Serial.println("An error has occurred while mounting LittleFS");
}
else{
Serial.println("LittleFS mounted successfully");
}
}
// Initialize WiFi
/* void initWiFi() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("Connecting to WiFi ..");
//Serial.println(cmH20)
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(1000);
}
Serial.println(WiFi.localIP());
} */
void checkAndUpdateZero(long rawPressure, float currentPSI) {
// Check if current pressure is close to zero
if (abs(currentPSI - 1) < DRIFT_THRESHOLD) { // Remember we're applying -1 offset to PSI
if (!isStable) {
// Start tracking stable period
isStable = true;
stableStartTime = millis();
stableSampleCount = 1;
} else {
stableSampleCount++;
// Check if we've been stable long enough and have enough samples
if (stableSampleCount >= DRIFT_SAMPLES &&
(millis() - stableStartTime) >= STABLE_TIME) {
// Update zero offset
zeroOffset = rawPressure;
stableSampleCount = 0;
isStable = false;
}
}
} else {
// Reset stable tracking if pressure is not near zero
isStable = false;
stableSampleCount = 0;
}
}
float convertToPSI(long rawValue, long zero) {
return (float)(rawValue - zero) / COUNTS_PER_PSI;
}
String readPressureRaw() {
while (digitalRead(inputpin)) {}
long result = 0;
noInterrupts();
for (int i = 0; i < 24; i++) {
digitalWrite(outputpin, HIGH);
digitalWrite(outputpin, LOW);
result = (result << 1);
if (digitalRead(inputpin)) {
result++;
}
}
for (char i = 0; i < 3; i++) {
digitalWrite(outputpin, HIGH);
digitalWrite(outputpin, LOW); }
interrupts();
long pressure = result ^ 0x800000;
if (!isCalibrated){
calibrationSum += pressure;
sampleCount++;
readings["sensor1"] = String(0,3);
if (sampleCount >= 15){
long zeroOffset = calibrationSum/15;
isCalibrated = true;
}
} else {
float psi = convertToPSI(pressure , zeroOffset);
float cmH20 = psi * 70.307;
checkAndUpdateZero(pressure,psi);
String pressuredata = String(cmH20,3);
readings["sensor1"] = pressuredata;
}
String jsonresult = JSON.stringify(readings);
return jsonresult;
//Serial.println(zeroOffset);
}
void setup() {
pinMode(inputpin,INPUT);
pinMode(outputpin, OUTPUT);
// Serial port for debugging purposes
Serial.begin(115200);
//initWiFi();
Serial.println();
// Setting the ESP as an access point
Serial.print("Setting AP (Access Point)…");
// Remove the password parameter, if you want the AP (Access Point) to be open
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
initLittleFS();
digitalWrite(outputpin, LOW);
for(int i = 0; i < 10; i++) {
digitalWrite(outputpin, HIGH);
digitalWrite(outputpin, LOW);
}
// Web Server Root URL
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(LittleFS, "/index.html", "text/html");
});
server.serveStatic("/", LittleFS, "/");
// Request for the latest sensor readings
server.on("/readings", HTTP_GET, [](AsyncWebServerRequest *request){
String json = readPressureRaw();
request->send(200, "application/json", json);
json = String();
});
events.onConnect([](AsyncEventSourceClient *client){
if(client->lastId()){
Serial.printf("Client reconnected! Last message ID that it got is: %u\n", client->lastId());
}
// send event with message "hello!", id current millis
// and set reconnect delay to 1 second
client->send("hello!", NULL, millis(), 10000);
});
server.addHandler(&events);
// Start server
server.begin();
}
void loop() {
if ((millis() - lastTime) > timerDelay) {
// Send Events to the client with the Sensor Readings Every 10 seconds
events.send("ping",NULL,millis());
events.send(readPressureRaw().c_str(),"new_readings" ,millis());
lastTime = millis();
}
}
<!DOCTYPE html>
<html>
<head>
<title>DASHBOARD</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/png" href="favicon.png">
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://code.highcharts.com/highcharts.js"></script>
</head>
<body>
<div class="topnav">
<h1 id="header"> Pressure Waveform and Control Data</h1>
</div>
<div class="content">
<div class="card-grid">
<div class="card">
<p id = "id1" class="card-title">Pressure Chart</p>
<div id="chart-pressure" class="chart-container"></div>
</div>
</div>
</div>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
window.addEventListener('load', getReadings);
var chartT = new Highcharts.Chart({
chart:{
renderTo:'chart-pressure'
},
series: [
{
name: 'Pressure #21',
type: 'line',
color: '#101D42',
},
],
title: {
text: undefined
},
xAxis: {
type: 'datetime',
dateTimeLabelFormats: { second: '%H:%M:%S' }
},
yAxis: {
title: {
text: 'Pressure '
}
},
credits: {
enabled: false
}
});
function plotPressure(jsonValue) {
var keys = Object.keys(jsonValue);
var x = (new Date()).getTime();
const key = keys[0];
var y = Number(jsonValue[key]);
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);
}
}
function getReadings(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myObj = JSON.parse(this.responseText);
console.log(myObj);
plotPressure(myObj);
}
};
xhr.open("GET", "/readings", true);
xhr.send();
}
if (!!window.EventSource) {
var source = new EventSource('/events');
source.addEventListener('open', function(e) {
console.log("Events Connected");
}, false);
source.addEventListener('error', function(e) {
if (e.target.readyState != EventSource.OPEN) {
console.log("Events Disconnected");
}
}, false);
source.addEventListener('message', function(e) {
console.log("message", e.data);
}, false);
source.addEventListener('new_readings', function(e) {
console.log("new_readings", e.data);
var myObj = JSON.parse(e.data);
plotPressure(myObj);
}, false);
}
https://code.highcharts.com/highcharts.jsis not accessible from the SoftAP network which is not connected to the Internet