Skip to content

Commit

Permalink
Implement alarm/interlock relays behaviors
Browse files Browse the repository at this point in the history
  • Loading branch information
Lyrkan committed May 20, 2024
1 parent 6821b16 commit 937dee2
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 7 deletions.
30 changes: 26 additions & 4 deletions include/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
#define SETTINGS_UPDATE_INTERVAL 1000

typedef enum {
SETTINGS_TYPE_BED = 0x01,
SETTINGS_TYPE_PROBES = 0x02,
SETTINGS_TYPE_OTA = 0x04,
SETTINGS_TYPE_GRBL = 0x08,
SETTINGS_TYPE_BED = 1 << 0,
SETTINGS_TYPE_PROBES = 1 << 1,
SETTINGS_TYPE_OTA = 1 << 2,
SETTINGS_TYPE_GRBL = 1 << 3,
SETTINGS_TYPE_RELAYS = 1 << 4,
} SettingsType;

typedef struct {
Expand Down Expand Up @@ -44,15 +45,36 @@ typedef struct {
uint32_t homing_timeout_ms;
} GrblSettings;

typedef struct {
uint32_t alarm_behavior;
uint32_t interlock_behavior;
} RelaysSettings;

typedef enum {
ALARM_ENABLE_WHEN_RUNNING = 1 << 0,
ALARM_ENABLE_WHEN_NOT_IDLING = 1 << 1,
ALARM_ENABLE_WHEN_FLAME_SENSOR_TRIGGERED = 1 << 2,
ALARM_ENABLE_WHEN_COOLING_ISSUE = 1 << 3,
ALARM_ENABLE_WHEN_LID_OPENED = 1 << 4
} AlarmBehaviorFlag;

typedef enum {
INTERLOCK_DISABLE_WHEN_LID_OPENED = 1 << 0,
INTERLOCK_DISABLE_WHEN_COOLING_ISSUE = 1 << 1,
INTERLOCK_DISABLE_WHEN_FLAME_SENSOR_TRIGGERED = 1 << 2,
} InterlockBehaviorFlag;

extern SemaphoreHandle_t bed_settings_mutex;
extern SemaphoreHandle_t probes_settings_mutex;
extern SemaphoreHandle_t ota_settings_mutex;
extern SemaphoreHandle_t grbl_settings_mutex;
extern SemaphoreHandle_t relays_settings_mutex;

extern BedSettings bed_settings;
extern ProbesSettings probes_settings;
extern OTASettings ota_settings;
extern GrblSettings grbl_settings;
extern RelaysSettings relays_settings;

void settings_init();
void settings_schedule_save(uint32_t settings_types);
Expand Down
62 changes: 61 additions & 1 deletion src/K40/relays.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
#include <Arduino.h>

#include "Grbl/grbl_report.h"
#include "Grbl/grbl_state.h"
#include "K40/alerts.h"
#include "K40/relays.h"
#include "macros.h"
#include "mutex.h"
#include "queues.h"
#include "settings.h"

static RelayPin relay_pins[] = {
RELAY_PIN_INTERLOCK, RELAY_PIN_AIR_ASSIST, RELAY_PIN_ALARM, RELAY_PIN_LIGHTS, RELAY_PIN_BEAM_PREVIEW};
Expand Down Expand Up @@ -41,15 +45,71 @@ bool relays_is_disabled(RelayPin pin) {
return false;
}

// Retrieve behaviors from settings
TAKE_MUTEX(relays_settings_mutex)
uint32_t interlock_behavior = relays_settings.interlock_behavior;
RELEASE_MUTEX(relays_settings_mutex)

uint8_t alerts_status = alerts_get_current_alerts();
return (alerts_status & (ALERT_TYPE_COOLING | ALERT_TYPE_LIDS)) != 0;
if ((bool)(interlock_behavior & INTERLOCK_DISABLE_WHEN_COOLING_ISSUE) && (alerts_status & (ALERT_TYPE_COOLING))) {
return true;
}

if ((bool)(interlock_behavior & INTERLOCK_DISABLE_WHEN_LID_OPENED) && (alerts_status & (ALERT_TYPE_LIDS))) {
return true;
}

if ((bool)(interlock_behavior & INTERLOCK_DISABLE_WHEN_FLAME_SENSOR_TRIGGERED) &&
(alerts_status & (ALERT_TYPE_FLAME_SENSOR))) {
return true;
}

return false;
}

