modified to also read channel B

This commit is contained in:
Emanuele Trabattoni
2026-04-10 12:12:28 +02:00
parent 2083119d79
commit 736a8d8bd5
12 changed files with 241 additions and 105 deletions

View File

@@ -27,7 +27,7 @@ monitor_port = COM4
monitor_speed = 921600 monitor_speed = 921600
build_type = release build_type = release
build_flags = build_flags =
-DCORE_DEBUG_LEVEL=1 -DCORE_DEBUG_LEVEL=4
-DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_CDC_ON_BOOT=0
-DARDUINO_USB_MODE=0 -DARDUINO_USB_MODE=0
-DCONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=1 -DCONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=1

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include <Arduino.h> #include <Arduino.h>
#include <map> #include <map>
#include <psvector.h>
// ===================== // =====================
// Event Flags (bitmask) // Event Flags (bitmask)
@@ -88,3 +89,7 @@ struct ignitionBoxStatus
uint32_t n_queue_errors = 0; uint32_t n_queue_errors = 0;
int32_t adc_read_time = 0; int32_t adc_read_time = 0;
}; };
template <typename T>
using PSRAMVector = std::vector<T, PSRAMAllocator<T>>;

View File

@@ -4,7 +4,56 @@
// ISR (Pass return bitmask to ISR management function) // ISR (Pass return bitmask to ISR management function)
// one function for each wake up pin conncted to a trigger // one function for each wake up pin conncted to a trigger
// ===================== // =====================
void trig_isr(void *arg) void trig_isr_A(void *arg)
{
const int64_t time_us = esp_timer_get_time();
// exit if invalid args
if (!arg)
return;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
isrParams *params = (isrParams *)arg;
ignitionBoxStatus *box = params->ign_stat;
TaskHandle_t task_handle = params->rt_handle_ptr;
// exit if task not running
if (!task_handle)
return;
switch (params->flag)
{
case TRIG_FLAG_12P:
case TRIG_FLAG_12N:
// only on first trigger to avoid multiple firing due to noise, to be fixed with hardware debounce
box->coils12.trig_time = time_us;
xTaskNotifyFromISR(task_handle, params->flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
break;
case TRIG_FLAG_34P:
case TRIG_FLAG_34N:
// only on first trigger to avoid multiple firing due to noise, to be fixed with hardware debounce
box->coils34.trig_time = time_us;
xTaskNotifyFromISR(task_handle, params->flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
break;
case SPARK_FLAG_12:
box->coils12.spark_time = time_us;
xTaskNotifyFromISR(task_handle, params->flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
break;
case SPARK_FLAG_34:
box->coils34.spark_time = time_us;
xTaskNotifyFromISR(task_handle, params->flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
break;
default:
break;
}
if (xHigherPriorityTaskWoken)
portYIELD_FROM_ISR();
}
void trig_isr_B(void *arg)
{ {
const int64_t time_us = esp_timer_get_time(); const int64_t time_us = esp_timer_get_time();

View File

@@ -26,4 +26,5 @@ struct isrParams
TaskHandle_t rt_handle_ptr; TaskHandle_t rt_handle_ptr;
}; };
void IRAM_ATTR trig_isr(void *arg); void IRAM_ATTR trig_isr_A(void *arg);
void IRAM_ATTR trig_isr_B(void *arg);

View File

@@ -19,6 +19,7 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
// Defines to enable channel B
// #define CH_B_ENABLE // #define CH_B_ENABLE
#define TEST #define TEST
@@ -81,35 +82,60 @@ void loop()
bool running = true; bool running = true;
const uint32_t max_queue = 128; const uint32_t max_queue = 128;
const uint32_t filter_k = 10; const uint32_t filter_k = 10;
PSRAMVector<ignitionBoxStatus> ignA_history_0(max_history); PSRAMVector<ignitionBoxStatus> ignA_history_0(max_history);
PSRAMVector<ignitionBoxStatus> ignA_history_1(max_history); PSRAMVector<ignitionBoxStatus> ignA_history_1(max_history);
auto *active_history = &ignA_history_0; auto *active_history_A = &ignA_history_0;
auto *writable_history = &ignA_history_1; auto *writable_history_A = &ignA_history_1;
#ifdef CH_B_ENABLE
PSRAMVector<ignitionBoxStatus> ignB_history_0(max_history);
PSRAMVector<ignitionBoxStatus> ignB_history_1(max_history);
auto *active_history_B = &ignB_history_0;
auto *writable_history_B = &ignB_history_1;
#endif
// Resources Initialization // Resources Initialization
Devices dev; Devices dev;
// Task handle // Task handle
TaskHandle_t trigA_TaskHandle = NULL; TaskHandle_t trigA_TaskHandle = NULL;
TaskHandle_t trigB_TaskHandle = NULL;
// Data Queue for real time task to main loop communication // Data Queue for real time task to main loop communication
QueueHandle_t rt_taskA_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); QueueHandle_t rt_taskA_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus));
QueueHandle_t rt_taskB_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus));
rtTaskParams taskA_params{ rtTaskParams taskA_params{
.rt_running = true, .rt_running = true,
.dev = &dev, .dev = &dev,
.rt_handle_ptr = &trigA_TaskHandle, .rt_handle_ptr = &trigA_TaskHandle,
.rt_queue = rt_taskA_queue, .rt_queue = rt_taskA_queue,
.rt_int = rtTaskInterrupts{ .rt_int = rtTaskInterrupts{
.isr_ptr = trig_isr, .isr_ptr = trig_isr_A,
.trig_pin_12p = TRIG_PIN_A12P, .trig_pin_12p = TRIG_PIN_A12P,
.trig_pin_12n = TRIG_PIN_A12N, .trig_pin_12n = TRIG_PIN_A12N,
.trig_pin_34p = TRIG_PIN_A34P, .trig_pin_34p = TRIG_PIN_A34P,
.trig_pin_34n = TRIG_PIN_A34N, .trig_pin_34n = TRIG_PIN_A34N,
.spark_pin_12 = SPARK_PIN_A12, .spark_pin_12 = SPARK_PIN_A12,
.spark_pin_34 = SPARK_PIN_A34}, .spark_pin_34 = SPARK_PIN_A34},
.rt_resets = rtTaskResets{.rst_io_peak= RST_EXT_PEAK_DETECT, .rst_io_sh = RST_EXT_SAMPLE_HOLD}}; .rt_resets = rtTaskResets{.rst_io_peak = RST_EXT_PEAK_DETECT_A, .rst_io_sh = RST_EXT_SAMPLE_HOLD_A}};
if (!rt_taskA_queue || !rt_taskB_queue) #ifdef CH_B_ENABLE
TaskHandle_t trigB_TaskHandle = NULL;
QueueHandle_t rt_taskB_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus));
rtTaskParams taskB_params{
.rt_running = true,
.dev = &dev,
.rt_handle_ptr = &trigB_TaskHandle,
.rt_queue = rt_taskB_queue,
.rt_int = rtTaskInterrupts{
.isr_ptr = trig_isr_B,
.trig_pin_12p = TRIG_PIN_B12P,
.trig_pin_12n = TRIG_PIN_B12N,
.trig_pin_34p = TRIG_PIN_B34P,
.trig_pin_34n = TRIG_PIN_B34N,
.spark_pin_12 = SPARK_PIN_B12,
.spark_pin_34 = SPARK_PIN_B34},
.rt_resets = rtTaskResets{.rst_io_peak = RST_EXT_PEAK_DETECT_B, .rst_io_sh = RST_EXT_SAMPLE_HOLD_B}};
#endif
if (!rt_taskA_queue /*|| !rt_taskB_queue*/)
{ {
LOG_ERROR("Unable To Create task queues"); LOG_ERROR("Unable To Create task queues");
LOG_ERROR("5 seconds to restart..."); LOG_ERROR("5 seconds to restart...");
@@ -119,24 +145,6 @@ void loop()
else else
LOG_DEBUG("Task Variables OK"); LOG_DEBUG("Task Variables OK");
#ifdef CH_B_ENABLE
QueueHandle_t rt_taskB_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus));
rtTaskParams taskB_params{
.rt_running = true,
.dev = &dev,
.rt_handle_ptr = &trigB_TaskHandle,
.rt_queue = rt_taskB_queue,
.rt_int = rtTaskInterrupts{
.isr_ptr = trig_isr,
.trig_pin_12p = TRIG_PIN_B12P,
.trig_pin_12n = TRIG_PIN_B12N,
.trig_pin_34p = TRIG_PIN_B34P,
.trig_pin_34n = TRIG_PIN_B34N,
.spark_pin_12 = SPARK_PIN_B12,
.spark_pin_34 = SPARK_PIN_B34},
.rt_resets = rtTaskResets{.rst_io_12p = RST_EXT_B12P, .rst_io_12n = RST_EXT_B12N, .rst_io_34p = RST_EXT_B34P, .rst_io_34n = RST_EXT_B34N}};
#endif
// Spi ok flags // Spi ok flags
bool spiA_ok = true; bool spiA_ok = true;
bool spiB_ok = true; bool spiB_ok = true;
@@ -145,9 +153,11 @@ void loop()
spiA_ok = SPI_A.begin(SPI_A_SCK, SPI_A_MISO, SPI_A_MOSI); spiA_ok = SPI_A.begin(SPI_A_SCK, SPI_A_MISO, SPI_A_MOSI);
SPI_A.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 SPI_A.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1
#ifdef CH_B_ENABLE #ifdef CH_B_ENABLE
#ifndef TEST
SPIClass SPI_B(HSPI); SPIClass SPI_B(HSPI);
spiB_ok = SPI_B.begin(SPI_B_SCK, SPI_B_MISO, SPI_B_MOSI); spiB_ok = SPI_B.begin(SPI_B_SCK, SPI_B_MISO, SPI_B_MOSI);
SPI_B.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 SPI_B.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1
#endif
#endif #endif
if (!spiA_ok || !spiB_ok) if (!spiA_ok || !spiB_ok)
{ {
@@ -158,18 +168,21 @@ void loop()
} }
LOG_DEBUG("Init SPI OK"); LOG_DEBUG("Init SPI OK");
#ifndef TEST
// Init ADC_A // Init ADC_A
dev.adc_a = new ADS1256(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_A_CS, 2.5, &SPI_A); dev.adc_a = new ADS1256(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_A_CS, 2.5, &SPI_A);
dev.adc_a->InitializeADC(); dev.adc_a->InitializeADC();
dev.adc_a->setPGA(PGA_1); dev.adc_a->setPGA(PGA_1);
dev.adc_a->setDRATE(DRATE_7500SPS); dev.adc_a->setDRATE(DRATE_7500SPS);
#endif
#ifdef CH_B_ENABLE #ifdef CH_B_ENABLE
#ifndef TEST
// Init ADC_B // Init ADC_B
dev.adc_a = new ADS1256(ADC_B_DRDY, ADC_B_RST, ADC_B_SYNC, ADC_B_CS, 2.5, &SPI_B); dev.adc_a = new ADS1256(ADC_B_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_B_CS, 2.5, &SPI_B);
dev.adc_a->InitializeADC(); dev.adc_a->InitializeADC();
dev.adc_a->setPGA(PGA_1); dev.adc_a->setPGA(PGA_1);
dev.adc_a->setDRATE(DRATE_1000SPS); dev.adc_a->setDRATE(DRATE_1000SPS);
#endif
#endif #endif
LOG_DEBUG("Init ADC OK"); LOG_DEBUG("Init ADC OK");
@@ -178,7 +191,7 @@ void loop()
auto ignA_task_success = pdPASS; auto ignA_task_success = pdPASS;
ignA_task_success = xTaskCreatePinnedToCore( ignA_task_success = xTaskCreatePinnedToCore(
rtIgnitionTask, rtIgnitionTask,
"rtIgnitionTask_boxA", "rtTask_A",
RT_TASK_STACK, RT_TASK_STACK,
(void *)&taskA_params, (void *)&taskA_params,
RT_TASK_PRIORITY, RT_TASK_PRIORITY,
@@ -188,15 +201,16 @@ void loop()
// Ignition B on Core 1 // Ignition B on Core 1
auto ignB_task_success = pdPASS; auto ignB_task_success = pdPASS;
#ifdef CH_B_ENABLE #ifdef CH_B_ENABLE
ignB_task_success = xTaskCreatePinnedToCore( ignB_task_success = xTaskCreatePinnedToCore(
rtIgnitionTask, rtIgnitionTask,
"rtIgnitionTask_boxB", "rtTask_B",
RT_TASK_STACK, RT_TASK_STACK,
(void *)&taskB_params, (void *)&taskB_params,
RT_TASK_PRIORITY, // priorità leggermente più alta RT_TASK_PRIORITY, // priorità leggermente più alta
&trigB_TaskHandle, &trigB_TaskHandle,
CORE_1); CORE_0);
delay(100); // give some time to the thread to start delay(100); // give some time to the thread to start
#endif #endif
@@ -214,48 +228,74 @@ void loop()
bool partial_save = false; // flag to indicate if a partial save has been done after a timeout bool partial_save = false; // flag to indicate if a partial save has been done after a timeout
uint32_t counter = 0; uint32_t counter = 0;
uint32_t wait_count = 0; uint32_t wait_count = 0;
ignitionBoxStatus ign_info; ignitionBoxStatus ign_info_A;
ignitionBoxStatusAverage ign_info_avg(filter_k); ignitionBoxStatus ign_info_B;
ignitionBoxStatusAverage ign_info_avg_A(filter_k);
ignitionBoxStatusAverage ign_info_avg_B(filter_k);
LITTLEFSGuard fsGuard; LITTLEFSGuard fsGuard;
WebPage webPage(80, LittleFS); // Initialize webserver and Websocket WebPage webPage(80, LittleFS); // Initialize webserver and Websocket
while (running) while (running)
{ {
if (counter >= active_history->size()) // not concurrent with write task auto dataA = pdFALSE;
auto dataB = pdFALSE;
if (counter >= active_history_A->size()) // not concurrent with write task
{ {
counter = 0; counter = 0;
partial_save = false; // reset partial save flag on new data cycle partial_save = false; // reset partial save flag on new data cycle
auto *temp = active_history; swapHistory(active_history_A, writable_history_A);
active_history = writable_history; // switch active and writable buffers save_history(*writable_history_A, "ignition_historyA.csv"); // directly call the save task function to save without delay
writable_history = temp; // ensure writable_history points to the buffer we just filled
dataSaveParams save_params{
.history = writable_history,
.file_path = "ignition_history.csv"};
save_history(*writable_history, "ignition_history.csv"); // directly call the save task function to save without delay
} }
dataA = xQueueReceive(rt_taskA_queue, &ign_info_A, pdMS_TO_TICKS(100));
#ifdef CH_B_ENABLE
if (counter >= active_history_B->size()) // not concurrent with write task
{
counter = 0;
partial_save = false; // reset partial save flag on new data cycle
swapHistory(active_history_B, writable_history_B);
save_history(*writable_history_B, "ignition_historyB.csv"); // directly call the save task function to save without delay
}
dataB = xQueueReceive(rt_taskB_queue, &ign_info_B, pdMS_TO_TICKS(100));
#endif
if (xQueueReceive(rt_taskA_queue, &ign_info, pdMS_TO_TICKS(1000)) == pdTRUE) if (dataA == pdTRUE || dataB == pdTRUE)
{ {
// printInfo(ign_info); // printInfo(ign_info);
auto &hist = *active_history; (*active_history_A)[counter % active_history_A->size()] = ign_info_A;
hist[counter++ % active_history->size()] = ign_info; #ifdef CH_B_ENABLE
ign_info_avg.update(ign_info); // update moving average with latest ignition status (*active_history_B)[counter % active_history_B->size()] = ign_info_B;
Serial.printf("\033[2K Data Received: %d/%d\r", counter, hist.size()); #endif
ign_info_avg_A.update(ign_info_A); // update moving average with latest ignition status
ign_info_avg_B.update(ign_info_B); // update moving average with latest ignition status
Serial.printf("\033[2K Data Received A: %d/%d\r", counter, (*active_history_A).size());
if (counter % filter_k == 0) // send data every 10 samples if (counter % filter_k == 0) // send data every 10 samples
{ {
Serial.println(); Serial.println();
LOG_DEBUG("Sending average ignition status to websocket clients..."); LOG_DEBUG("Sending average ignition status to websocket clients...");
webPage.sendWsData(ign_info_avg.toJson().as<String>()); ArduinoJson::JsonDocument wsData;
wsData["box_a"] = ign_info_avg_A.toJson();
wsData["box_b"] = ign_info_avg_B.toJson();
webPage.sendWsData(wsData.as<String>());
} }
counter++;
} }
else else
{ {
Serial.printf("[%d] Waiting for data...\r", wait_count++); Serial.printf("[%d] Waiting for data...\r", wait_count++);
if (!partial_save && counter > 0) // if timeout occurs but we have unsaved data, save it before next timeout if (!partial_save && counter > 0) // if timeout occurs but we have unsaved data, save it before next timeout
{ {
active_history->resize(counter); // resize active history to actual number of records received to avoid saving empty records active_history_A->resize(counter); // resize active history to actual number of records received to avoid saving empty records
save_history(*active_history, "ignition_history.csv"); save_history(*active_history_A, "ignition_history_A.csv");
active_history->resize(max_history); // resize back to max history size for next data cycle active_history_A->resize(max_history); // resize back to max history size for next data cycle
#ifdef CH_B_ENABLE
active_history_B->resize(counter); // resize active history to actual number of records received to avoid saving empty records
save_history(*active_history_B, "ignition_history_B.csv");
active_history_B->resize(max_history); // resize back to max history size for next data cycle
#endif
counter = 0; // reset counter after saving counter = 0; // reset counter after saving
partial_save = true; partial_save = true;
first_save = true; first_save = true;
@@ -266,7 +306,9 @@ void loop()
if (trigA_TaskHandle) if (trigA_TaskHandle)
vTaskDelete(trigA_TaskHandle); vTaskDelete(trigA_TaskHandle);
#ifdef CH_B_ENABLE
if (trigB_TaskHandle) if (trigB_TaskHandle)
vTaskDelete(trigB_TaskHandle); vTaskDelete(trigB_TaskHandle);
#endif
////////////////////// MAIN LOOP ////////////////////// ////////////////////// MAIN LOOP //////////////////////
} }

View File

@@ -84,18 +84,18 @@
// ===================== // =====================
// --- RESET LINES --- // --- RESET LINES ---
#define RST_EXT_PEAK_DETECT 0 #define RST_EXT_PEAK_DETECT_A 0
#define RST_EXT_SAMPLE_HOLD 1 #define RST_EXT_SAMPLE_HOLD_A 1
#define BTN_1 2 #define RST_EXT_PEAK_DETECT_B 2
#define BTN_2 3 #define RST_EXT_SAMPLE_HOLD_B 3
#define BTN_3 4 #define BTN_3 4
#define BTN_4 5 #define BTN_4 5
#define BTN_5 6 #define BTN_5 6
#define BTN_6 7 #define BTN_6 7
// --- RELAY --- // --- RELAY ---
#define A_EXT_RELAY 8 #define EXT_RELAY_A 8
#define B_EXT_RELAY 9 #define EXT_RELAY_B 9
// --- STATUS / BUTTON --- // --- STATUS / BUTTON ---
#define BTN_7 10 #define BTN_7 10

View File

@@ -65,7 +65,7 @@
#define RST_EXT_A34N 3 #define RST_EXT_A34N 3
// --- RELAY --- // --- RELAY ---
#define A_EXT_RELAY 8 #define EXT_RELAY_A 8
// Init Pin Functions // Init Pin Functions

View File

@@ -25,6 +25,3 @@ struct PSRAMAllocator {
heap_caps_free(p); heap_caps_free(p);
} }
}; };
template <typename T>
using PSRAMVector = std::vector<T, PSRAMAllocator<T>>;

View File

@@ -2,5 +2,12 @@
#include <Arduino.h> #include <Arduino.h>
#include <string> #include <string>
#include <datastruct.h>
std::string printBits(uint32_t value); std::string printBits(uint32_t value);
inline void swapHistory(PSRAMVector<ignitionBoxStatus>* active, PSRAMVector<ignitionBoxStatus>* writable) {
auto *temp = active;
active = writable; // switch active and writable buffers
writable = temp; // ensure writable_history points to the buffer we just filled
}

View File

@@ -1,3 +1,5 @@
#define DEBUGLOG_DEFAULT_LOG_LEVEL_DEBUG
#include <Arduino.h> #include <Arduino.h>
#include <DebugLog.h> #include <DebugLog.h>
@@ -52,6 +54,31 @@ static timerStatus stsA = {
.coil_pulse_us = 1000, .coil_pulse_us = 1000,
.spark_pulse_us = 100, .spark_pulse_us = 100,
.spark_delay_us = 50, .spark_delay_us = 50,
.pins = {
.pin_trig_12p = PIN_TRIG_A12P,
.pin_trig_12n = PIN_TRIG_A12N,
.pin_trig_34p = PIN_TRIG_A34P,
.pin_trig_34n = PIN_TRIG_A34N,
.pin_spark_12 = SPARK_A12,
.pin_spark_34 = SPARK_A34
},
.main_task = NULL};
static timerStatus stsB = {
.clock_period_us = (uint32_t)PERIOD_US,
.pause_long_us = 10000,
.pause_short_us = 1000,
.coil_pulse_us = 1000,
.spark_pulse_us = 100,
.spark_delay_us = 50,
.pins = {
.pin_trig_12p = PIN_TRIG_B12P,
.pin_trig_12n = PIN_TRIG_B12N,
.pin_trig_34p = PIN_TRIG_B34P,
.pin_trig_34n = PIN_TRIG_B34N,
.pin_spark_12 = SPARK_B12,
.pin_spark_34 = SPARK_B34
},
.main_task = NULL}; .main_task = NULL};
static bool isEnabled = false; static bool isEnabled = false;
@@ -82,12 +109,23 @@ void setup()
pinMode(ENABLE_PIN, INPUT_PULLUP); pinMode(ENABLE_PIN, INPUT_PULLUP);
// get the task handle for the main loop
stsA.main_task = xTaskGetCurrentTaskHandleForCore(1); stsA.main_task = xTaskGetCurrentTaskHandleForCore(1);
stsB.main_task = xTaskGetCurrentTaskHandleForCore(1);
// Begin timer with preset fixed frequency
timerA = timerBegin(FREQUENCY); timerA = timerBegin(FREQUENCY);
timerB = timerBegin(FREQUENCY);
// Stop timers because of autostart
timerStop(timerA); timerStop(timerA);
timerStop(timerB);
// Attach interrupts and call callback every timer expiry
timerAttachInterruptArg(timerA, &onTimer, (void *)&stsA); timerAttachInterruptArg(timerA, &onTimer, (void *)&stsA);
timerAlarm(timerA, 1, true, 0); timerAttachInterruptArg(timerB, &onTimer, (void *)&stsB);
timerAlarm(timerA, 1, true, 0); // infinite number of reloads
timerAlarm(timerB, 1, true, 0);
LOG_INFO("Setup Complete"); LOG_INFO("Setup Complete");
} }
@@ -103,10 +141,13 @@ void loop()
} else { } else {
stsA.soft_start = false; stsA.soft_start = false;
} }
stsB.soft_start = stsA.soft_start;
stsB.spark_delay_us = stsA.spark_delay_us;
double new_rpm = (double)(map(analogRead(FREQ_POT), 0, 4096, RPM_MIN, RPM_MAX)); double new_rpm = (double)(map(analogRead(FREQ_POT), 0, 4096, RPM_MIN, RPM_MAX));
filtered_rpm = filtered_rpm + 0.1 * (new_rpm - filtered_rpm); filtered_rpm = filtered_rpm + 0.1 * (new_rpm - filtered_rpm);
stsA.pause_long_us = (uint32_t)(60000000.0f / filtered_rpm / 2.0f); stsA.pause_long_us = (uint32_t)(60000000.0f / filtered_rpm / 2.0f);
stsB.pause_long_us = stsA.pause_long_us;
if (isEnabled) { if (isEnabled) {
LOG_INFO("==== System is ENABLED ===="); LOG_INFO("==== System is ENABLED ====");
@@ -121,8 +162,11 @@ void loop()
if (digitalRead(ENABLE_PIN) == LOW && !isEnabled) { if (digitalRead(ENABLE_PIN) == LOW && !isEnabled) {
timerStart(timerA); timerStart(timerA);
delayMicroseconds(50);
timerStart(timerB);
isEnabled = true; isEnabled = true;
} else if (digitalRead(ENABLE_PIN) == HIGH && isEnabled) { } else if (digitalRead(ENABLE_PIN) == HIGH && isEnabled) {
timerStop(timerA);
timerStop(timerA); timerStop(timerA);
isEnabled = false; isEnabled = false;
} }

View File

@@ -7,20 +7,18 @@ void onTimer(void *arg)
BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t xHigherPriorityTaskWoken = pdFALSE;
timerStatus *params = (timerStatus *)(arg); timerStatus *params = (timerStatus *)(arg);
TaskHandle_t task = params->main_task; TaskHandle_t task = params->main_task;
const timerPins pins = params->pins;
// increment state time // increment state time
params->state_time += params->clock_period_us; params->state_time += params->clock_period_us;
digitalWrite(PIN_TRIG_B12P, HIGH);
switch (params->state) switch (params->state)
{ {
case S_12P: case S_12P:
if (params->state_time == params->clock_period_us && !params->coil12p_high) if (params->state_time == params->clock_period_us && !params->coil12p_high)
{ {
// xTaskNotifyFromISR(task, PIN_TRIG_A12P, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); digitalWrite(pins.pin_trig_12p, HIGH);
digitalWrite(PIN_TRIG_A12P, HIGH);
params->coil12p_high = true; params->coil12p_high = true;
wait_sent = false; wait_sent = false;
} }
@@ -29,21 +27,18 @@ void onTimer(void *arg)
{ {
if (params->state_time == params->spark_delay_us) if (params->state_time == params->spark_delay_us)
{ {
// xTaskNotifyFromISR(task, SPARK_A12, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); digitalWrite(pins.pin_spark_12, HIGH);
digitalWrite(SPARK_A12, HIGH);
} }
if (params->state_time == (params->spark_delay_us + params->spark_pulse_us)) if (params->state_time == (params->spark_delay_us + params->spark_pulse_us))
{ {
// xTaskNotifyFromISR(task, ~SPARK_A12, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); digitalWrite(pins.pin_spark_12, LOW);
digitalWrite(SPARK_A12, LOW);
} }
} }
if (params->state_time >= params->coil_pulse_us && params->coil12p_high) if (params->state_time >= params->coil_pulse_us && params->coil12p_high)
{ {
// xTaskNotifyFromISR(task, ~PIN_TRIG_A12P, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); digitalWrite(pins.pin_trig_12p, LOW);
digitalWrite(PIN_TRIG_A12P, LOW);
params->coil12p_high = false; params->coil12p_high = false;
} }
@@ -57,8 +52,7 @@ void onTimer(void *arg)
case S_12N: case S_12N:
if (params->state_time == params->clock_period_us && !params->coil12n_high) if (params->state_time == params->clock_period_us && !params->coil12n_high)
{ {
// xTaskNotifyFromISR(task, PIN_TRIG_A12N, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); digitalWrite(pins.pin_trig_12n, HIGH);
digitalWrite(PIN_TRIG_A12N, HIGH);
params->coil12n_high = true; params->coil12n_high = true;
} }
@@ -66,21 +60,18 @@ void onTimer(void *arg)
{ {
if (params->state_time == params->spark_delay_us) if (params->state_time == params->spark_delay_us)
{ {
// xTaskNotifyFromISR(task, SPARK_A12, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); digitalWrite(pins.pin_spark_12, HIGH);
digitalWrite(SPARK_A12, HIGH);
} }
if (params->state_time == (params->spark_delay_us + params->spark_pulse_us)) if (params->state_time == (params->spark_delay_us + params->spark_pulse_us))
{ {
// xTaskNotifyFromISR(task, ~SPARK_A12, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); digitalWrite(pins.pin_spark_12, LOW);
digitalWrite(SPARK_A12, LOW);
} }
} }
if (params->state_time >= params->coil_pulse_us && params->coil12n_high) if (params->state_time >= params->coil_pulse_us && params->coil12n_high)
{ {
// xTaskNotifyFromISR(task, ~PIN_TRIG_A12N, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); digitalWrite(pins.pin_trig_12n, LOW);
digitalWrite(PIN_TRIG_A12N, LOW);
params->coil12n_high = false; params->coil12n_high = false;
params->state = S_WAIT_10MS; params->state = S_WAIT_10MS;
params->state_time = 0; params->state_time = 0;
@@ -90,7 +81,6 @@ void onTimer(void *arg)
case S_WAIT_10MS: case S_WAIT_10MS:
if (!wait_sent) if (!wait_sent)
{ {
// xTaskNotifyFromISR(task, S_WAIT_10MS, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
wait_sent = true; wait_sent = true;
} }
if (params->state_time >= params->pause_long_us) if (params->state_time >= params->pause_long_us)
@@ -103,8 +93,7 @@ void onTimer(void *arg)
case S_34P: case S_34P:
if (params->state_time == params->clock_period_us && !params->coil34p_high) if (params->state_time == params->clock_period_us && !params->coil34p_high)
{ {
// xTaskNotifyFromISR(task, PIN_TRIG_A34P, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); digitalWrite(pins.pin_trig_34p, HIGH);
digitalWrite(PIN_TRIG_A34P, HIGH);
params->coil34p_high = true;; params->coil34p_high = true;;
wait_sent = false; wait_sent = false;
} }
@@ -113,21 +102,18 @@ void onTimer(void *arg)
{ {
if (params->state_time == params->spark_delay_us) if (params->state_time == params->spark_delay_us)
{ {
// xTaskNotifyFromISR(task, SPARK_A34, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); digitalWrite(pins.pin_spark_34, HIGH);
digitalWrite(SPARK_A34, HIGH);
} }
if (params->state_time == params->spark_delay_us + params->spark_pulse_us) if (params->state_time == params->spark_delay_us + params->spark_pulse_us)
{ {
// xTaskNotifyFromISR(task, ~SPARK_A34, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); digitalWrite(pins.pin_spark_34, LOW);
digitalWrite(SPARK_A34, LOW);
} }
} }
if (params->state_time >= params->coil_pulse_us && params->coil34p_high) if (params->state_time >= params->coil_pulse_us && params->coil34p_high)
{ {
// xTaskNotifyFromISR(task, ~PIN_TRIG_A34P, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); digitalWrite(pins.pin_trig_34p, LOW);
digitalWrite(PIN_TRIG_A34P, LOW);
params->coil34p_high = false; params->coil34p_high = false;
} }
@@ -141,8 +127,7 @@ void onTimer(void *arg)
case S_34N: case S_34N:
if (params->state_time == params->clock_period_us && !params->coil34n_high) if (params->state_time == params->clock_period_us && !params->coil34n_high)
{ {
// xTaskNotifyFromISR(task, PIN_TRIG_A34N, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); digitalWrite(pins.pin_trig_34n, HIGH);
digitalWrite(PIN_TRIG_A34N, HIGH);
params->coil34n_high = true; params->coil34n_high = true;
} }
@@ -150,21 +135,18 @@ void onTimer(void *arg)
{ {
if (params->state_time == params->spark_delay_us) if (params->state_time == params->spark_delay_us)
{ {
// xTaskNotifyFromISR(task, SPARK_A34, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); digitalWrite(pins.pin_spark_34, HIGH);
digitalWrite(SPARK_A34, HIGH);
} }
if (params->state_time == params->spark_delay_us + params->spark_pulse_us) if (params->state_time == params->spark_delay_us + params->spark_pulse_us)
{ {
// xTaskNotifyFromISR(task, ~SPARK_A34, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); digitalWrite(pins.pin_spark_34, LOW);
digitalWrite(SPARK_A34, LOW);
} }
} }
if (params->state_time >= params->coil_pulse_us && params->coil34n_high) if (params->state_time >= params->coil_pulse_us && params->coil34n_high)
{ {
// xTaskNotifyFromISR(task, ~PIN_TRIG_A34N, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); digitalWrite(pins.pin_trig_34n, LOW);
digitalWrite(PIN_TRIG_A34N, LOW);
params->coil34n_high = false; params->coil34n_high = false;
params->state = S_WAIT_10MS_END; params->state = S_WAIT_10MS_END;
params->state_time = 0; params->state_time = 0;
@@ -174,7 +156,6 @@ void onTimer(void *arg)
case S_WAIT_10MS_END: case S_WAIT_10MS_END:
if (!wait_sent) if (!wait_sent)
{ {
// xTaskNotifyFromISR(task, S_WAIT_10MS_END, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
wait_sent = true; wait_sent = true;
} }
if (params->state_time >= params->pause_long_us) if (params->state_time >= params->pause_long_us)
@@ -185,8 +166,6 @@ void onTimer(void *arg)
break; break;
} }
digitalWrite(PIN_TRIG_B12P, LOW);
if (xHigherPriorityTaskWoken) if (xHigherPriorityTaskWoken)
portYIELD_FROM_ISR(); portYIELD_FROM_ISR();
} }

View File

@@ -1,5 +1,7 @@
#pragma once #pragma once
#define DEBUGLOG_DEFAULT_LOG_LEVEL_DEBUG
#include <Arduino.h> #include <Arduino.h>
#include <DebugLog.h> #include <DebugLog.h>
#include "pins.h" #include "pins.h"
@@ -19,6 +21,15 @@ enum State
S_WAIT_10MS_END S_WAIT_10MS_END
}; };
struct timerPins {
const uint8_t pin_trig_12p;
const uint8_t pin_trig_12n;
const uint8_t pin_trig_34p;
const uint8_t pin_trig_34n;
const uint8_t pin_spark_12;
const uint8_t pin_spark_34;
};
struct timerStatus struct timerStatus
{ {
State state = State::S_12P; State state = State::S_12P;
@@ -34,6 +45,7 @@ struct timerStatus
bool coil34p_high = false; bool coil34p_high = false;
bool coil12n_high = false; bool coil12n_high = false;
bool coil34n_high = false; bool coil34n_high = false;
timerPins pins;
TaskHandle_t main_task; TaskHandle_t main_task;
}; };