safety interlocking and a bunch of other fun stuff

This commit is contained in:
Thaddeus Hughes
2026-01-05 19:47:51 -06:00
parent 53bea4eb04
commit 15e2145560
19 changed files with 1004 additions and 935 deletions

View File

@@ -1,10 +1,12 @@
#include "sensors.h"
#include "i2c.h"
#include "esp_log.h"
#include "esp_task_wdt.h"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "storage.h"
static const char* TAG = "SENS";
@@ -15,6 +17,13 @@ static volatile uint64_t sensor_last_isr_time[N_SENSORS] = {0};
static volatile bool sensor_stable_state[N_SENSORS] = {false};
static QueueHandle_t sensor_event_queue = NULL;
// Safety sensor debouncing
static volatile bool safety_tripped = false;
static volatile uint64_t safety_low_start_time = 0;
static volatile uint64_t safety_high_start_time = 0;
#define SAFETY_TRIP_DEBOUNCE_US get_param_value_t(PARAM_SAFETY_BREAK_US).u32
#define SAFETY_UNTRIP_DEBOUNCE_US get_param_value_t(PARAM_SAFETY_BREAK_US).u32
#define DEBOUNCE_TIME_US 2000 // 2 ms debounce (adjust per switch)
#define DEBOUNCE_TICKS pdMS_TO_TICKS(DEBOUNCE_TIME_MS)
@@ -23,7 +32,7 @@ typedef struct {
bool level;
} sensor_event_t;
// ISR: Minimal work just record timestamp and forward to queue
// ISR: Minimal work just record timestamp and forward to queue
static void IRAM_ATTR sensor_isr_handler(void* arg) {
uint32_t gpio_num = (uint32_t)arg;
uint8_t i;
@@ -56,62 +65,72 @@ static void sensor_debounce_task(void* param) {
last_processed_time[i] = esp_timer_get_time();
}
// Initialize safety sensor
bool safety_current = !gpio_get_level(sensor_pins[SENSOR_SAFETY]);
if (safety_current) {
safety_low_start_time = esp_timer_get_time();
safety_high_start_time = 0;
} else {
safety_low_start_time = 0;
safety_high_start_time = esp_timer_get_time();
}
uint8_t i = 0;
//int64_t now = -1;
uint8_t i = 0;
while (1) {
if (xQueueReceive(sensor_event_queue, &evt, pdMS_TO_TICKS(100)) == pdTRUE) {
if (xQueueReceive(sensor_event_queue, &evt, pdMS_TO_TICKS(10)) == pdTRUE) {
i = evt.sensor_id;
ESP_LOGI("SENS", "EVENT %d", i);
bool current_raw = !gpio_get_level(sensor_pins[i]);
sensor_stable_state[i] = current_raw;
sensor_stable_state[i] = current_raw;
if (current_raw && !last_raw_state[i]){
ESP_LOGI("SENS", "FALLING");
sensor_count[i]++;
}
if (current_raw && !last_raw_state[i]){
ESP_LOGI("SENS", "FALLING");
sensor_count[i]++;
}
if (!current_raw && last_raw_state[i]){
ESP_LOGI("SENS", "RISING");
sensor_count[i]++;
}
last_raw_state[i] = current_raw;
ESP_LOGI("SENS", "RISING");
sensor_count[i]++;
}
last_raw_state[i] = current_raw;
}
// Handle safety sensor debouncing with asymmetric timing
bool safety_current = !gpio_get_level(sensor_pins[SENSOR_SAFETY]);
uint64_t now = esp_timer_get_time();
//now = esp_timer_get_time();
if (safety_current) {
// Safety sensor is LOW (active)
if (safety_low_start_time == 0) {
// First time going low, start timing
safety_low_start_time = now;
safety_high_start_time = 0;
ESP_LOGI(TAG, "Safety sensor went LOW, starting trip timer");
} else if (!safety_tripped && (now - safety_low_start_time >= SAFETY_TRIP_DEBOUNCE_US)) {
// Been low for 200ms, trip the safety
safety_tripped = true;
i2c_set_safety_status(false);
ESP_LOGW(TAG, "SAFETY TRIPPED - Relays disabled");
}
} else {
// Safety sensor is HIGH (inactive)
if (safety_high_start_time == 0) {
// First time going high, start timing
safety_high_start_time = now;
safety_low_start_time = 0;
ESP_LOGI(TAG, "Safety sensor went HIGH, starting un-trip timer");
} else if (safety_tripped && (now - safety_high_start_time >= SAFETY_UNTRIP_DEBOUNCE_US)) {
// Been high for 300ms, un-trip the safety
safety_tripped = false;
i2c_set_safety_status(true);
ESP_LOGI(TAG, "SAFETY CLEARED - Relays enabled");
}
}
/*// Wait for debounce period since last ISR
if (now - sensor_last_isr_time[i] >= (DEBOUNCE_TIME_US)) {
bool current_raw = !gpio_get_level(sensor_pins[i]);
// Only update if stable and different from last stable
if (current_raw != sensor_stable_state[i]) {
bool was_high = sensor_stable_state[i];
// Count rising OR falling edges
if (current_raw && !sensor_stable_state[i]){
ESP_LOGI("SENS", "FALLING");
sensor_count[i]++;
}
if (!current_raw && sensor_stable_state[i]){
ESP_LOGI("SENS", "RISING");
sensor_count[i]++;
}
sensor_stable_state[i] = current_raw;
last_raw_state[i] = current_raw;
last_processed_time[i] = now;
}
}*/
esp_task_wdt_reset();
}
}
@@ -160,6 +179,10 @@ bool get_sensor(sensor_t i) {
return sensor_stable_state[i];
}
bool get_safety_sensor(void) {
return !safety_tripped; // Returns true if safe, false if tripped
}
int32_t get_sensor_counter(sensor_t i) {
return sensor_count[i];
}