Save/load state of BME680 to intern EEPROM

This commit is contained in:
Maximilian Grau 2021-11-01 16:56:50 +01:00
parent 664c61026e
commit 9405b3d8b8

View file

@ -3,12 +3,14 @@
#include "main.h" #include "main.h"
#include "semphr.h" #include "semphr.h"
#include "spi.h" #include "spi.h"
#include "stm32l1xx_hal_flash_ex.h"
#include "task.h" #include "task.h"
#include <cstring> #include <cstring>
#include "BME68x-Sensor-API/bme68x.h" #include "BME68x-Sensor-API/bme68x.h"
#include "BSEC/bsec_interface.h" #include "BSEC/bsec_interface.h"
#include "SSD1306_SPI.hpp"
#include "oled-driver/Renderer.hpp" #include "oled-driver/Renderer.hpp"
extern QueueHandle_t spiMutex; extern QueueHandle_t spiMutex;
@ -51,8 +53,10 @@ float iaq, rawTemperature, pressure, rawHumidity, gasResistance, stabStatus, run
uint8_t iaqAccuracy, staticIaqAccuracy, co2Accuracy, breathVocAccuracy, compGasAccuracy, uint8_t iaqAccuracy, staticIaqAccuracy, co2Accuracy, breathVocAccuracy, compGasAccuracy,
gasPercentageAcccuracy; gasPercentageAcccuracy;
// uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE]; uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE];
// uint8_t workBuffer[BSEC_MAX_WORKBUFFER_SIZE]; uint8_t workBuffer[BSEC_MAX_WORKBUFFER_SIZE];
constexpr uintptr_t EepromAddress = FLASH_EEPROM_BASE;
void setChipSelect(bool state) void setChipSelect(bool state)
{ {
@ -310,33 +314,94 @@ void printBmeSensorData()
{ {
renderer.clearAll(); renderer.clearAll();
snprintf(buffer, MaximumChars, const auto MaxTextWidth = renderer.getLineWidth("1000hPa");
"%d°C, %luhPa, %d%%\nIAQ: %d, Accuracy: %d\nCO2: %dppm\n%d, %d, %d - %lukOhm",
snprintf(buffer, MaximumChars, "%d°C\n%luhPa\n%d%%\nAcc: %d",
static_cast<int>(temperature), // static_cast<int>(temperature), //
bmeData[numberOfData - 1].pressure / 100, // bmeData[numberOfData - 1].pressure / 100, //
static_cast<int>(humidity), // static_cast<int>(humidity), //
static_cast<int>(iaq), // iaqAccuracy);
iaqAccuracy, // renderer.print({128, 0}, buffer, Renderer::Alignment::Right);
static_cast<int>(co2Equivalent), // renderer.drawVerticalLine(OledWidth - MaxTextWidth - 2, 0, OledPages - 1);
bmeData[numberOfData - 1].status, //
bmeData[numberOfData - 1].gas_index, //
bmeData[numberOfData - 1].gas_wait, //
bmeData[numberOfData - 1].gas_resistance / 1000);
renderer.print({0, 0}, buffer); if (iaqAccuracy == 0)
snprintf(buffer, MaximumChars, "IAQ:---\n---ppm\n");
else
snprintf(buffer, MaximumChars, "IAQ:%d\n%dppm\n",
static_cast<int>(iaq), //
static_cast<int>(co2Equivalent));
renderer.print({0, 0}, buffer, Renderer::Alignment::Left, 2);
renderer.render(); renderer.render();
} }
void readStateFromEeprom()
{
uint8_t sizeOfData = *reinterpret_cast<uint8_t *>(EepromAddress);
if (sizeOfData != BSEC_MAX_STATE_BLOB_SIZE)
return;
// Existing state in EEPROM
for (uint8_t i = 0; i < BSEC_MAX_STATE_BLOB_SIZE; i++)
{
bsecState[i] = *reinterpret_cast<uint8_t *>(EepromAddress + i + 1);
}
bsec_set_state(bsecState, BSEC_MAX_STATE_BLOB_SIZE, workBuffer, sizeof(workBuffer));
}
void writeStateToEeprom()
{
if (iaqAccuracy != 3)
return;
uint32_t numberSerializedState = BSEC_MAX_STATE_BLOB_SIZE;
auto status = bsec_get_state(0, bsecState, BSEC_MAX_STATE_BLOB_SIZE, workBuffer,
BSEC_MAX_STATE_BLOB_SIZE, &numberSerializedState);
if (status != BSEC_OK)
return;
HAL_FLASHEx_DATAEEPROM_Unlock();
// write size
HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_BYTE, EepromAddress,
BSEC_MAX_STATE_BLOB_SIZE);
for (uint8_t i = 0; i < BSEC_MAX_STATE_BLOB_SIZE; i++)
{
HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_BYTE, EepromAddress + i + 1,
bsecState[i]);
}
HAL_FLASHEx_DATAEEPROM_Lock();
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
extern "C" void sensorTask(void *) extern "C" void sensorTask(void *)
{ {
initDisplay(); initDisplay();
bmeSensorInit(); bmeSensorInit();
readStateFromEeprom();
uint16_t counter = 0;
while (1) while (1)
{ {
bmeRun(); bmeRun();
bsecRun(); bsecRun();
printBmeSensorData(); printBmeSensorData();
if (counter++ >= 100)
{
initDisplay();
counter = 0;
writeStateToEeprom();
}
vTaskDelay(pdMS_TO_TICKS(10));
} }
} }