Skip to content

Commit

Permalink
fix(thermocycler-gen2): always disable if thermistors are bad (#427)
Browse files Browse the repository at this point in the history
* Add more checks to thermistor error flags
  • Loading branch information
fsinapi authored Nov 17, 2022
1 parent 929e2b7 commit 5f63649
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ class LidHeaterTask {
auto old_error_bitmap = _state.error_bitmap;
auto current_time = Milliseconds(msg.timestamp_ms);
handle_temperature_conversion(msg.lid_temp, _thermistor);
if (old_error_bitmap != _state.error_bitmap) {
if ((old_error_bitmap != _state.error_bitmap) ||
(_state.error_bitmap != 0)) {
if (_state.error_bitmap != 0) {
// We entered an error state. Disable power output.
_state.system_status = State::ERROR;
Expand Down Expand Up @@ -297,6 +298,7 @@ class LidHeaterTask {
messages::AcknowledgePrevious{.responding_to_id = msg.id};

if (_state.system_status == State::ERROR && !msg.from_system) {
std::ignore = policy.set_heater_power(0.0F);
response.with_error = most_relevant_error();
static_cast<void>(
_task_registry->comms->get_message_queue().try_send(response));
Expand Down Expand Up @@ -328,7 +330,9 @@ class LidHeaterTask {
messages::DeactivateAllResponse{.responding_to_id = msg.id};

static_cast<void>(policy.set_heater_power(0.0F));
_state.system_status = State::IDLE;
if (_state.system_status != State::ERROR) {
_state.system_status = State::IDLE;
}

static_cast<void>(
_task_registry->comms->get_message_queue().try_send(response));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,8 @@ class ThermalPlateTask {
}
}

if (old_error_bitmap != _state.error_bitmap) {
if ((old_error_bitmap != _state.error_bitmap) ||
(_state.error_bitmap != 0)) {
if (_state.error_bitmap != 0) {
// We entered an error state. Disable power output.
_state.system_status = State::ERROR;
Expand Down Expand Up @@ -589,8 +590,9 @@ class ThermalPlateTask {
messages::DeactivateAllResponse{.responding_to_id = msg.id};

policy.set_enabled(false);
_state.system_status = State::IDLE;

if (_state.system_status != State::ERROR) {
_state.system_status = State::IDLE;
}
static_cast<void>(
_task_registry->comms->get_message_queue().try_send(response));
}
Expand Down
51 changes: 51 additions & 0 deletions stm32-modules/thermocycler-gen2/tests/test_lid_heater_task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,3 +556,54 @@ SCENARIO("lid heater task message passing") {
}
}
}
TEST_CASE("lid heater error flag handling") {
uint32_t timestamp = TIME_DELTA;
GIVEN("a lid heater task with invalid temperatures") {
auto tasks = TaskBuilder::build();
auto &lid_queue = tasks->get_lid_heater_queue();
auto &host_queue = tasks->get_host_comms_queue();
auto read_message = messages::LidTempReadComplete{
.lid_temp = _shorted_adc, .timestamp_ms = timestamp};
timestamp += TIME_DELTA;
REQUIRE(lid_queue.try_send(read_message));
tasks->run_lid_heater_task();
WHEN("sending a SetPlateTemperature message") {
auto set_msg =
messages::SetLidTemperatureMessage{.id = 123, .setpoint = 50};
REQUIRE(lid_queue.try_send(set_msg));
tasks->run_lid_heater_task();
THEN("the response shows an error") {
REQUIRE(host_queue.has_message());
auto rsp = host_queue.backing_deque.front();
REQUIRE(
std::holds_alternative<messages::AcknowledgePrevious>(rsp));
auto response = std::get<messages::AcknowledgePrevious>(rsp);
REQUIRE(response.responding_to_id == 123);
REQUIRE(response.with_error != errors::ErrorCode::NO_ERROR);
}
}
WHEN("sending a DeactivateAll message") {
auto deactivate = messages::DeactivateAllMessage{.id = 444};
REQUIRE(lid_queue.try_send(deactivate));
tasks->run_lid_heater_task();
host_queue.backing_deque.clear();
AND_THEN("sending a SetPlateTemperature message") {
auto set_msg = messages::SetLidTemperatureMessage{
.id = 123, .setpoint = 50};
REQUIRE(lid_queue.try_send(set_msg));
tasks->run_lid_heater_task();
THEN("the response shows an error") {
REQUIRE(host_queue.has_message());
auto rsp = host_queue.backing_deque.front();
REQUIRE(
std::holds_alternative<messages::AcknowledgePrevious>(
rsp));
auto response =
std::get<messages::AcknowledgePrevious>(rsp);
REQUIRE(response.responding_to_id == 123);
REQUIRE(response.with_error != errors::ErrorCode::NO_ERROR);
}
}
}
}
}
60 changes: 60 additions & 0 deletions stm32-modules/thermocycler-gen2/tests/test_thermal_plate_task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1174,3 +1174,63 @@ TEST_CASE("sending individual channel offset constants") {
}
}
}

TEST_CASE("thermal plate error flag handling") {
uint32_t timestamp = TIME_DELTA;
GIVEN("a thermal plate task with invalid temperatures") {
auto tasks = TaskBuilder::build();
auto &plate_queue = tasks->get_thermal_plate_queue();
auto &host_queue = tasks->get_host_comms_queue();
auto invalid_adc = _converter.backconvert(130);
auto read_message =
messages::ThermalPlateTempReadComplete{.heat_sink = invalid_adc,
.front_right = invalid_adc,
.front_center = invalid_adc,
.front_left = invalid_adc,
.back_right = invalid_adc,
.back_center = invalid_adc,
.back_left = invalid_adc,
.timestamp_ms = timestamp};
timestamp += TIME_DELTA;
REQUIRE(plate_queue.try_send(read_message));
tasks->run_thermal_plate_task();
WHEN("sending a SetPlateTemperature message") {
auto set_msg = messages::SetPlateTemperatureMessage{
.id = 123, .setpoint = 50, .hold_time = 0};
REQUIRE(plate_queue.try_send(set_msg));
tasks->run_thermal_plate_task();
THEN("the response shows an error") {
REQUIRE(host_queue.has_message());
auto rsp = host_queue.backing_deque.front();
REQUIRE(
std::holds_alternative<messages::AcknowledgePrevious>(rsp));
auto response = std::get<messages::AcknowledgePrevious>(rsp);
REQUIRE(response.responding_to_id == 123);
REQUIRE(response.with_error != errors::ErrorCode::NO_ERROR);
}
}
WHEN("sending a DeactivateAll message") {
auto deactivate = messages::DeactivateAllMessage{.id = 444};
REQUIRE(plate_queue.try_send(deactivate));
tasks->run_thermal_plate_task();
host_queue.backing_deque.clear();
AND_THEN("sending a SetPlateTemperature message") {
auto set_msg = messages::SetPlateTemperatureMessage{
.id = 123, .setpoint = 50, .hold_time = 0};
REQUIRE(plate_queue.try_send(set_msg));
tasks->run_thermal_plate_task();
THEN("the response shows an error") {
REQUIRE(host_queue.has_message());
auto rsp = host_queue.backing_deque.front();
REQUIRE(
std::holds_alternative<messages::AcknowledgePrevious>(
rsp));
auto response =
std::get<messages::AcknowledgePrevious>(rsp);
REQUIRE(response.responding_to_id == 123);
REQUIRE(response.with_error != errors::ErrorCode::NO_ERROR);
}
}
}
}
}

0 comments on commit 5f63649

Please sign in to comment.