Transmit last temperature time
This commit is contained in:
parent
3727fdb694
commit
c4d8116cfd
@ -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();
|
@ -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,86 +215,121 @@ 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() {
|
||||||
|
uint16_t value;
|
||||||
|
|
||||||
|
// BluetoothResponse::success
|
||||||
|
setResponse(BluetoothResponse::success);
|
||||||
|
|
||||||
|
// the number of bytes as a uint16_t (2 bytes)
|
||||||
|
value = getTotalNumberOfStoredBytes();
|
||||||
|
memcpy(bluetoothDataBuffer, &value, sizeof(uint16_t));
|
||||||
|
bluetoothDataCount = sizeof(uint16_t);
|
||||||
|
|
||||||
|
// the number of seconds until the next measurement as a uint16_t (2 bytes)
|
||||||
|
value = secondsUntilNextTemperatureMeasurement();
|
||||||
|
memcpy(bluetoothDataBuffer + bluetoothDataCount, &value, sizeof(uint16_t));
|
||||||
|
bluetoothDataCount += sizeof(uint16_t);
|
||||||
|
|
||||||
|
// the number of seconds between measurements as a uint16_t (2 bytes)
|
||||||
|
value = temperatureMeasurementIntervalSeconds;
|
||||||
|
memcpy(bluetoothDataBuffer + bluetoothDataCount, &value, sizeof(uint16_t));
|
||||||
|
bluetoothDataCount += sizeof(uint16_t);
|
||||||
|
|
||||||
|
// the number of measurements as a uint16_t (2 bytes)
|
||||||
|
value = getNumberOfMeasurements();
|
||||||
|
memcpy(bluetoothDataBuffer + bluetoothDataCount, &value, sizeof(uint16_t));
|
||||||
|
bluetoothDataCount += sizeof(uint16_t);
|
||||||
|
|
||||||
|
// the maximum number of bytes that can be copied
|
||||||
|
value = bluetoothMaxDataSize;
|
||||||
|
memcpy(bluetoothDataBuffer + bluetoothDataCount, &value, sizeof(uint16_t));
|
||||||
|
bluetoothDataCount += sizeof(uint16_t);
|
||||||
|
|
||||||
|
// the number of seconds since power on as a uint32_t (4 bytes)
|
||||||
|
uint32_t currentTime = time(NULL);
|
||||||
|
memcpy(bluetoothDataBuffer + bluetoothDataCount, ¤tTime, sizeof(uint32_t));
|
||||||
|
bluetoothDataCount += sizeof(uint32_t);
|
||||||
|
|
||||||
|
// The last temperatures
|
||||||
|
bluetoothDataBuffer[bluetoothDataCount] = getLastTemperature(0);
|
||||||
|
bluetoothDataCount += sizeof(uint8_t);
|
||||||
|
bluetoothDataBuffer[bluetoothDataCount] = getLastTemperature(1);
|
||||||
|
bluetoothDataCount += sizeof(uint8_t);
|
||||||
|
|
||||||
|
// Temperature sensor addresses
|
||||||
|
copySensorAddress(0, bluetoothDataBuffer + bluetoothDataCount);
|
||||||
|
bluetoothDataCount += TEMPERATURE_SENSOR_ADDRESS_SIZE;
|
||||||
|
copySensorAddress(1, bluetoothDataBuffer + bluetoothDataCount);
|
||||||
|
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) {
|
if (count < 1) {
|
||||||
setResponseWithoutData(BluetoothResponse::invalidCommand);
|
setResponseWithoutData(BluetoothResponse::invalidCommand);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t currentTime;
|
|
||||||
uint16_t value;
|
|
||||||
BluetoothRequest request = static_cast<BluetoothRequest>(buffer[0]);
|
BluetoothRequest request = static_cast<BluetoothRequest>(buffer[0]);
|
||||||
switch (request) {
|
switch (request) {
|
||||||
case BluetoothRequest::getInfo:
|
case BluetoothRequest::getInfo:
|
||||||
// BluetoothResponse::success
|
fillInfo();
|
||||||
setResponse(BluetoothResponse::success);
|
|
||||||
|
|
||||||
// the number of bytes as a uint16_t (2 bytes)
|
|
||||||
value = getTotalNumberOfStoredBytes();
|
|
||||||
memcpy(bluetoothDataBuffer, &value, sizeof(uint16_t));
|
|
||||||
bluetoothDataCount = sizeof(uint16_t);
|
|
||||||
|
|
||||||
// the number of seconds until the next measurement as a uint16_t (2 bytes)
|
|
||||||
value = secondsUntilNextTemperatureMeasurement();
|
|
||||||
memcpy(bluetoothDataBuffer + bluetoothDataCount, &value, sizeof(uint16_t));
|
|
||||||
bluetoothDataCount += sizeof(uint16_t);
|
|
||||||
|
|
||||||
// the number of seconds between measurements as a uint16_t (2 bytes)
|
|
||||||
value = temperatureMeasurementIntervalSeconds;
|
|
||||||
memcpy(bluetoothDataBuffer + bluetoothDataCount, &value, sizeof(uint16_t));
|
|
||||||
bluetoothDataCount += sizeof(uint16_t);
|
|
||||||
|
|
||||||
// the number of measurements as a uint16_t (2 bytes)
|
|
||||||
value = getNumberOfMeasurements();
|
|
||||||
memcpy(bluetoothDataBuffer + bluetoothDataCount, &value, sizeof(uint16_t));
|
|
||||||
bluetoothDataCount += sizeof(uint16_t);
|
|
||||||
|
|
||||||
// the maximum number of bytes that can be copied
|
|
||||||
value = bluetoothMaxDataSize;
|
|
||||||
memcpy(bluetoothDataBuffer + bluetoothDataCount, &value, sizeof(uint16_t));
|
|
||||||
bluetoothDataCount += sizeof(uint16_t);
|
|
||||||
|
|
||||||
// the number of seconds since power on as a uint32_t (4 bytes)
|
|
||||||
currentTime = time(NULL);
|
|
||||||
memcpy(bluetoothDataBuffer + bluetoothDataCount, ¤tTime, sizeof(uint32_t));
|
|
||||||
bluetoothDataCount += sizeof(uint32_t);
|
|
||||||
|
|
||||||
// The last temperatures
|
|
||||||
bluetoothDataBuffer[bluetoothDataCount] = getLastTemperature(0);
|
|
||||||
bluetoothDataCount += sizeof(uint8_t);
|
|
||||||
bluetoothDataBuffer[bluetoothDataCount] = getLastTemperature(1);
|
|
||||||
bluetoothDataCount += sizeof(uint8_t);
|
|
||||||
|
|
||||||
// Temperature sensor addresses
|
|
||||||
copySensorAddress(0, bluetoothDataBuffer + bluetoothDataCount);
|
|
||||||
bluetoothDataCount += TEMPERATURE_SENSOR_ADDRESS_SIZE;
|
|
||||||
copySensorAddress(1, bluetoothDataBuffer + bluetoothDataCount);
|
|
||||||
bluetoothDataCount += TEMPERATURE_SENSOR_ADDRESS_SIZE;
|
|
||||||
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:
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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();
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user