void relays_update() {
// Holds the indexes of force disabled relays as a bit mask
// Those relays should be re-activated automatically when they are not disabled anymore.
static int8_t force_disabled_indexes = 0;

// Retrieve alarm behavior from settings
TAKE_MUTEX(relays_settings_mutex)
uint32_t alarm_behavior = relays_settings.alarm_behavior;
RELEASE_MUTEX(relays_settings_mutex)

// Check if the alarm relay should be enabled
bool enable_alarm_relay = false;
uint8_t alerts_status = alerts_get_current_alerts();

TAKE_MUTEX(grbl_last_report_mutex)
GrblState grbl_state = grbl_last_report.state;
RELEASE_MUTEX(grbl_last_report_mutex)

if (((bool)alarm_behavior & ALARM_ENABLE_WHEN_COOLING_ISSUE) && (alerts_status & (ALERT_TYPE_COOLING))) {
enable_alarm_relay = true;
}

if (((bool)alarm_behavior & ALARM_ENABLE_WHEN_FLAME_SENSOR_TRIGGERED) &&
(alerts_status & (ALERT_TYPE_FLAME_SENSOR))) {
enable_alarm_relay = true;
}

if (((bool)alarm_behavior & ALARM_ENABLE_WHEN_LID_OPENED) && (alerts_status & (ALERT_TYPE_LIDS))) {
enable_alarm_relay = true;
}

if (((bool)alarm_behavior & ALARM_ENABLE_WHEN_RUNNING) && grbl_state == GRBL_STATE_RUN) {
enable_alarm_relay = true;
}

if (((bool)alarm_behavior & ALARM_ENABLE_WHEN_NOT_IDLING) && grbl_state != GRBL_STATE_IDLE) {
enable_alarm_relay = true;
}

digitalWrite(
RELAY_PIN_ALARM,
relays_get_pin_state_value(RELAY_PIN_ALARM, enable_alarm_relay ? RELAY_STATE_ENABLED : RELAY_STATE_DISABLED));

// Process new command if there is one
static RelaysCommand relays_command;
bool current_status_updated = false;
Expand Down
57 changes: 57 additions & 0 deletions src/UI/screens/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,52 @@ static void ui_settings_save_ota_settings() {
RELEASE_MUTEX(ota_settings_mutex)
}

static void ui_settings_load_relays_settings() {
// Acquire relays settings mutex
TAKE_MUTEX(relays_settings_mutex)

// clang-format off
// Alarm behavior
ui_utils_toggle_state(ui_settings_alarm_enable_when_running_value, LV_STATE_CHECKED, (bool)(relays_settings.alarm_behavior & ALARM_ENABLE_WHEN_RUNNING));
ui_utils_toggle_state(ui_settings_alarm_enable_when_not_idling_value, LV_STATE_CHECKED, (bool)(relays_settings.alarm_behavior & ALARM_ENABLE_WHEN_NOT_IDLING));
ui_utils_toggle_state(ui_settings_alarm_enable_when_flame_sensor_triggered_value, LV_STATE_CHECKED, (bool)(relays_settings.alarm_behavior & ALARM_ENABLE_WHEN_FLAME_SENSOR_TRIGGERED));
ui_utils_toggle_state(ui_settings_alarm_enable_when_cooling_issue_value, LV_STATE_CHECKED, (bool)(relays_settings.alarm_behavior & ALARM_ENABLE_WHEN_COOLING_ISSUE));
ui_utils_toggle_state(ui_settings_alarm_enable_when_lid_opened_value, LV_STATE_CHECKED, (bool)(relays_settings.alarm_behavior & ALARM_ENABLE_WHEN_LID_OPENED));

// Interlock behavior
ui_utils_toggle_state(ui_settings_interlock_disable_when_lid_opened_value, LV_STATE_CHECKED, (bool)(relays_settings.interlock_behavior & INTERLOCK_DISABLE_WHEN_LID_OPENED));
ui_utils_toggle_state(ui_settings_interlock_disable_when_cooling_issue_value, LV_STATE_CHECKED, (bool)(relays_settings.interlock_behavior & INTERLOCK_DISABLE_WHEN_COOLING_ISSUE));
ui_utils_toggle_state(ui_settings_interlock_disable_when_flame_sensor_triggered_value, LV_STATE_CHECKED, (bool)(relays_settings.interlock_behavior & INTERLOCK_DISABLE_WHEN_FLAME_SENSOR_TRIGGERED));
// clang-format on

// Release relays settings mutex
RELEASE_MUTEX(relays_settings_mutex)
}

static void ui_settings_save_relays_settings() {
// Acquire relays settings mutex
TAKE_MUTEX(relays_settings_mutex)

// clang-format off
relays_settings.alarm_behavior =
(ALARM_ENABLE_WHEN_COOLING_ISSUE * (int) lv_obj_has_state(ui_settings_alarm_enable_when_cooling_issue_value, LV_STATE_CHECKED)) +
(ALARM_ENABLE_WHEN_FLAME_SENSOR_TRIGGERED * (int) lv_obj_has_state(ui_settings_alarm_enable_when_flame_sensor_triggered_value, LV_STATE_CHECKED)) +
(ALARM_ENABLE_WHEN_LID_OPENED * (int) lv_obj_has_state(ui_settings_alarm_enable_when_lid_opened_value, LV_STATE_CHECKED)) +
(ALARM_ENABLE_WHEN_NOT_IDLING * (int) lv_obj_has_state(ui_settings_alarm_enable_when_not_idling_value, LV_STATE_CHECKED)) +
(ALARM_ENABLE_WHEN_RUNNING * (int) lv_obj_has_state(ui_settings_alarm_enable_when_running_value, LV_STATE_CHECKED));

relays_settings.interlock_behavior =
(INTERLOCK_DISABLE_WHEN_COOLING_ISSUE * (int) lv_obj_has_state(ui_settings_interlock_disable_when_cooling_issue_value, LV_STATE_CHECKED)) +
(INTERLOCK_DISABLE_WHEN_FLAME_SENSOR_TRIGGERED * (int) lv_obj_has_state(ui_settings_interlock_disable_when_flame_sensor_triggered_value, LV_STATE_CHECKED)) +
(INTERLOCK_DISABLE_WHEN_LID_OPENED * (int) lv_obj_has_state(ui_settings_interlock_disable_when_lid_opened_value, LV_STATE_CHECKED));
// clang-format on

settings_schedule_save(SETTINGS_TYPE_RELAYS);

// Release GRBL settings mutex
RELEASE_MUTEX(relays_settings_mutex)
}

static void ui_settings_load_grbl_settings() {
// Acquire GRBL settings mutex
TAKE_MUTEX(grbl_settings_mutex)
Expand Down Expand Up @@ -294,6 +340,16 @@ static void ui_settings_field_value_changed_handler(lv_event_t *e) {
target == ui_settings_grbl_jog_speed_value || target == ui_settings_grbl_default_timeout_value ||
target == ui_settings_grbl_homing_timeout_value) {
ui_settings_save_grbl_settings();
} else if (
target == ui_settings_alarm_enable_when_running_value ||
target == ui_settings_alarm_enable_when_not_idling_value ||
target == ui_settings_alarm_enable_when_flame_sensor_triggered_value ||
target == ui_settings_alarm_enable_when_cooling_issue_value ||
target == ui_settings_alarm_enable_when_lid_opened_value ||
target == ui_settings_interlock_disable_when_lid_opened_value ||
target == ui_settings_interlock_disable_when_cooling_issue_value ||
target == ui_settings_interlock_disable_when_flame_sensor_triggered_value) {
ui_settings_save_relays_settings();
}
}
}
Expand Down Expand Up @@ -571,6 +627,7 @@ static void ui_settings_init_screen_content() {
ui_settings_load_probes_settings();
ui_settings_load_ota_settings();
ui_settings_load_grbl_settings();
ui_settings_load_relays_settings();
settings_loaded = true;

// Force the first update
Expand Down
50 changes: 48 additions & 2 deletions src/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ static const char PREFERENCES_NAMESPACE_BED[] = "bed-settings";
static const char PREFERENCES_NAMESPACE_PROBES[] = "probes-settings";
static const char PREFERENCES_NAMESPACE_OTA[] = "ota-settings";
static const char PREFERENCES_NAMESPACE_GRBL[] = "grbl-settings";
static const char PREFERENCES_NAMESPACE_RELAYS[] = "relays-settings";

static const char PREFERENCES_KEY_BED_SCREW_LEAD[] = "screw-lead-um";
static const char PREFERENCES_KEY_BED_MICROSTEP_MULTIPLIER[] = "microstep-mul";
Expand All @@ -32,12 +33,16 @@ static const char PREFERENCES_KEY_GRBL_JOG_SPEED[] = "jog-speed";
static const char PREFERENCES_KEY_GRBL_DEFAULT_TIMEOUT[] = "default-timeout";
static const char PREFERENCES_KEY_GRBL_HOMING_TIMEOUT[] = "homing-timeout";

static const char PREFERENCES_KEY_RELAYS_ALARM_BEHAVIOR[] = "alarm-flags";
static const char PREFERENCES_KEY_RELAYS_INTERLOCK_BEHAVIOR[] = "interlock-flags";

static Preferences preferences;

SemaphoreHandle_t bed_settings_mutex = xSemaphoreCreateMutex();
SemaphoreHandle_t probes_settings_mutex = xSemaphoreCreateMutex();
SemaphoreHandle_t ota_settings_mutex = xSemaphoreCreateMutex();
SemaphoreHandle_t grbl_settings_mutex = xSemaphoreCreateMutex();
SemaphoreHandle_t relays_settings_mutex = xSemaphoreCreateMutex();

BedSettings bed_settings = {
.screw_lead_um = 8000,
Expand Down Expand Up @@ -66,6 +71,12 @@ GrblSettings grbl_settings = {
.homing_timeout_ms = 30000,
};

RelaysSettings relays_settings = {
.alarm_behavior =
ALARM_ENABLE_WHEN_COOLING_ISSUE | ALARM_ENABLE_WHEN_FLAME_SENSOR_TRIGGERED | ALARM_ENABLE_WHEN_LID_OPENED,
.interlock_behavior = INTERLOCK_DISABLE_WHEN_COOLING_ISSUE | INTERLOCK_DISABLE_WHEN_LID_OPENED,
};

static void settings_save_task_func(void *params) {
uint32_t settings_types;

Expand Down Expand Up @@ -140,10 +151,25 @@ static void settings_save_task_func(void *params) {
preferences.putUInt(PREFERENCES_KEY_GRBL_HOMING_TIMEOUT, grbl_settings.homing_timeout_ms);
preferences.end();

// Release OTA settings lock
// Release GRBL settings lock
RELEASE_MUTEX(grbl_settings_mutex)
}

if ((settings_types & SETTINGS_TYPE_RELAYS) != 0) {
log_i("Relays settings have changed, saving new values...");

// Acquire relays settings lock
TAKE_MUTEX(relays_settings_mutex)

preferences.begin(PREFERENCES_NAMESPACE_RELAYS, false);
preferences.putUInt(PREFERENCES_KEY_RELAYS_ALARM_BEHAVIOR, relays_settings.alarm_behavior);
preferences.putUInt(PREFERENCES_KEY_RELAYS_INTERLOCK_BEHAVIOR, relays_settings.interlock_behavior);
preferences.end();

// Release relays settings lock
RELEASE_MUTEX(relays_settings_mutex)
}

// Wait a little bit before the next check
vTaskDelay(pdMS_TO_TICKS(SETTINGS_UPDATE_INTERVAL));
}
Expand Down Expand Up @@ -249,11 +275,31 @@ void settings_init() {

log_d(" jog speed: %.1f", grbl_settings.jog_speed);
log_d(" default timeout: %d", grbl_settings.default_timeout_ms);
log_d(" homing timeoutd: %d", grbl_settings.homing_timeout_ms);
log_d(" homing timeout: %d", grbl_settings.homing_timeout_ms);

// Release GRBL settings lock
RELEASE_MUTEX(grbl_settings_mutex)

// Acquire relays settings lock
TAKE_MUTEX(relays_settings_mutex)
log_i("Loading relays settings... ");
preferences.begin(PREFERENCES_NAMESPACE_RELAYS, true);

// clang-format off
relays_settings = {
.alarm_behavior = preferences.getUInt(PREFERENCES_KEY_RELAYS_ALARM_BEHAVIOR, relays_settings.alarm_behavior),
.interlock_behavior = preferences.getUInt(PREFERENCES_KEY_RELAYS_INTERLOCK_BEHAVIOR, relays_settings.interlock_behavior),
};
// clang-format on

preferences.end();

log_d(" alarm behavior: 0x%x", relays_settings.alarm_behavior);
log_d(" interlock behavior: 0x%x", relays_settings.interlock_behavior);

// Release relays settings lock
RELEASE_MUTEX(relays_settings_mutex)

// Start saving task
xTaskCreatePinnedToCore(
settings_save_task_func,
Expand Down

0 comments on commit 937dee2

Please sign in to comment.