Transmit last temperature time

This commit is contained in:
Christoph Hagen 2023-06-03 08:14:30 +02:00
parent 3727fdb694
commit c4d8116cfd
4 changed files with 118 additions and 70 deletions

View File

@ -17,6 +17,8 @@ constexpr size_t rtcStorageSize = 7600;
constexpr size_t maxEepromSize = 13350; constexpr size_t maxEepromSize = 13350;
constexpr size_t eepromSize = 13350; constexpr size_t eepromSize = 13350;
constexpr size_t totalStorageSize = rtcStorageSize + eepromSize;
// The minimum temperature to store, in millidegrees celcius // The minimum temperature to store, in millidegrees celcius
// True minimum will be higher by 1°, since two values are reserved // True minimum will be higher by 1°, since two values are reserved
constexpr long temperatureShiftForStorage = -40000; constexpr long temperatureShiftForStorage = -40000;
@ -44,6 +46,8 @@ uint16_t getNumberOfMeasurements();
uint8_t getLastTemperature(uint8_t sensorIndex); uint8_t getLastTemperature(uint8_t sensorIndex);
uint16_t getTimeSinceValidTemperature(uint8_t sensorIndex);
uint16_t getRecordedBytesAtOffset(uint8_t* buffer, uint16_t offset, uint16_t count); uint16_t getRecordedBytesAtOffset(uint8_t* buffer, uint16_t offset, uint16_t count);
void discardAllRecordedBytes(); void discardAllRecordedBytes();

View File

