Fix initial temp bug, transmit wake reason

This commit is contained in:
Christoph Hagen 2023-06-13 16:59:17 +02:00
parent 7f43cfedf2
commit 16f71c888b
7 changed files with 74 additions and 53 deletions

View File

@ -7,4 +7,6 @@ void bluetoothConfigure();
bool bluetoothIsConnected(); bool bluetoothIsConnected();
// In main.cpp // In main.cpp
uint32_t secondsUntilNextTemperatureMeasurement(); uint32_t secondsUntilNextTemperatureMeasurement();
uint8_t getWakeupCause();

View File

@ -26,7 +26,7 @@ constexpr long maximumTemperature = temperatureShiftForStorage + 255 * 500;
constexpr uint8_t temperatureMaximumValue = 255; constexpr uint8_t temperatureMaximumValue = 255;
void storageConfigure(); void storageConfigure(bool isFirstRun);
/** /**
* @brief Save temperatures for both temperature sensors * @brief Save temperatures for both temperature sensors
@ -38,8 +38,6 @@ void storageConfigure();
*/ */
void saveTemperatures(Temperature* temperatures); void saveTemperatures(Temperature* temperatures);
void saveTemperatureAtCurrentIndex(Temperature temp);
uint16_t getTotalNumberOfStoredBytes(); uint16_t getTotalNumberOfStoredBytes();
uint16_t getNumberOfMeasurements(); uint16_t getNumberOfMeasurements();

View File

