diff --git a/CHANGELOG.md b/CHANGELOG.md index e71966b0..edafc9d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ will consitute of a breaking change warranting a new major release: - STR missed reply handling is now moved to DHB rather than the COM interface. The COM IF will still trigger an event if a reply is taking too long, and FDIR should still work via reply timeouts. +- Rad sensor is now only polled every 30 minutes instead of every device cycle to reduce wear of + the RADFET electronics. ## Added diff --git a/mission/payload/RadiationSensorHandler.cpp b/mission/payload/RadiationSensorHandler.cpp index 2a87e730..e20d7308 100644 --- a/mission/payload/RadiationSensorHandler.cpp +++ b/mission/payload/RadiationSensorHandler.cpp @@ -15,6 +15,8 @@ RadiationSensorHandler::RadiationSensorHandler(object_id_t objectId, object_id_t if (comCookie == nullptr) { sif::error << "RadiationSensorHandler: Invalid com cookie" << std::endl; } + // Time out immediately so we get an immediate measurement at device startup. + measurementCd.timeOut(); } RadiationSensorHandler::~RadiationSensorHandler() {} @@ -51,6 +53,9 @@ void RadiationSensorHandler::doShutDown() { } ReturnValue_t RadiationSensorHandler::buildNormalDeviceCommand(DeviceCommandId_t *id) { + if (measurementCd.isBusy()) { + return NOTHING_TO_SEND; + } switch (communicationStep) { case CommunicationStep::START_CONVERSION: { *id = radSens::START_CONVERSION; @@ -177,22 +182,25 @@ ReturnValue_t RadiationSensorHandler::interpretDeviceReply(DeviceCommandId_t id, switch (id) { case radSens::READ_CONVERSIONS: { uint8_t offset = 0; - PoolReadGuard readSet(&dataset); - uint16_t tempRaw = ((packet[offset] & 0x0f) << 8) | packet[offset + 1]; - dataset.temperatureCelcius = max1227::getTemperature(tempRaw); - offset += 2; - dataset.ain0 = (*(packet + offset) << 8) | *(packet + offset + 1); - offset += 2; - dataset.ain1 = (*(packet + offset) << 8) | *(packet + offset + 1); - offset += 6; - dataset.ain4 = (*(packet + offset) << 8) | *(packet + offset + 1); - offset += 2; - dataset.ain5 = (*(packet + offset) << 8) | *(packet + offset + 1); - offset += 2; - dataset.ain6 = (*(packet + offset) << 8) | *(packet + offset + 1); - offset += 2; - dataset.ain7 = (*(packet + offset) << 8) | *(packet + offset + 1); - dataset.setValidity(true, true); + measurementCd.resetTimer(); + { + PoolReadGuard readSet(&dataset); + uint16_t tempRaw = ((packet[offset] & 0x0f) << 8) | packet[offset + 1]; + dataset.temperatureCelcius = max1227::getTemperature(tempRaw); + offset += 2; + dataset.ain0 = (*(packet + offset) << 8) | *(packet + offset + 1); + offset += 2; + dataset.ain1 = (*(packet + offset) << 8) | *(packet + offset + 1); + offset += 6; + dataset.ain4 = (*(packet + offset) << 8) | *(packet + offset + 1); + offset += 2; + dataset.ain5 = (*(packet + offset) << 8) | *(packet + offset + 1); + offset += 2; + dataset.ain6 = (*(packet + offset) << 8) | *(packet + offset + 1); + offset += 2; + dataset.ain7 = (*(packet + offset) << 8) | *(packet + offset + 1); + dataset.setValidity(true, true); + } if (printPeriodicData) { sif::info << "Radiation sensor temperature: " << dataset.temperatureCelcius << " °C" << std::dec << std::endl; @@ -203,6 +211,12 @@ ReturnValue_t RadiationSensorHandler::interpretDeviceReply(DeviceCommandId_t id, sif::info << "Radiation sensor ADC value channel 6: " << dataset.ain6 << std::endl; sif::info << "Radiation sensor ADC value channel 7: " << dataset.ain7 << std::endl; } + ReturnValue_t result = + getHkManagerHandle()->generateHousekeepingPacket(dataset.getSid(), &dataset, true); + if (result != returnvalue::OK) { + // TODO: Maybe add event? + sif::error << "Generating HK set for radiation sensor failed" << std::endl; + } break; } default: { @@ -226,8 +240,11 @@ ReturnValue_t RadiationSensorHandler::initializeLocalDataPool(localpool::DataPoo localDataPoolMap.emplace(radSens::AIN5, new PoolEntry({0})); localDataPoolMap.emplace(radSens::AIN6, new PoolEntry({0})); localDataPoolMap.emplace(radSens::AIN7, new PoolEntry({0})); + // It should normally not be necessary to enable this set, as a sample TM will be generated + // after a measurement. If this is still enabled, sample with double the measurement frequency + // to ensure we get all measurements. poolManager.subscribeForRegularPeriodicPacket( - subdp::RegularHkPeriodicParams(dataset.getSid(), false, 20.0)); + subdp::RegularHkPeriodicParams(dataset.getSid(), false, DEFAULT_MEASUREMENT_CD_MS / 2)); return returnvalue::OK; } diff --git a/mission/payload/RadiationSensorHandler.h b/mission/payload/RadiationSensorHandler.h index 2e8ca7f2..429cda79 100644 --- a/mission/payload/RadiationSensorHandler.h +++ b/mission/payload/RadiationSensorHandler.h @@ -38,12 +38,15 @@ class RadiationSensorHandler : public DeviceHandlerBase { LocalDataPoolManager &poolManager) override; private: + static constexpr uint32_t DEFAULT_MEASUREMENT_CD_MS = 30 * 60 * 1000; + enum class CommunicationStep { START_CONVERSION, READ_CONVERSIONS }; enum class InternalState { OFF, POWER_SWITCHING, SETUP, CONFIGURED }; bool printPeriodicData = false; radSens::RadSensorDataset dataset; + Countdown measurementCd = Countdown(DEFAULT_MEASUREMENT_CD_MS); static const uint8_t MAX_CMD_LEN = radSens::READ_SIZE; GpioIF *gpioIF = nullptr; Stack5VHandler &stackHandler;