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

@ -8,3 +8,5 @@ bool bluetoothIsConnected();
// In main.cpp
uint32_t secondsUntilNextTemperatureMeasurement();
uint8_t getWakeupCause();

View File

@ -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();

View File

@ -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,

View File

@ -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);

View File

@ -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<uint8_t>(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");

View File

@ -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,18 +50,16 @@ void resetLastMeasurements() {
lastTemperatures[index].status == TemperatureStatus::sensorNotFound;
lastTemperatures[index].value = 0;
lastValidTemperatureTime[index] = 0;
lastMeasurements[index] = 0;
}
}
void storageConfigure() {
if (!isFirstRunAfterPowerOn) {
return;
}
isFirstRunAfterPowerOn = false;
void storageConfigure(bool isFirstRun) {
if (isFirstRun) {
// Ensure that first values are stored
resetLastMeasurements();
}
}
uint16_t getNumberOfBytesStoredInEEPROM() {
if (eepromIsConsideredEmpty) {
@ -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<uint8_t>(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<uint8_t>(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();
}

View File

@ -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