From 16f71c888bf1dec111c9f47072fe7f6ace09eae1 Mon Sep 17 00:00:00 2001 From: Christoph Hagen Date: Tue, 13 Jun 2023 16:59:17 +0200 Subject: [PATCH] Fix initial temp bug, transmit wake reason --- include/bluetooth.h | 4 ++- include/storage.h | 4 +-- include/temperature.h | 2 +- src/bluetooth.cpp | 9 +++--- src/main.cpp | 28 +++++++++------- src/storage.cpp | 74 +++++++++++++++++++++++++------------------ src/temperature.cpp | 6 +++- 7 files changed, 74 insertions(+), 53 deletions(-) diff --git a/include/bluetooth.h b/include/bluetooth.h index 9bf4642..042f607 100644 --- a/include/bluetooth.h +++ b/include/bluetooth.h @@ -7,4 +7,6 @@ void bluetoothConfigure(); bool bluetoothIsConnected(); // In main.cpp -uint32_t secondsUntilNextTemperatureMeasurement(); \ No newline at end of file +uint32_t secondsUntilNextTemperatureMeasurement(); + +uint8_t getWakeupCause(); \ No newline at end of file diff --git a/include/storage.h b/include/storage.h index 68c0e8d..7fb8b67 100644 --- a/include/storage.h +++ b/include/storage.h @@ -26,7 +26,7 @@ constexpr long maximumTemperature = temperatureShiftForStorage + 255 * 500; constexpr uint8_t temperatureMaximumValue = 255; -void storageConfigure(); +void storageConfigure(bool isFirstRun); /** * @brief Save temperatures for both temperature sensors @@ -38,8 +38,6 @@ void storageConfigure(); */ void saveTemperatures(Temperature* temperatures); -void saveTemperatureAtCurrentIndex(Temperature temp); - uint16_t getTotalNumberOfStoredBytes(); uint16_t getNumberOfMeasurements(); diff --git a/include/temperature.h b/include/temperature.h index 8aa4766..5f39687 100644 --- a/include/temperature.h +++ b/include/temperature.h @@ -15,7 +15,7 @@ constexpr uint8_t temperatureSensorNotAvailable = 0; constexpr uint8_t temperatureSensorFailure = 1; constexpr uint8_t temperatureMinimumValue = 2; -enum class TemperatureStatus { +enum class TemperatureStatus: uint8_t { sensorNotFound = temperatureSensorNotAvailable, diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index 3ff2607..848e88b 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -309,6 +309,9 @@ void fillInfo() { memcpy(bluetoothDataBuffer + bluetoothDataCount, &value, sizeof(uint16_t)); bluetoothDataCount += sizeof(uint16_t); + bluetoothDataBuffer[bluetoothDataCount] = getWakeupCause(); + bluetoothDataCount += sizeof(uint8_t); + setResponse(BluetoothResponse::success); } @@ -328,7 +331,7 @@ void getRecordingData(uint8_t* buffer, uint16_t count) { memcpy(&byteOffset, buffer + sizeof(uint16_t), sizeof(uint16_t)); bluetoothDataCount = getRecordedBytesAtOffset(bluetoothDataBuffer, byteOffset, byteCount); - setResponseWithoutData(BluetoothResponse::success); + setResponse(BluetoothResponse::success); } void clearRecordingBuffer(uint8_t* buffer, uint16_t count) { @@ -358,10 +361,6 @@ void setDeviceStartTime(uint8_t* buffer, uint16_t count) { setResponseWithoutData(BluetoothResponse::success); } -1694498815 -1686227379 - - void bluetoothDidReceiveData(uint8_t* buffer, uint16_t count) { if (count < 1) { setResponseWithoutData(BluetoothResponse::invalidCommand); diff --git a/src/main.cpp b/src/main.cpp index d018ae0..1f2af2a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,10 +14,18 @@ constexpr uint32_t delayWaitingForNextMeasurementMS = 50; // Time is measured in seconds since power-on via RTC clock RTC_DATA_ATTR uint32_t nextTimeToMeasureTemperatureSeconds = 0; +RTC_DATA_ATTR bool isFirstStart = true; + // Indicate the time until the device should stay awake // Updated when button is pressed uint32_t sleepStartAfterButtonPressOrConnection = 0; +uint8_t wakeupCauseByte = 0; + +uint8_t getWakeupCause() { + return wakeupCauseByte; +} + /** * @brief Check if enough time has passed for the next temperature measurement * @@ -99,13 +107,7 @@ void updateStayAwakeTime() { * @return false Keep the device awake */ bool shouldGoToSleep() { - if (bluetoothIsConnected()) { - return false; - } - if (time(NULL) <= sleepStartAfterButtonPressOrConnection) { - return false; - } - return true; + return time(NULL) > sleepStartAfterButtonPressOrConnection; } void enableLED() { @@ -123,7 +125,7 @@ void enableLED() { void setup() { // No need for serial output in production - // Serial.begin(serialBaudRate); + Serial.begin(serialBaudRate); // LED useless inside case // enableLED(); @@ -134,11 +136,13 @@ void setup() { // Enable EEPROM to persist measurements // Only needed if sufficient measurements are in RTC memory - storageConfigure(); + storageConfigure(isFirstStart); // Configure bluetooth if wake button was pressed - if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_EXT0) { - Serial.println("Wake after button press"); + esp_sleep_wakeup_cause_t wakeupCause = esp_sleep_get_wakeup_cause(); + wakeupCauseByte = static_cast(wakeupCause); + if (wakeupCause == ESP_SLEEP_WAKEUP_EXT0 || isFirstStart) { + Serial.println("First start or button press"); bluetoothConfigure(); updateStayAwakeTime(); } @@ -148,9 +152,9 @@ void setup() { temperatureConfigure(); Serial.println("Setup complete"); + isFirstStart = false; } - void loop() { if (shouldMeasureTemperature()) { Serial.println("Measuring"); diff --git a/src/storage.cpp b/src/storage.cpp index cd312e6..24e5c9d 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -21,6 +21,7 @@ RTC_DATA_ATTR bool isFirstRunAfterPowerOn = true; // Keeps the last valid temperatures for each sensor RTC_DATA_ATTR Temperature lastTemperatures[temperatureSensorCount]; RTC_DATA_ATTR uint32_t lastValidTemperatureTime[temperatureSensorCount]; +RTC_DATA_ATTR uint8_t lastMeasurements[temperatureSensorCount] = {0, 0}; bool didSetupEEPROM = false; @@ -49,17 +50,15 @@ void resetLastMeasurements() { lastTemperatures[index].status == TemperatureStatus::sensorNotFound; lastTemperatures[index].value = 0; lastValidTemperatureTime[index] = 0; + lastMeasurements[index] = 0; } } -void storageConfigure() { - if (!isFirstRunAfterPowerOn) { - return; +void storageConfigure(bool isFirstRun) { + if (isFirstRun) { + // Ensure that first values are stored + resetLastMeasurements(); } - isFirstRunAfterPowerOn = false; - - // Ensure that first values are stored - resetLastMeasurements(); } uint16_t getNumberOfBytesStoredInEEPROM() { @@ -104,9 +103,25 @@ void saveByteAtCurrentIndex(uint8_t byte) { dataIndex += 1; } -uint8_t byteForAbsoluteTemperature(long temp) { +uint8_t byteForAbsoluteTemperature(Temperature* temp) { + switch (temp->status) { + case TemperatureStatus::sensorError: + return temperatureSensorFailure; + case TemperatureStatus::sensorNotFound: + return temperatureSensorNotAvailable; + case TemperatureStatus::temperatureIsValid: + break; + default: + return temperatureSensorNotAvailable; + } // Convert to temperature range - long converted = (temp - (temperatureShiftForStorage)) / 500; + if (temp->value > 87500) { + return temperatureMaximumValue; + } + if (temp->value < -39000) { + return temperatureMinimumValue; + } + long converted = (temp->value - (temperatureShiftForStorage)) / 500; if (converted < temperatureMinimumValue) { return temperatureMinimumValue; } @@ -116,16 +131,10 @@ uint8_t byteForAbsoluteTemperature(long temp) { return converted; } -void saveTemperatureAtCurrentIndex(Temperature temp) { - if (temp.status != TemperatureStatus::temperatureIsValid) { - saveByteAtCurrentIndex(static_cast(temp.status)); - return; - } - uint8_t byte = byteForAbsoluteTemperature(temp.value); - saveByteAtCurrentIndex(byte); -} - bool needsAbsoluteTemperatureRecording(Temperature* temperatures) { + if (numberOfMeasurements == 0) { + return true; + } for (uint8_t index = 0; index < temperatureSensorCount; index += 1) { if (temperatures[index].status != TemperatureStatus::temperatureIsValid) { // Error value can be encoded as differential (0x00) @@ -145,10 +154,13 @@ void saveTemperatures(Temperature* temperatures) { // Write absolute temperatures saveByteAtCurrentIndex(absoluteTemperatureIndicator); for (uint8_t sensorIndex = 0; sensorIndex < temperatureSensorCount; sensorIndex += 1) { - saveTemperatureAtCurrentIndex(temperatures[sensorIndex]); - if (temperatures[sensorIndex].status == TemperatureStatus::temperatureIsValid) { + Temperature* temp = &temperatures[sensorIndex]; + uint8_t byte = byteForAbsoluteTemperature(temp); + saveByteAtCurrentIndex(byte); + lastMeasurements[sensorIndex] = byte; + if (temp->status == TemperatureStatus::temperatureIsValid) { // Only update if temperature is valid - lastTemperatures[sensorIndex] = temperatures[sensorIndex]; + lastTemperatures[sensorIndex] = *temp; lastValidTemperatureTime[sensorIndex] = time(NULL); } } @@ -156,9 +168,10 @@ void saveTemperatures(Temperature* temperatures) { // Calculate temperature differences uint8_t valueToStore = 0; for (uint8_t index = 0; index < temperatureSensorCount; index += 1) { + Temperature* temp = &temperatures[index]; uint8_t diff = 0; // Indicate sensor error - if (temperatures[index].status == TemperatureStatus::temperatureIsValid) { - diff = (lastTemperatures[index].value - temperatures[index].value) / 500 + 8; + if (temp->status == TemperatureStatus::temperatureIsValid) { + diff = (lastTemperatures[index].value - temp->value) / 500 + 8; } if (index % 2) { // Store second bits @@ -169,11 +182,16 @@ void saveTemperatures(Temperature* temperatures) { // Store in first four bits valueToStore = (diff << 4); } + lastMeasurements[index] = byteForAbsoluteTemperature(temp); - if (temperatures[index].status == TemperatureStatus::temperatureIsValid) { + if (temp->status == TemperatureStatus::temperatureIsValid) { // Only update if temperature is valid - lastTemperatures[index] = temperatures[index]; + lastTemperatures[index].status = TemperatureStatus::temperatureIsValid; + lastTemperatures[index].value = temp->value; lastValidTemperatureTime[index] = time(NULL); + } else if (lastTemperatures[index].status != TemperatureStatus::temperatureIsValid) { + lastTemperatures[index].value = 0; + lastValidTemperatureTime[index] = 0; } } // Ensure storage with uneven number of sensors @@ -199,10 +217,7 @@ uint32_t getTotalNumberOfMeasurements() { } uint8_t getLastTemperature(uint8_t sensorIndex) { - if (lastTemperatures[sensorIndex].status != TemperatureStatus::temperatureIsValid) { - return static_cast(lastTemperatures[sensorIndex].status); - } - return byteForAbsoluteTemperature(lastTemperatures[sensorIndex].value); + return lastMeasurements[sensorIndex]; } uint16_t getTimeSinceValidTemperature(uint8_t sensorIndex) { @@ -234,5 +249,4 @@ void discardAllRecordedBytes() { dataIndex = 0; numberOfDiscardedMeasurements += numberOfMeasurements; numberOfMeasurements = 0; - resetLastMeasurements(); } \ No newline at end of file diff --git a/src/temperature.cpp b/src/temperature.cpp index 6d6c2f1..bbf2202 100644 --- a/src/temperature.cpp +++ b/src/temperature.cpp @@ -176,6 +176,11 @@ void temperatureConfigure() { Serial.println("Failed to set temperature limits and resolution"); return; } + + // Do an update once, because otherwise the temperature will be 85° for some reason + Temperature samples[TEMPERATURE_SENSOR_MAX_COUNT]; + delay(500); // Delay seems to prevent missing sensors on first measurement + temperaturePerformUpdate(samples); didConfigureTemperatureSensors = true; } @@ -184,7 +189,6 @@ void temperaturePerformUpdate(Temperature* temperatures) { // Convert temperature on all sensors connected sensorInterface.convertTempAll(DSTherm::SCAN_BUS, TEMPERATURE_SENSOR_PARASITE_POWER); - DSTherm::Scratchpad* scratchpad = getScratchpad(); // Read sensors one by one