added temperature and altitude estimation from atmospheric pressure
This commit is contained in:
parent
fd1143d732
commit
532cca230b
@ -51,7 +51,7 @@ void DataLogger::open()
|
|||||||
file = SPIFFS.open(fileName, FILE_WRITE);
|
file = SPIFFS.open(fileName, FILE_WRITE);
|
||||||
if(!isOpen()) Serial.println("DataLogger: failed to open file");
|
if(!isOpen()) Serial.println("DataLogger: failed to open file");
|
||||||
|
|
||||||
if(!file.print("time,speed,battery voltage,battery output current\n")) Serial.println("DataLogger: failed to write to file");
|
if(!file.print("time,speed,battery voltage,battery output current,temperature,altitude\n")) Serial.println("DataLogger: failed to write to file");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataLogger::close()
|
void DataLogger::close()
|
||||||
@ -69,7 +69,7 @@ void DataLogger::log(unsigned long timeMilliseconds, const Entry& entry)
|
|||||||
if((lastEntry.isDifferent(entry) || currentTime >= lastLogTime + 20.0f) && currentTime >= lastLogTime + 0.2f)
|
if((lastEntry.isDifferent(entry) || currentTime >= lastLogTime + 20.0f) && currentTime >= lastLogTime + 0.2f)
|
||||||
{
|
{
|
||||||
char line[128];
|
char line[128];
|
||||||
sprintf(line, "%.3f,%.3f,%.3f,%.3f\n", currentTime, entry.speed, entry.batteryVoltage, entry.batteryOutputCurrent);
|
sprintf(line, "%.3f,%.3f,%.3f,%.3f,%.1f,%.1f\n", currentTime, entry.speed, entry.batteryVoltage, entry.batteryOutputCurrent, entry.temperature, entry.altitude);
|
||||||
file.print(line);
|
file.print(line);
|
||||||
|
|
||||||
lastEntry = entry;
|
lastEntry = entry;
|
||||||
|
@ -9,6 +9,8 @@ public:
|
|||||||
float batteryVoltage = 0.0f; // V
|
float batteryVoltage = 0.0f; // V
|
||||||
float batteryOutputCurrent = 0.0f; // A
|
float batteryOutputCurrent = 0.0f; // A
|
||||||
float speed = 0.0f; // m/s
|
float speed = 0.0f; // m/s
|
||||||
|
float temperature = 0.0f; // in °C
|
||||||
|
float altitude = 0.0f; // in m
|
||||||
|
|
||||||
bool isDifferent(const Entry& other)
|
bool isDifferent(const Entry& other)
|
||||||
{
|
{
|
||||||
@ -16,7 +18,9 @@ public:
|
|||||||
return
|
return
|
||||||
std::abs(batteryVoltage - other.batteryVoltage) > 0.1f * scale
|
std::abs(batteryVoltage - other.batteryVoltage) > 0.1f * scale
|
||||||
|| std::abs(batteryOutputCurrent - other.batteryOutputCurrent) > 0.1f * scale
|
|| std::abs(batteryOutputCurrent - other.batteryOutputCurrent) > 0.1f * scale
|
||||||
|| std::abs(speed - other.speed) > 0.1f;
|
|| std::abs(speed - other.speed) > 0.1f
|
||||||
|
|| std::abs(temperature - other.temperature) > 0.5f * scale
|
||||||
|
|| std::abs(altitude - other.altitude) > 0.5f * scale;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include <SPIFFS.h>
|
#include <SPIFFS.h>
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
|
||||||
|
#include <Dps310.h>
|
||||||
|
|
||||||
#include "ADC.h"
|
#include "ADC.h"
|
||||||
#include "OTA.h"
|
#include "OTA.h"
|
||||||
#include "DataLogger.h"
|
#include "DataLogger.h"
|
||||||
@ -13,14 +15,19 @@
|
|||||||
|
|
||||||
#include "wifi-credentials.h"
|
#include "wifi-credentials.h"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#define DUMMY_DATA 0
|
#define DUMMY_DATA 0
|
||||||
|
|
||||||
AsyncWebServer server(80);
|
AsyncWebServer server(80);
|
||||||
|
|
||||||
ADC currentSensor(36);
|
ADC currentSensor(36);
|
||||||
ADC batterySensor(39);
|
ADC batterySensor(39);
|
||||||
|
Dps310 pressureSensor = Dps310();
|
||||||
const int8_t speedSensorPin = 13;
|
const int8_t speedSensorPin = 13;
|
||||||
const int8_t debugLedPin = 2;
|
const int8_t debugLedPin = 2;
|
||||||
|
const int8_t I2C_SDA = 12;
|
||||||
|
const int8_t I2C_SCL = 15;
|
||||||
|
|
||||||
const float wheelDiameterInches = 20;
|
const float wheelDiameterInches = 20;
|
||||||
const int numImpulsesPerTurn = 2;
|
const int numImpulsesPerTurn = 2;
|
||||||
@ -28,6 +35,8 @@ const float wheelCircumferenceMeters = wheelDiameterInches * 0.0254f * 3.1415f /
|
|||||||
|
|
||||||
uint16_t batteryVoltage = 0; // in mV
|
uint16_t batteryVoltage = 0; // in mV
|
||||||
uint16_t batteryOutputCurrent = 0; // in mV
|
uint16_t batteryOutputCurrent = 0; // in mV
|
||||||
|
int16_t temperature = 0; // in tenth of °C
|
||||||
|
int32_t altitude = 0; // in mm above sea level (can be negative if below sea level, or depending on atmospheric conditions)
|
||||||
|
|
||||||
WiFiMulti wifiMulti;
|
WiFiMulti wifiMulti;
|
||||||
wl_status_t wifi_STA_status = WL_NO_SHIELD;
|
wl_status_t wifi_STA_status = WL_NO_SHIELD;
|
||||||
@ -163,10 +172,16 @@ void setup()
|
|||||||
|
|
||||||
OTA.begin();
|
OTA.begin();
|
||||||
|
|
||||||
|
Wire.begin(I2C_SDA, I2C_SCL);
|
||||||
|
|
||||||
|
pressureSensor.begin(Wire);
|
||||||
|
|
||||||
server.on("/api/status", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/api/status", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
int v = batteryVoltage;
|
int v = batteryVoltage;
|
||||||
int c = batteryOutputCurrent;
|
int c = batteryOutputCurrent;
|
||||||
int s = (int)(getSpeed() * 1000.0f + 0.5f);
|
int s = (int)(getSpeed() * 1000.0f + 0.5f);
|
||||||
|
int t = temperature;
|
||||||
|
int alt = altitude;
|
||||||
|
|
||||||
const char* logFileName = DataLogger::get().currentLogFileName();
|
const char* logFileName = DataLogger::get().currentLogFileName();
|
||||||
if(String(logFileName).startsWith("/log/")) logFileName += 5;
|
if(String(logFileName).startsWith("/log/")) logFileName += 5;
|
||||||
@ -175,7 +190,7 @@ void setup()
|
|||||||
int usedSize = (int)(SPIFFS.usedBytes() / 1000);
|
int usedSize = (int)(SPIFFS.usedBytes() / 1000);
|
||||||
|
|
||||||
char json[128];
|
char json[128];
|
||||||
sprintf(json, "{\"v\":%d,\"c\":%d,\"s\":%d,\"log\":\"%s\",\"tot\":%d,\"used\":%d}", v, c, s, logFileName, totalSize, usedSize);
|
sprintf(json, "{\"v\":%d,\"c\":%d,\"s\":%d,\"t\":%d,\"alt\":%d,\"log\":\"%s\",\"tot\":%d,\"used\":%d}", v, c, s, t, alt, logFileName, totalSize, usedSize);
|
||||||
request->send(200, "text/json", json);
|
request->send(200, "text/json", json);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -295,11 +310,73 @@ void handle_ADC_measures()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_pressure_measure()
|
||||||
|
{
|
||||||
|
const uint8_t oversampling = 7;
|
||||||
|
int16_t ret;
|
||||||
|
|
||||||
|
float temp; // in Celcius degrees
|
||||||
|
ret = pressureSensor.measureTempOnce(temp, oversampling);
|
||||||
|
if(ret != 0)
|
||||||
|
{
|
||||||
|
Serial.print("Failed to measure temperature: "); Serial.println(ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
temperature = (int16_t)(temp * 10.0f + 0.5f);
|
||||||
|
|
||||||
|
float pressure; // in Pa
|
||||||
|
pressureSensor.measurePressureOnce(pressure, oversampling);
|
||||||
|
if(ret != 0)
|
||||||
|
{
|
||||||
|
Serial.print("Failed to measure pressure: "); Serial.println(ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PressureToAltitude
|
||||||
|
{
|
||||||
|
float pressure; // in Pa
|
||||||
|
float altitude; // in meters above sea level
|
||||||
|
};
|
||||||
|
const PressureToAltitude altitudeTable[] =
|
||||||
|
{
|
||||||
|
{ 101325.0f, 0.0f },
|
||||||
|
{ 100000.0f, 111.0f },
|
||||||
|
{ 95000.0f, 540.0f },
|
||||||
|
{ 90000.0f, 989.0f },
|
||||||
|
{ 85000.0f, 1457.0f },
|
||||||
|
{ 80000.0f, 1949.0f },
|
||||||
|
{ 75000.0f, 2466.0f },
|
||||||
|
{ 70000.0f, 3012.0f },
|
||||||
|
{ 65000.0f, 3591.0f },
|
||||||
|
{ 60000.0f, 4206.0f },
|
||||||
|
{ 55000.0f, 4865.0f },
|
||||||
|
};
|
||||||
|
const int8_t altitudeTableNumValues = sizeof(altitudeTable)/sizeof(altitudeTable[0]);
|
||||||
|
|
||||||
|
float alt = -std::numeric_limits<float>::max();
|
||||||
|
for(int8_t i = 0; i < altitudeTableNumValues - 1; ++i)
|
||||||
|
{
|
||||||
|
if(i == altitudeTableNumValues - 2 || pressure >= altitudeTable[i+1].pressure)
|
||||||
|
{
|
||||||
|
const auto& p = altitudeTable[i];
|
||||||
|
const auto& n = altitudeTable[i+1];
|
||||||
|
alt = (pressure - p.pressure) / (n.pressure - p.pressure) * (n.altitude - p.altitude) + p.altitude;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
altitude = (int32_t)(alt * 1000.0f + 0.5f);
|
||||||
|
|
||||||
|
/*Serial.print("temperature="); Serial.print(temp); Serial.print("°C");
|
||||||
|
Serial.print(" pressure="); Serial.print(pressure); Serial.print("Pa");
|
||||||
|
Serial.print(" altitude="); Serial.print(altitude); Serial.println("mm");*/
|
||||||
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
OTA.handle();
|
OTA.handle();
|
||||||
handle_wifi_connection();
|
handle_wifi_connection();
|
||||||
handle_ADC_measures();
|
handle_ADC_measures();
|
||||||
|
handle_pressure_measure(); // also measures temperature
|
||||||
|
|
||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
static DataLogger::Entry entry;
|
static DataLogger::Entry entry;
|
||||||
@ -333,5 +410,5 @@ void loop()
|
|||||||
}
|
}
|
||||||
DataLogger::get().log(now, entry);
|
DataLogger::get().log(now, entry);
|
||||||
|
|
||||||
delay(10);
|
delay(DataLogger::get().isOpen() ? 10 : 1000);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user