From 246ba7eeb275db47ccc45ba9cbc3abc48941ca6e Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Fri, 10 Apr 2026 22:03:09 +0200 Subject: [PATCH] Task A+B concurrency

Box_A

-

Timestamp: -

-

Data Valid: -

-

Generator voltage: -

-

ADC read time: -

-

Queue errors: -

+

Timestamp: -

+

Data Valid: -

+

Generator voltage: -

+

ADC read time: -

+

Queue errors: -

- Engine RPM: - + Engine RPM: -
@@ -46,53 +46,53 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +
Spark delay----
Spark status----
Soft start status----
Peak P in----
Peak N in----
Peak P out----
Peak N out----
Level spark----
Spark Events----
Missed Events----
diff --git a/RotaxMonitor/data/script.js b/RotaxMonitor/data/script.js index 5ea3c66..7ab466c 100644 --- a/RotaxMonitor/data/script.js +++ b/RotaxMonitor/data/script.js @@ -49,36 +49,36 @@ function connectWS() { // Update Box_A if (data.box_a) { const boxA = data.box_a; - document.getElementById("datavalid").textContent = boxA.datavalid ?? "-"; - document.getElementById("timestamp").textContent = boxA.timestamp ?? "-"; - document.getElementById("volts_gen").textContent = boxA.volts_gen ?? "-"; - document.getElementById("eng_rpm").textContent = boxA.eng_rpm ?? "-"; - document.getElementById("adc_read_time").textContent = boxA.adc_read_time ?? "-"; - document.getElementById("n_queue_errors").textContent = boxA.n_queue_errors ?? "-"; + document.getElementById("a_datavalid").textContent = boxA.datavalid ?? "-"; + document.getElementById("a_timestamp").textContent = boxA.timestamp ?? "-"; + document.getElementById("a_volts_gen").textContent = boxA.volts_gen ?? "-"; + document.getElementById("a_eng_rpm").textContent = boxA.eng_rpm ?? "-"; + document.getElementById("a_adc_read_time").textContent = boxA.adc_read_time ?? "-"; + document.getElementById("a_n_queue_errors").textContent = boxA.n_queue_errors ?? "-"; const coils12A = boxA.coils12 || {}; const coils34A = boxA.coils34 || {}; - document.getElementById("coils12_spark_delay").textContent = coils12A.spark_delay ?? "-"; - document.getElementById("coils34_spark_delay").textContent = coils34A.spark_delay ?? "-"; - document.getElementById("coils12_spark_status").textContent = coils12A.spark_status ?? "-"; - document.getElementById("coils34_spark_status").textContent = coils34A.spark_status ?? "-"; - document.getElementById("coils12_sstart_status").textContent = coils12A.sstart_status ?? "-"; - document.getElementById("coils34_sstart_status").textContent = coils34A.sstart_status ?? "-"; - document.getElementById("coils12_peak_p_in").textContent = coils12A.peak_p_in ?? "-"; - document.getElementById("coils34_peak_p_in").textContent = coils34A.peak_p_in ?? "-"; - document.getElementById("coils12_peak_n_in").textContent = coils12A.peak_n_in ?? "-"; - document.getElementById("coils34_peak_n_in").textContent = coils34A.peak_n_in ?? "-"; - document.getElementById("coils12_peak_p_out").textContent = coils12A.peak_p_out ?? "-"; - document.getElementById("coils34_peak_p_out").textContent = coils34A.peak_p_out ?? "-"; - document.getElementById("coils12_peak_n_out").textContent = coils12A.peak_n_out ?? "-"; - document.getElementById("coils34_peak_n_out").textContent = coils34A.peak_n_out ?? "-"; - document.getElementById("coils12_level_spark").textContent = coils12A.level_spark ?? "-"; - document.getElementById("coils34_level_spark").textContent = coils34A.level_spark ?? "-"; - document.getElementById("coils12_n_events").textContent = coils12A.n_events ?? "-"; - document.getElementById("coils34_n_events").textContent = coils34A.n_events ?? "-"; - document.getElementById("coils12_n_missed_firing").textContent = coils12A.n_missed_firing ?? "-"; - document.getElementById("coils34_n_missed_firing").textContent = coils34A.n_missed_firing ?? "-"; + document.getElementById("a_coils12_spark_delay").textContent = coils12A.spark_delay ?? "-"; + document.getElementById("a_coils34_spark_delay").textContent = coils34A.spark_delay ?? "-"; + document.getElementById("a_coils12_spark_status").textContent = coils12A.spark_status ?? "-"; + document.getElementById("a_coils34_spark_status").textContent = coils34A.spark_status ?? "-"; + document.getElementById("a_coils12_sstart_status").textContent = coils12A.sstart_status ?? "-"; + document.getElementById("a_coils34_sstart_status").textContent = coils34A.sstart_status ?? "-"; + document.getElementById("a_coils12_peak_p_in").textContent = coils12A.peak_p_in ?? "-"; + document.getElementById("a_coils34_peak_p_in").textContent = coils34A.peak_p_in ?? "-"; + document.getElementById("a_coils12_peak_n_in").textContent = coils12A.peak_n_in ?? "-"; + document.getElementById("a_coils34_peak_n_in").textContent = coils34A.peak_n_in ?? "-"; + document.getElementById("a_coils12_peak_p_out").textContent = coils12A.peak_p_out ?? "-"; + document.getElementById("a_coils34_peak_p_out").textContent = coils34A.peak_p_out ?? "-"; + document.getElementById("a_coils12_peak_n_out").textContent = coils12A.peak_n_out ?? "-"; + document.getElementById("a_coils34_peak_n_out").textContent = coils34A.peak_n_out ?? "-"; + document.getElementById("a_coils12_level_spark").textContent = coils12A.level_spark ?? "-"; + document.getElementById("a_coils34_level_spark").textContent = coils34A.level_spark ?? "-"; + document.getElementById("a_coils12_n_events").textContent = coils12A.n_events ?? "-"; + document.getElementById("a_coils34_n_events").textContent = coils34A.n_events ?? "-"; + document.getElementById("a_coils12_n_missed_firing").textContent = coils12A.n_missed_firing ?? "-"; + document.getElementById("a_coils34_n_missed_firing").textContent = coils34A.n_missed_firing ?? "-"; } // Update Box_B diff --git a/RotaxMonitor/platformio.ini b/RotaxMonitor/platformio.ini index 4b5097f..41ef22d 100644 --- a/RotaxMonitor/platformio.ini +++ b/RotaxMonitor/platformio.ini @@ -21,17 +21,15 @@ lib_deps = me-no-dev/AsyncTCP@^3.3.2 me-no-dev/ESPAsyncWebServer@^3.6.0 upload_protocol = esptool -upload_port = COM8 +upload_port = /dev/ttyACM1 upload_speed = 921600 -monitor_port = COM4 +monitor_port = /dev/ttyACM0 monitor_speed = 921600 build_type = release build_flags = -DCORE_DEBUG_LEVEL=4 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MODE=0 - -DCONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=1 - -DCONFIG_FREERTOS_USE_TRACE_FACILITY=1 -DCONFIG_ASYNC_TCP_MAX_ACK_TIME=5000 -DCONFIG_ASYNC_TCP_PRIORITY=20 -DCONFIG_ASYNC_TCP_QUEUE_SIZE=128 @@ -48,9 +46,9 @@ framework = ${env:esp32-s3-devkitc1-n16r8.framework} lib_deps = ${env:esp32-s3-devkitc1-n16r8.lib_deps} upload_protocol = esptool -upload_port = COM8 +upload_port = /dev/ttyACM1 upload_speed = 921600 -monitor_port = COM4 +monitor_port = /dev/ttyACM0 monitor_speed = 921600 debug_tool = esp-builtin debug_speed = 15000 @@ -62,8 +60,6 @@ build_flags = -DCORE_DEBUG_LEVEL=3 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MODE=0 - -DCONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=1 - -DCONFIG_FREERTOS_USE_TRACE_FACILITY=1 -DCONFIG_ASYNC_TCP_MAX_ACK_TIME=5000 -DCONFIG_ASYNC_TCP_PRIORITY=20 -DCONFIG_ASYNC_TCP_QUEUE_SIZE=128 diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index cf1cd4c..4ac0bd7 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -20,7 +20,7 @@ #include "freertos/task.h" // Defines to enable channel B -// #define CH_B_ENABLE +#define CH_B_ENABLE #define TEST // Debug Defines @@ -99,15 +99,17 @@ void loop() Devices dev; // Task handle TaskHandle_t trigA_TaskHandle = NULL; + TaskHandle_t trigB_TaskHandle = NULL; // Data Queue for real time task to main loop communication QueueHandle_t rt_taskA_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); + QueueHandle_t rt_taskB_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); + rtTaskParams taskA_params{ .rt_running = true, .dev = &dev, - .rt_handle_ptr = &trigA_TaskHandle, .rt_queue = rt_taskA_queue, .rt_int = rtTaskInterrupts{ - .isr_ptr = trig_isr_A, + .isr_ptr = &trig_isr_A, .trig_pin_12p = TRIG_PIN_A12P, .trig_pin_12n = TRIG_PIN_A12N, .trig_pin_34p = TRIG_PIN_A34P, @@ -117,15 +119,12 @@ void loop() .rt_resets = rtTaskResets{.rst_io_peak = RST_EXT_PEAK_DETECT_A, .rst_io_sh = RST_EXT_SAMPLE_HOLD_A}}; #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, + .isr_ptr = &trig_isr_B, .trig_pin_12p = TRIG_PIN_B12P, .trig_pin_12n = TRIG_PIN_B12N, .trig_pin_34p = TRIG_PIN_B34P, @@ -135,7 +134,7 @@ void loop() .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*/) + if (!rt_taskA_queue || !rt_taskB_queue) { LOG_ERROR("Unable To Create task queues"); LOG_ERROR("5 seconds to restart..."); @@ -210,7 +209,7 @@ void loop() (void *)&taskB_params, RT_TASK_PRIORITY, // priorità leggermente più alta &trigB_TaskHandle, - CORE_0); + CORE_1); delay(100); // give some time to the thread to start #endif @@ -226,12 +225,18 @@ void loop() ////////////////////// MAIN LOOP ////////////////////// bool partial_save = false; // flag to indicate if a partial save has been done after a timeout - uint32_t counter = 0; + auto last_data = millis(); + uint32_t counter_a = 0; + uint32_t counter_b = 0; + uint32_t wait_count = 0; + ignitionBoxStatus ign_info_A; ignitionBoxStatus ign_info_B; + ignitionBoxStatusAverage ign_info_avg_A(filter_k); ignitionBoxStatusAverage ign_info_avg_B(filter_k); + LITTLEFSGuard fsGuard; WebPage webPage(80, LittleFS); // Initialize webserver and Websocket @@ -240,66 +245,78 @@ void loop() auto dataA = pdFALSE; auto dataB = pdFALSE; - if (counter >= active_history_A->size()) // not concurrent with write task + dataA = xQueueReceive(rt_taskA_queue, &ign_info_A, pdMS_TO_TICKS(10)); + if (counter_a >= active_history_A->size()) // not concurrent with write task { - counter = 0; + counter_a = 0; partial_save = false; // reset partial save flag on new data cycle swapHistory(active_history_A, writable_history_A); save_history(*writable_history_A, "ignition_historyA.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 + dataB = xQueueReceive(rt_taskB_queue, &ign_info_B, pdMS_TO_TICKS(10)); + if (counter_b >= active_history_B->size()) // not concurrent with write task { - counter = 0; + counter_b = 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 - + // Update last data if (dataA == pdTRUE || dataB == pdTRUE) { - // printInfo(ign_info); - (*active_history_A)[counter % active_history_A->size()] = ign_info_A; -#ifdef CH_B_ENABLE - (*active_history_B)[counter % active_history_B->size()] = ign_info_B; -#endif + last_data = millis(); + } + + if (dataA == pdTRUE) + { + (*active_history_A)[counter_a++ % active_history_A->size()] = ign_info_A; 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 + Serial.printf("Data Received A: %d/%d\n\r", counter_a, (*active_history_A).size()); + if (counter_a % filter_k == 0) // send data every 10 samples { - Serial.println(); - LOG_DEBUG("Sending average ignition status to websocket clients..."); ArduinoJson::JsonDocument wsData; wsData["box_a"] = ign_info_avg_A.toJson(); + wsData["box_b"] = JsonObject(); + webPage.sendWsData(wsData.as()); + } + } +#ifdef CH_B_ENABLE + if (dataB == pdTRUE) + { + (*active_history_B)[counter_b++ % active_history_B->size()] = ign_info_B; + ign_info_avg_B.update(ign_info_B); // update moving average with latest ignition status + Serial.printf("Data Received B: %d/%d\n\r", counter_b, (*active_history_B).size()); + if (counter_b % filter_k == 0) // send data every 10 samples + { + ArduinoJson::JsonDocument wsData; + wsData["box_a"] = JsonObject(); wsData["box_b"] = ign_info_avg_B.toJson(); webPage.sendWsData(wsData.as()); } - - counter++; } - else +#endif + if (dataA == pdFALSE && dataB == pdFALSE && millis() - last_data > 2000) { - 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_a > 0) // if timeout occurs but we have unsaved data, save it before next timeout { - active_history_A->resize(counter); // resize active history to actual number of records received to avoid saving empty records + active_history_A->resize(counter_a); // resize active history to actual number of records received to avoid saving empty records save_history(*active_history_A, "ignition_history_A.csv"); 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 + active_history_B->resize(counter_a); // 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_a = 0; // reset counter after saving + counter_b = 0; // reset counter after saving + partial_save = true; first_save = true; } + Serial.printf("[%d] Waiting for data...\r", wait_count++); delay(500); } } diff --git a/RotaxMonitor/src/tasks.cpp b/RotaxMonitor/src/tasks.cpp index 8bbc8f2..948a29f 100644 --- a/RotaxMonitor/src/tasks.cpp +++ b/RotaxMonitor/src/tasks.cpp @@ -17,57 +17,65 @@ void rtIgnitionTask(void *pvParameters) LOG_ERROR("Null rt_task_ptr parameters"); vTaskDelete(NULL); } - LOG_INFO("rtTask Params OK"); + // Task Parameters and Devices rtTaskParams *params = (rtTaskParams *)pvParameters; const rtTaskInterrupts rt_int = params->rt_int; // copy to avoid external override const rtTaskResets rt_rst = params->rt_resets; // copy to avoid external override QueueHandle_t rt_queue = params->rt_queue; - TaskHandle_t rt_handle_ptr = *params->rt_handle_ptr; Devices *dev = params->dev; ADS1256 *adc = dev->adc_a; PCA9555 *io = dev->io; + TaskStatus_t rt_task_info; + vTaskGetInfo(NULL, &rt_task_info, pdFALSE, eInvalid); + + const auto rt_task_name = pcTaskGetName(rt_task_info.xHandle); + LOG_INFO("rtTask Params OK [", rt_task_name, "]"); + ignitionBoxStatus ign_box_sts; // Variables for ISR, static to be fixed in memory locations - static isrParams isr_params_t12p{ + isrParams isr_params_t12p{ .flag = TRIG_FLAG_12P, .ign_stat = &ign_box_sts, - .rt_handle_ptr = rt_handle_ptr}; - static isrParams isr_params_t12n{ + .rt_handle_ptr = rt_task_info.xHandle}; + isrParams isr_params_t12n{ .flag = TRIG_FLAG_12N, .ign_stat = &ign_box_sts, - .rt_handle_ptr = rt_handle_ptr}; - static isrParams isr_params_t34p{ + .rt_handle_ptr = rt_task_info.xHandle}; + isrParams isr_params_t34p{ .flag = TRIG_FLAG_34P, .ign_stat = &ign_box_sts, - .rt_handle_ptr = rt_handle_ptr}; - static isrParams isr_params_t34n{ + .rt_handle_ptr = rt_task_info.xHandle}; + isrParams isr_params_t34n{ .flag = TRIG_FLAG_34N, .ign_stat = &ign_box_sts, - .rt_handle_ptr = rt_handle_ptr}; - static isrParams isr_params_sp12{ + .rt_handle_ptr = rt_task_info.xHandle}; + isrParams isr_params_sp12{ .flag = SPARK_FLAG_12, .ign_stat = &ign_box_sts, - .rt_handle_ptr = rt_handle_ptr}; - static isrParams isr_params_sp34{ + .rt_handle_ptr = rt_task_info.xHandle}; + isrParams isr_params_sp34{ .flag = SPARK_FLAG_34, .ign_stat = &ign_box_sts, - .rt_handle_ptr = rt_handle_ptr}; + .rt_handle_ptr = rt_task_info.xHandle}; - LOG_INFO("rtTask ISR Params OK"); + LOG_DEBUG("rtTask HDL Params OK, HDL* [", (uint32_t)rt_task_info.xHandle, "]"); + LOG_DEBUG("rtTask ISR Params OK, ISR* [", (uint32_t)rt_int.isr_ptr, "]"); + LOG_DEBUG("rtTask QUE Params OK, QUE* [", (uint32_t)rt_queue, "]"); // Create esp_timer for microsecond precision timeout esp_timer_handle_t timeout_timer; esp_timer_create_args_t timer_args = { .callback = spark_timeout_callback, - .arg = (void *)rt_handle_ptr, + .arg = (void *)rt_task_info.xHandle, .dispatch_method = ESP_TIMER_TASK, .name = "spark_timeout"}; esp_timer_create(&timer_args, &timeout_timer); + // Attach Pin Interrupts attachInterruptArg(digitalPinToInterrupt(rt_int.trig_pin_12p), rt_int.isr_ptr, (void *)&isr_params_t12p, RISING); attachInterruptArg(digitalPinToInterrupt(rt_int.trig_pin_12n), rt_int.isr_ptr, (void *)&isr_params_t12n, RISING); @@ -76,7 +84,7 @@ void rtIgnitionTask(void *pvParameters) attachInterruptArg(digitalPinToInterrupt(rt_int.spark_pin_12), rt_int.isr_ptr, (void *)&isr_params_sp12, RISING); attachInterruptArg(digitalPinToInterrupt(rt_int.spark_pin_34), rt_int.isr_ptr, (void *)&isr_params_sp34, RISING); - LOG_INFO("rtTask ISR Attach OK"); + LOG_INFO("rtTask ISR Attach OK [", rt_task_name, "]"); // Global rt_task_ptr variables bool first_cycle = true; diff --git a/RotaxMonitor/src/tasks.h b/RotaxMonitor/src/tasks.h index e5152ec..542f96d 100644 --- a/RotaxMonitor/src/tasks.h +++ b/RotaxMonitor/src/tasks.h @@ -55,7 +55,6 @@ struct rtTaskParams { bool rt_running; // run flag, false to terminate Devices *dev; - TaskHandle_t* rt_handle_ptr; const QueueHandle_t rt_queue; const rtTaskInterrupts rt_int; // interrupt pins to attach const rtTaskResets rt_resets; // reset ping for peak detectors diff --git a/RotaxMonitor/src/ui.h b/RotaxMonitor/src/ui.h index 8fdf35b..36b2a11 100644 --- a/RotaxMonitor/src/ui.h +++ b/RotaxMonitor/src/ui.h @@ -14,191 +14,3 @@ void printField(const char name[], const char *val); void printInfo(const ignitionBoxStatus &info); -static const std::string htmlTest = R"rawliteral( - - - - - ESP32 Dashboard - - - - -

RotaxMonitor realtime data

- - - - -
-

Timestamp: -

-

Data Valid: -

-

Generator voltage: -

-

Engine RPM: -

-

ADC read time: -

-

Queue errors: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyCoils 12Coils 34
Spark delay--
Spark status--
Soft start status--
Peak P in--
Peak N in--
Peak P out--
Peak N out--
Level spark--
Events--
Missed firings--
-
- - - - - -)rawliteral"; \ No newline at end of file diff --git a/RotaxMonitorTester/.vscode/extensions.json b/RotaxMonitorTester/.vscode/extensions.json index 411655e..b397401 100644 --- a/RotaxMonitorTester/.vscode/extensions.json +++ b/RotaxMonitorTester/.vscode/extensions.json @@ -1,8 +1,7 @@ { "recommendations": [ "Jason2866.esp-decoder", - "pioarduino.pioarduino-ide", - "platformio.platformio-ide" + "pioarduino.pioarduino-ide" ], "unwantedRecommendations": [ "ms-vscode.cpptools-extension-pack" diff --git a/RotaxMonitorTester/src/main.cpp b/RotaxMonitorTester/src/main.cpp index eadb954..e2fafd5 100644 --- a/RotaxMonitorTester/src/main.cpp +++ b/RotaxMonitorTester/src/main.cpp @@ -18,15 +18,16 @@ static uint32_t count = 0; #define SPARK_DLY_MAX 490 #define PAUSE_LONG_MIN 5000 -#define PAUSE_LONG_MAX PAUSE_LONG_MIN*100 +#define PAUSE_LONG_MAX PAUSE_LONG_MIN * 100 -#define RPM_MIN 800 +#define RPM_MIN 250 #define RPM_MAX 5500 -void clearScreen(){ - Serial.print("\033[2J"); // clear screen - Serial.print("\033[H"); // cursor home - Serial.flush(); +void clearScreen() +{ + Serial.print("\033[2J"); // clear screen + Serial.print("\033[H"); // cursor home + Serial.flush(); } static double filtered_rpm = 0; @@ -48,45 +49,44 @@ static const std::map pin2Name = { {State::S_WAIT_10MS, "S_WAIT_10MS"}}; static timerStatus stsA = { - .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 = { + .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_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}; + .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 = { + .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}; + .pin_spark_34 = SPARK_B34}, + .main_task = NULL}; -static bool isEnabled = false; +static bool isEnabled_A = false; +static bool isEnabled_B = false; void setup() { - Serial.begin(921600); + Serial.begin(115200); delay(1000); LOG_ATTACH_SERIAL(Serial); @@ -107,7 +107,8 @@ void setup() pinMode(SPARK_DELAY_POT, ANALOG); pinMode(FREQ_POT, ANALOG); - pinMode(ENABLE_PIN, INPUT_PULLUP); + pinMode(ENABLE_PIN_A, INPUT_PULLUP); + pinMode(ENABLE_PIN_B, INPUT_PULLUP); // get the task handle for the main loop stsA.main_task = xTaskGetCurrentTaskHandleForCore(1); @@ -135,40 +136,58 @@ void loop() LOG_INFO("Loop: ", count++); uint32_t spark_delay = (uint32_t)(map(analogRead(SPARK_DELAY_POT), 0, 4096, SPARK_DLY_MIN, SPARK_DLY_MAX) / PERIOD_US); stsA.spark_delay_us = spark_delay * PERIOD_US; - if (stsA.spark_delay_us > (SPARK_DLY_MIN + SPARK_DLY_MAX) / 2) { + if (stsA.spark_delay_us > (SPARK_DLY_MIN + SPARK_DLY_MAX) / 2) + { stsA.soft_start = true; stsA.spark_delay_us -= (SPARK_DLY_MIN + SPARK_DLY_MAX) / 2; - } else { + } + else + { stsA.soft_start = false; } - stsB.soft_start = stsA.soft_start; - stsB.spark_delay_us = stsA.spark_delay_us; + 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)); filtered_rpm = filtered_rpm + 0.1 * (new_rpm - filtered_rpm); stsA.pause_long_us = (uint32_t)(60000000.0f / filtered_rpm / 2.0f); stsB.pause_long_us = stsA.pause_long_us; - if (isEnabled) { - LOG_INFO("==== System is ENABLED ===="); - } else { - LOG_INFO("==== System is DISABLED ===="); - } + if (isEnabled_A) + LOG_INFO("==== System A is ENABLED ===="); + else + LOG_INFO("==== System A is DISABLED ===="); + + if (isEnabled_B) + LOG_INFO("==== System B is ENABLED ===="); + else + LOG_INFO("==== System B is DISABLED ===="); LOG_INFO("Spark Delay uS: ", stsA.spark_delay_us, "\tSoft Start: ", stsA.soft_start ? "TRUE" : "FALSE"); LOG_INFO("Engine Rpm: ", (uint32_t)(filtered_rpm)); LOG_INFO("Coil Pulse: ", stsA.coil_pulse_us, "us"); LOG_INFO("Spark Pulse: ", stsA.spark_pulse_us, "us"); - - if (digitalRead(ENABLE_PIN) == LOW && !isEnabled) { + + if (digitalRead(ENABLE_PIN_A) == LOW && !isEnabled_A) + { timerStart(timerA); - delayMicroseconds(50); + isEnabled_A = true; + } + else if (digitalRead(ENABLE_PIN_A) == HIGH && isEnabled_A) + { + timerStop(timerA); + isEnabled_A = false; + } + + if (digitalRead(ENABLE_PIN_B) == LOW && !isEnabled_B) + { timerStart(timerB); - isEnabled = true; - } else if (digitalRead(ENABLE_PIN) == HIGH && isEnabled) { - timerStop(timerA); - timerStop(timerA); - isEnabled = false; + isEnabled_B = true; + } + else if (digitalRead(ENABLE_PIN_B) == HIGH && isEnabled_B) + { + timerStop(timerB); + isEnabled_B = false; } delay(100); diff --git a/RotaxMonitorTester/src/pins.h b/RotaxMonitorTester/src/pins.h index 6d2e8da..04427a1 100644 --- a/RotaxMonitorTester/src/pins.h +++ b/RotaxMonitorTester/src/pins.h @@ -1,7 +1,8 @@ #pragma once // Enable Pin -#define ENABLE_PIN 16 +#define ENABLE_PIN_A 16 +#define ENABLE_PIN_B 15 ///// Ignition Box A ///// #define PIN_TRIG_A12P 18