Merge pull request 'Add safety contact output' (#5) from feature/safety_contact into main

Reviewed-on: #5
This commit is contained in:
Hendrik Schutter 2024-12-19 21:41:14 +01:00
commit 5d890b8654
6 changed files with 87 additions and 15 deletions

View File

@ -33,6 +33,8 @@ Sntp <|-- Metrics
+setCirculationPumpState()
+getBurnerState()
+setBurnerState()
+getSafetyControlState()
+setSafetyControlState()
}
class Control{
@ -71,10 +73,10 @@ Sntp <|-- Metrics
### Hardware
| Function| ESP32 | ES32C14 |
|-----------------------|-------|---------------------------|
| CirculationPump | IO27 | Relay 1 NO1 |
| Burner | IO14 | Relay 1 NC2 |
| Burner Fault | IO19 | Digital Input IN1 |
| Temperature DS10B20 | IO04 | 1-Wire |
| Function | ESP32 | PLC ES32C14 |
|---------------------------------------|-------|---------------------------|
| Output CirculationPump | IO27 | Relay 1 NO1 |
| Output Burner Fire Signal | IO14 | Relay 2 NC2 |
| Output Safety Contact (powers Burner) | IO12 | Relay 3 NC2 |
| Input Burner Fault | IO19 | Digital Input IN1 |
| Input Temperature DS10B20 | IO04 | 1-Wire |

View File

@ -56,5 +56,6 @@ void taskControl(void *pvParameters)
// TODO: control the burner based on timetable
setCirculationPumpState(DISABLED);
setBurnerState(ENABLED);
setSafetyControlState(ENABLED);
}
}

View File

@ -55,6 +55,12 @@ void taskMetrics(void *pvParameters)
u16MetricCounter = 0U;
/*Burner Error State*/
strcpy(aMetrics[u16MetricCounter].caMetricName, "burner_fault_pending");
aMetrics[u16MetricCounter].type = INTEGER_U8;
aMetrics[u16MetricCounter].u8MetricValue = getBurnerError();
u16MetricCounter++;
/*Circulation Pump State*/
if (getCirculationPumpState() == ENABLED)
{
@ -71,12 +77,6 @@ void taskMetrics(void *pvParameters)
u16MetricCounter++;
}
/*Burner Error State*/
strcpy(aMetrics[u16MetricCounter].caMetricName, "burner_fault_pending");
aMetrics[u16MetricCounter].type = INTEGER_U8;
aMetrics[u16MetricCounter].u8MetricValue = getBurnerError();
u16MetricCounter++;
/*Burner State*/
if (getBurnerState() == ENABLED)
{
@ -93,6 +93,22 @@ void taskMetrics(void *pvParameters)
u16MetricCounter++;
}
/*Safety Contact State*/
if (getSafetyControlState() == ENABLED)
{
strcpy(aMetrics[u16MetricCounter].caMetricName, "safety_contact_enabled");
aMetrics[u16MetricCounter].type = INTEGER_U8;
aMetrics[u16MetricCounter].u8MetricValue = 1U;
u16MetricCounter++;
}
else
{
strcpy(aMetrics[u16MetricCounter].caMetricName, "safety_contact_enabled");
aMetrics[u16MetricCounter].type = INTEGER_U8;
aMetrics[u16MetricCounter].u8MetricValue = 0U;
u16MetricCounter++;
}
/*Chamber Temperature*/
strcpy(aMetrics[u16MetricCounter].caMetricName, "chamber_temperature");
aMetrics[u16MetricCounter].type = FLOAT;

View File

@ -8,10 +8,12 @@
static const char *TAG = "smart-oil-heater-control-system-outputs";
const uint8_t uCirculationPumpGpioPin = 27U;
const uint8_t uBurnerGpioPin = 14U;
const uint8_t uSafetyContactGpioPin = 12U;
static SemaphoreHandle_t xMutexAccessOutputs = NULL;
static eOutput sCirculationPumpState;
static eOutput sBurnerState;
static eOutput sSafetyContactState;
void initOutputs(void)
{
@ -30,8 +32,18 @@ void initOutputs(void)
.pull_down_en = GPIO_PULLDOWN_DISABLE, // Disable pull-down
.intr_type = GPIO_INTR_DISABLE // Disable interrupts
};
gpio_config_t ioConfSafetyContact = {
.pin_bit_mask = (1ULL << uSafetyContactGpioPin), // Pin mask
.mode = GPIO_MODE_OUTPUT, // Set as output
.pull_up_en = GPIO_PULLUP_DISABLE, // Disable pull-up
.pull_down_en = GPIO_PULLDOWN_DISABLE, // Disable pull-down
.intr_type = GPIO_INTR_DISABLE // Disable interrupts
};
gpio_config(&ioConfCirculationPump);
gpio_config(&ioConfBurner);
gpio_config(&ioConfSafetyContact);
xMutexAccessOutputs = xSemaphoreCreateRecursiveMutex();
if (xMutexAccessOutputs == NULL)
@ -105,4 +117,41 @@ void setBurnerState(eOutput in)
{
ESP_LOGE(TAG, "Unable to take mutex: setBurnerState()");
}
}
eOutput getSafetyControlState(void)
{
eOutput ret = ENABLED;
if (xSemaphoreTakeRecursive(xMutexAccessOutputs, pdMS_TO_TICKS(5000)) == pdTRUE)
{
ret = sSafetyContactState;
xSemaphoreGiveRecursive(xMutexAccessOutputs);
}
else
{
ESP_LOGE(TAG, "Unable to take mutex: getSafetyControlState()");
}
return ret;
}
void setSafetyControlState(eOutput in)
{
if (xSemaphoreTakeRecursive(xMutexAccessOutputs, pdMS_TO_TICKS(5000)) == pdTRUE)
{
sSafetyContactState = in;
switch (sSafetyContactState)
{
case ENABLED:
gpio_set_level(uSafetyContactGpioPin, 0U); // Switch on power for Burner
break;
case DISABLED:
gpio_set_level(uSafetyContactGpioPin, 1U); // Switch off power for Burner
default:
break;
}
xSemaphoreGiveRecursive(xMutexAccessOutputs);
}
else
{
ESP_LOGE(TAG, "Unable to take mutex: setSafetyControlState()");
}
}

View File

@ -1,6 +1,7 @@
#pragma once
typedef enum _Output{
typedef enum _Output
{
ENABLED,
DISABLED
} eOutput;
@ -9,4 +10,6 @@ void initOutputs(void);
eOutput getCirculationPumpState(void);
void setCirculationPumpState(eOutput in);
eOutput getBurnerState(void);
void setBurnerState(eOutput in);
void setBurnerState(eOutput in);
eOutput getSafetyControlState(void);
void setSafetyControlState(eOutput in);

View File

@ -132,6 +132,7 @@ void setSafeState(void)
{
setCirculationPumpState(ENABLED); // To cool down system
setBurnerState(DISABLED); // Deactivate burner
setSafetyControlState(DISABLED); // Disable power to Burner
}
void getSensorSanityStates(sSensorSanityCheck *pSensorSanityChecks)