@ -30,7 +30,7 @@ uint8_t* bluetoothResponse;
size_t bluetoothDataCount = 0; size_t bluetoothDataCount = 0;
void bluetoothStartAdvertising(); void bluetoothStartAdvertising();
void bluetoothDidReceiveData(uint8_t* buffer, size_t count); void bluetoothDidReceiveData(uint8_t* buffer, uint16_t count);
class BluetoothConnection: public BLEServerCallbacks { class BluetoothConnection: public BLEServerCallbacks {
@ -215,17 +215,9 @@ uint16_t readNumberFromReceivedBuffer(uint8_t* buffer) {
return *((uint16_t*) buffer + 1); return *((uint16_t*) buffer + 1);
} }
void bluetoothDidReceiveData(uint8_t* buffer, size_t count) { void fillInfo() {
if (count < 1) {
setResponseWithoutData(BluetoothResponse::invalidCommand);
return;
}
uint32_t currentTime;
uint16_t value; uint16_t value;
BluetoothRequest request = static_cast<BluetoothRequest>(buffer[0]);
switch (request) {
case BluetoothRequest::getInfo:
// BluetoothResponse::success // BluetoothResponse::success
setResponse(BluetoothResponse::success); setResponse(BluetoothResponse::success);
@ -255,7 +247,7 @@ void bluetoothDidReceiveData(uint8_t* buffer, size_t count) {
bluetoothDataCount += sizeof(uint16_t); bluetoothDataCount += sizeof(uint16_t);
// the number of seconds since power on as a uint32_t (4 bytes) // the number of seconds since power on as a uint32_t (4 bytes)
currentTime = time(NULL); uint32_t currentTime = time(NULL);
memcpy(bluetoothDataBuffer + bluetoothDataCount, &currentTime, sizeof(uint32_t)); memcpy(bluetoothDataBuffer + bluetoothDataCount, &currentTime, sizeof(uint32_t));
bluetoothDataCount += sizeof(uint32_t); bluetoothDataCount += sizeof(uint32_t);
@ -270,31 +262,74 @@ void bluetoothDidReceiveData(uint8_t* buffer, size_t count) {
bluetoothDataCount += TEMPERATURE_SENSOR_ADDRESS_SIZE; bluetoothDataCount += TEMPERATURE_SENSOR_ADDRESS_SIZE;
copySensorAddress(1, bluetoothDataBuffer + bluetoothDataCount); copySensorAddress(1, bluetoothDataBuffer + bluetoothDataCount);
bluetoothDataCount += TEMPERATURE_SENSOR_ADDRESS_SIZE; bluetoothDataCount += TEMPERATURE_SENSOR_ADDRESS_SIZE;
// Time since measurement of sensor 0
value = getTimeSinceValidTemperature(0);
memcpy(bluetoothDataBuffer + bluetoothDataCount, &value, sizeof(uint16_t));
bluetoothDataCount += sizeof(uint16_t);
// Time since measurement of sensor 1
value = getTimeSinceValidTemperature(1);
memcpy(bluetoothDataBuffer + bluetoothDataCount, &value, sizeof(uint16_t));
bluetoothDataCount += sizeof(uint16_t);
value = totalStorageSize;
memcpy(bluetoothDataBuffer + bluetoothDataCount, &value, sizeof(uint16_t));
bluetoothDataCount += sizeof(uint16_t);
}
void getRecordingData(uint8_t* buffer, uint16_t count) {
if (count != 2 * sizeof(uint16_t)) {
setResponseWithoutData(BluetoothResponse::invalidCommand);
return;
}
uint16_t byteCount;
memcpy(&byteCount, buffer, sizeof(uint16_t));
if (byteCount > bluetoothMaxDataSize) {
setResponseWithoutData(BluetoothResponse::responseTooLarge);
return;
}
uint16_t byteOffset;
memcpy(&byteOffset, buffer + sizeof(uint16_t), sizeof(uint16_t));
bluetoothDataCount = getRecordedBytesAtOffset(bluetoothDataBuffer, byteOffset, byteCount);
}
void clearRecordingBuffer(uint8_t* buffer, uint16_t count) {
if (count != sizeof(uint16_t)) {
setResponseWithoutData(BluetoothResponse::invalidCommand);
return;
}
uint16_t byteCount;
memcpy(&byteCount, buffer, sizeof(uint16_t));
if (byteCount != getTotalNumberOfStoredBytes()) {
setResponseWithoutData(BluetoothResponse::invalidNumberOfBytesToDelete);
return;
}
discardAllRecordedBytes();
setResponseWithoutData(BluetoothResponse::success);
}
void bluetoothDidReceiveData(uint8_t* buffer, uint16_t count) {
if (count < 1) {
setResponseWithoutData(BluetoothResponse::invalidCommand);
return;
}
BluetoothRequest request = static_cast<BluetoothRequest>(buffer[0]);
switch (request) {
case BluetoothRequest::getInfo:
fillInfo();
break; break;
case BluetoothRequest::clearRecordingBuffer: case BluetoothRequest::clearRecordingBuffer:
memcpy(&count, buffer + 1, sizeof(uint16_t)); clearRecordingBuffer(buffer + sizeof(uint8_t), count - sizeof(uint8_t));
if (count != getTotalNumberOfStoredBytes()) {
setResponseWithoutData(BluetoothResponse::invalidNumberOfBytesToDelete);
} else {
discardAllRecordedBytes();
setResponseWithoutData(BluetoothResponse::success);
}
break; break;
case BluetoothRequest::getRecordingData: case BluetoothRequest::getRecordingData:
if (count != sizeof(uint16_t) + sizeof(uint8_t)) { getRecordingData(buffer + sizeof(uint8_t), count - sizeof(uint8_t));
setResponseWithoutData(BluetoothResponse::invalidCommand);
break;
}
memcpy(&value, buffer + sizeof(uint8_t) , sizeof(uint16_t));
memcpy(&count, buffer + sizeof(uint8_t) + sizeof(uint16_t), sizeof(uint16_t));
if (count > bluetoothMaxDataSize) {
setResponseWithoutData(BluetoothResponse::responseTooLarge);
break;
}
count = getRecordedBytesAtOffset(bluetoothDataBuffer, value, count);
bluetoothDataCount = count;
break; break;
default: default:

View File

@ -134,7 +134,7 @@ void loop() {
setNextTemperatureMeasurementInterval(); setNextTemperatureMeasurementInterval();
} }
if (wakeupButtonIsPressed()) { if (wakeupButtonIsPressed() || bluetoothIsConnected()) {
bluetoothConfigure(); // Only done once internally bluetoothConfigure(); // Only done once internally
updateStayAwakeTime(); updateStayAwakeTime();
} }
@ -146,5 +146,7 @@ void loop() {
// May return, if less then one second to wait // May return, if less then one second to wait
// Otherwise control flow starts with setup() again // Otherwise control flow starts with setup() again
deepSleepUntilNextTemperatureMeasurement(); deepSleepUntilNextTemperatureMeasurement();
} else {
delay(100);
} }
} }

View File

@ -19,13 +19,14 @@ 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];
bool didSetupEEPROM = false; bool didSetupEEPROM = false;
// On first boot, this is set to true; Afterwards it's remembered to be false // On first boot, this is set to true; Afterwards it's remembered to be false
RTC_DATA_ATTR bool eepromIsConsideredEmpty = true; RTC_DATA_ATTR bool eepromIsConsideredEmpty = true;
constexpr uint16_t eepromOffset = 2; // Size of uint16 constexpr uint16_t eepromOffset = sizeof(uint16_t);
constexpr uint16_t eepromDataSize = eepromSize - eepromOffset; constexpr uint16_t eepromDataSize = eepromSize - eepromOffset;
void setupEEPROMIfNeeded() { void setupEEPROMIfNeeded() {
@ -46,6 +47,7 @@ void resetLastMeasurements() {
for (uint8_t index = 0; index < temperatureSensorCount; index += 1) { for (uint8_t index = 0; index < temperatureSensorCount; index += 1) {
lastTemperatures[index].status == TemperatureStatus::sensorNotFound; lastTemperatures[index].status == TemperatureStatus::sensorNotFound;
lastTemperatures[index].value = 0; lastTemperatures[index].value = 0;
lastValidTemperatureTime[index] = 0;
} }
} }
@ -146,6 +148,7 @@ void saveTemperatures(Temperature* temperatures) {
if (temperatures[sensorIndex].status == TemperatureStatus::temperatureIsValid) { if (temperatures[sensorIndex].status == TemperatureStatus::temperatureIsValid) {
// Only update if temperature is valid // Only update if temperature is valid
lastTemperatures[sensorIndex] = temperatures[sensorIndex]; lastTemperatures[sensorIndex] = temperatures[sensorIndex];
lastValidTemperatureTime[sensorIndex] = time(NULL);
} }
} }
} else { } else {
@ -169,6 +172,7 @@ void saveTemperatures(Temperature* temperatures) {
if (temperatures[index].status == TemperatureStatus::temperatureIsValid) { if (temperatures[index].status == TemperatureStatus::temperatureIsValid) {
// Only update if temperature is valid // Only update if temperature is valid
lastTemperatures[index] = temperatures[index]; lastTemperatures[index] = temperatures[index];
lastValidTemperatureTime[index] = time(NULL);
} }
} }
// Ensure storage with uneven number of sensors // Ensure storage with uneven number of sensors
@ -196,6 +200,10 @@ uint8_t getLastTemperature(uint8_t sensorIndex) {
return byteForAbsoluteTemperature(lastTemperatures[sensorIndex].value); return byteForAbsoluteTemperature(lastTemperatures[sensorIndex].value);
} }
uint16_t getTimeSinceValidTemperature(uint8_t sensorIndex) {
return time(NULL) - lastValidTemperatureTime[sensorIndex];
}
uint16_t getRecordedBytesAtOffset(uint8_t* buffer, uint16_t offset, uint16_t count) { uint16_t getRecordedBytesAtOffset(uint8_t* buffer, uint16_t offset, uint16_t count) {
// TODO: Check limits // TODO: Check limits
uint16_t eepromByteCount = getNumberOfBytesStoredInEEPROM(); uint16_t eepromByteCount = getNumberOfBytesStoredInEEPROM();
@ -221,5 +229,4 @@ void discardAllRecordedBytes() {
dataIndex = 0; dataIndex = 0;
numberOfMeasurements = 0; numberOfMeasurements = 0;
resetLastMeasurements(); resetLastMeasurements();
} }