@ -15,7 +15,7 @@ constexpr uint8_t temperatureSensorNotAvailable = 0;
constexpr uint8_t temperatureSensorFailure = 1; constexpr uint8_t temperatureSensorFailure = 1;
constexpr uint8_t temperatureMinimumValue = 2; constexpr uint8_t temperatureMinimumValue = 2;
enum class TemperatureStatus { enum class TemperatureStatus: uint8_t {
sensorNotFound = temperatureSensorNotAvailable, sensorNotFound = temperatureSensorNotAvailable,

View File

@ -309,6 +309,9 @@ void fillInfo() {
memcpy(bluetoothDataBuffer + bluetoothDataCount, &value, sizeof(uint16_t)); memcpy(bluetoothDataBuffer + bluetoothDataCount, &value, sizeof(uint16_t));
bluetoothDataCount += sizeof(uint16_t); bluetoothDataCount += sizeof(uint16_t);
bluetoothDataBuffer[bluetoothDataCount] = getWakeupCause();
bluetoothDataCount += sizeof(uint8_t);
setResponse(BluetoothResponse::success); setResponse(BluetoothResponse::success);
} }
@ -328,7 +331,7 @@ void getRecordingData(uint8_t* buffer, uint16_t count) {
memcpy(&byteOffset, buffer + sizeof(uint16_t), sizeof(uint16_t)); memcpy(&byteOffset, buffer + sizeof(uint16_t), sizeof(uint16_t));
bluetoothDataCount = getRecordedBytesAtOffset(bluetoothDataBuffer, byteOffset, byteCount); bluetoothDataCount = getRecordedBytesAtOffset(bluetoothDataBuffer, byteOffset, byteCount);
setResponseWithoutData(BluetoothResponse::success); setResponse(BluetoothResponse::success);
} }
void clearRecordingBuffer(uint8_t* buffer, uint16_t count) { void clearRecordingBuffer(uint8_t* buffer, uint16_t count) {
@ -358,10 +361,6 @@ void setDeviceStartTime(uint8_t* buffer, uint16_t count) {
setResponseWithoutData(BluetoothResponse::success); setResponseWithoutData(BluetoothResponse::success);
} }
1694498815
1686227379
void bluetoothDidReceiveData(uint8_t* buffer, uint16_t count) { void bluetoothDidReceiveData(uint8_t* buffer, uint16_t count) {
if (count < 1) { if (count < 1) {
setResponseWithoutData(BluetoothResponse::invalidCommand); setResponseWithoutData(BluetoothResponse::invalidCommand);

View File

@ -14,10 +14,18 @@ constexpr uint32_t delayWaitingForNextMeasurementMS = 50;
// Time is measured in seconds since power-on via RTC clock // Time is measured in seconds since power-on via RTC clock
RTC_DATA_ATTR uint32_t nextTimeToMeasureTemperatureSeconds = 0; RTC_DATA_ATTR uint32_t nextTimeToMeasureTemperatureSeconds = 0;
RTC_DATA_ATTR bool isFirstStart = true;
// Indicate the time until the device should stay awake // Indicate the time until the device should stay awake
// Updated when button is pressed // Updated when button is pressed
uint32_t sleepStartAfterButtonPressOrConnection = 0; 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 * @brief Check if enough time has passed for the next temperature measurement
* *
@ -99,13 +107,7 @@ void updateStayAwakeTime() {
* @return false Keep the device awake * @return false Keep the device awake
*/ */
bool shouldGoToSleep() { bool shouldGoToSleep() {
if (bluetoothIsConnected()) { return time(NULL) > sleepStartAfterButtonPressOrConnection;
return false;
}
if (time(NULL) <= sleepStartAfterButtonPressOrConnection) {
return false;
}
return true;
} }
void enableLED() { void enableLED() {
@ -123,7 +125,7 @@ void enableLED() {
void setup() { void setup() {
// No need for serial output in production // No need for serial output in production
// Serial.begin(serialBaudRate); Serial.begin(serialBaudRate);
// LED useless inside case // LED useless inside case
// enableLED(); // enableLED();
@ -134,11 +136,13 @@ void setup() {
// Enable EEPROM to persist measurements // Enable EEPROM to persist measurements
// Only needed if sufficient measurements are in RTC memory // Only needed if sufficient measurements are in RTC memory
storageConfigure(); storageConfigure(isFirstStart);
// Configure bluetooth if wake button was pressed // Configure bluetooth if wake button was pressed
if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_EXT0) { esp_sleep_wakeup_cause_t wakeupCause = esp_sleep_get_wakeup_cause();
Serial.println("Wake after button press"); wakeupCauseByte = static_cast<uint8_t>(wakeupCause);
if (wakeupCause == ESP_SLEEP_WAKEUP_EXT0 || isFirstStart) {
Serial.println("First start or button press");
bluetoothConfigure(); bluetoothConfigure();
updateStayAwakeTime(); updateStayAwakeTime();
} }
@ -148,9 +152,9 @@ void setup() {
temperatureConfigure(); temperatureConfigure();
Serial.println("Setup complete"); Serial.println("Setup complete");
isFirstStart = false;
} }
void loop() { void loop() {
if (shouldMeasureTemperature()) { if (shouldMeasureTemperature()) {
Serial.println("Measuring"); Serial.println("Measuring");

View File

@ -21,6 +21,7 @@ RTC_DATA_ATTR bool isFirstRunAfterPowerOn = true;
// Keeps the last valid temperatures for each sensor // Keeps the last valid temperatures for each sensor
RTC_DATA_ATTR Temperature lastTemperatures[temperatureSensorCount]; RTC_DATA_ATTR Temperature lastTemperatures[temperatureSensorCount];
RTC_DATA_ATTR uint32_t lastValidTemperatureTime[temperatureSensorCount]; RTC_DATA_ATTR uint32_t lastValidTemperatureTime[temperatureSensorCount];
RTC_DATA_ATTR uint8_t lastMeasurements[temperatureSensorCount] = {0, 0};
bool didSetupEEPROM = false; bool didSetupEEPROM = false;
@ -49,17 +50,15 @@ void resetLastMeasurements() {
lastTemperatures[index].status == TemperatureStatus::sensorNotFound; lastTemperatures[index].status == TemperatureStatus::sensorNotFound;
lastTemperatures[index].value = 0; lastTemperatures[index].value = 0;
lastValidTemperatureTime[index] = 0; lastValidTemperatureTime[index] = 0;
lastMeasurements[index] = 0;
} }
} }
void storageConfigure() { void storageConfigure(bool isFirstRun) {
if (!isFirstRunAfterPowerOn) { if (isFirstRun) {
return; // Ensure that first values are stored
resetLastMeasurements();
} }
isFirstRunAfterPowerOn = false;
// Ensure that first values are stored
resetLastMeasurements();
} }
uint16_t getNumberOfBytesStoredInEEPROM() { uint16_t getNumberOfBytesStoredInEEPROM() {
@ -104,9 +103,25 @@ void saveByteAtCurrentIndex(uint8_t byte) {
dataIndex += 1; 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 // 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) { if (converted < temperatureMinimumValue) {
return temperatureMinimumValue; return temperatureMinimumValue;
} }
@ -116,16 +131,10 @@ uint8_t byteForAbsoluteTemperature(long temp) {
return converted; return converted;
} }
void saveTemperatureAtCurrentIndex(Temperature temp) {
if (temp.status != TemperatureStatus::temperatureIsValid) {
saveByteAtCurrentIndex(static_cast<uint8_t>(temp.status));
return;
}
uint8_t byte = byteForAbsoluteTemperature(temp.value);
saveByteAtCurrentIndex(byte);
}
bool needsAbsoluteTemperatureRecording(Temperature* temperatures) { bool needsAbsoluteTemperatureRecording(Temperature* temperatures) {
if (numberOfMeasurements == 0) {
return true;
}
for (uint8_t index = 0; index < temperatureSensorCount; index += 1) { for (uint8_t index = 0; index < temperatureSensorCount; index += 1) {
if (temperatures[index].status != TemperatureStatus::temperatureIsValid) { if (temperatures[index].status != TemperatureStatus::temperatureIsValid) {
// Error value can be encoded as differential (0x00) // Error value can be encoded as differential (0x00)
@ -145,10 +154,13 @@ void saveTemperatures(Temperature* temperatures) {
// Write absolute temperatures // Write absolute temperatures
saveByteAtCurrentIndex(absoluteTemperatureIndicator); saveByteAtCurrentIndex(absoluteTemperatureIndicator);
for (uint8_t sensorIndex = 0; sensorIndex < temperatureSensorCount; sensorIndex += 1) { for (uint8_t sensorIndex = 0; sensorIndex < temperatureSensorCount; sensorIndex += 1) {
saveTemperatureAtCurrentIndex(temperatures[sensorIndex]); Temperature* temp = &temperatures[sensorIndex];
if (temperatures[sensorIndex].status == TemperatureStatus::temperatureIsValid) { uint8_t byte = byteForAbsoluteTemperature(temp);
saveByteAtCurrentIndex(byte);
lastMeasurements[sensorIndex] = byte;
if (temp->status == TemperatureStatus::temperatureIsValid) {
// Only update if temperature is valid // Only update if temperature is valid
lastTemperatures[sensorIndex] = temperatures[sensorIndex]; lastTemperatures[sensorIndex] = *temp;
lastValidTemperatureTime[sensorIndex] = time(NULL); lastValidTemperatureTime[sensorIndex] = time(NULL);
} }
} }
@ -156,9 +168,10 @@ void saveTemperatures(Temperature* temperatures) {
// Calculate temperature differences // Calculate temperature differences
uint8_t valueToStore = 0; uint8_t valueToStore = 0;
for (uint8_t index = 0; index < temperatureSensorCount; index += 1) { for (uint8_t index = 0; index < temperatureSensorCount; index += 1) {
Temperature* temp = &temperatures[index];
uint8_t diff = 0; // Indicate sensor error uint8_t diff = 0; // Indicate sensor error
if (temperatures[index].status == TemperatureStatus::temperatureIsValid) { if (temp->status == TemperatureStatus::temperatureIsValid) {
diff = (lastTemperatures[index].value - temperatures[index].value) / 500 + 8; diff = (lastTemperatures[index].value - temp->value) / 500 + 8;
} }
if (index % 2) { if (index % 2) {
// Store second bits // Store second bits
@ -169,11 +182,16 @@ void saveTemperatures(Temperature* temperatures) {
// Store in first four bits // Store in first four bits
valueToStore = (diff << 4); valueToStore = (diff << 4);
} }
lastMeasurements[index] = byteForAbsoluteTemperature(temp);
if (temperatures[index].status == TemperatureStatus::temperatureIsValid) { if (temp->status == TemperatureStatus::temperatureIsValid) {
// Only update if temperature is valid // Only update if temperature is valid
lastTemperatures[index] = temperatures[index]; lastTemperatures[index].status = TemperatureStatus::temperatureIsValid;
lastTemperatures[index].value = temp->value;
lastValidTemperatureTime[index] = time(NULL); 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 // Ensure storage with uneven number of sensors
@ -199,10 +217,7 @@ uint32_t getTotalNumberOfMeasurements() {
} }
uint8_t getLastTemperature(uint8_t sensorIndex) { uint8_t getLastTemperature(uint8_t sensorIndex) {
if (lastTemperatures[sensorIndex].status != TemperatureStatus::temperatureIsValid) { return lastMeasurements[sensorIndex];
return static_cast<uint8_t>(lastTemperatures[sensorIndex].status);
}
return byteForAbsoluteTemperature(lastTemperatures[sensorIndex].value);
} }
uint16_t getTimeSinceValidTemperature(uint8_t sensorIndex) { uint16_t getTimeSinceValidTemperature(uint8_t sensorIndex) {
@ -234,5 +249,4 @@ void discardAllRecordedBytes() {
dataIndex = 0; dataIndex = 0;
numberOfDiscardedMeasurements += numberOfMeasurements; numberOfDiscardedMeasurements += numberOfMeasurements;
numberOfMeasurements = 0; numberOfMeasurements = 0;
resetLastMeasurements();
} }

View File

@ -176,6 +176,11 @@ void temperatureConfigure() {
Serial.println("Failed to set temperature limits and resolution"); Serial.println("Failed to set temperature limits and resolution");
return; 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; didConfigureTemperatureSensors = true;
} }
@ -184,7 +189,6 @@ void temperaturePerformUpdate(Temperature* temperatures) {
// Convert temperature on all sensors connected // Convert temperature on all sensors connected
sensorInterface.convertTempAll(DSTherm::SCAN_BUS, TEMPERATURE_SENSOR_PARASITE_POWER); sensorInterface.convertTempAll(DSTherm::SCAN_BUS, TEMPERATURE_SENSOR_PARASITE_POWER);
DSTherm::Scratchpad* scratchpad = getScratchpad(); DSTherm::Scratchpad* scratchpad = getScratchpad();
// Read sensors one by one // Read sensors one by one