diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c2004c..d20347b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ TODO: - rename RampConstAcceleration to e.g. RampControl - for esp-idf 5 make use of espressif resource management of rmt channels +0.31.3: +- esp32: add `engine->task_rate(uint8_t delay_ms)` function to adjust the stepper task rate to e.g. 1ms (see #288 for reference) + 0.31.2: - Move constants out of PoorManFloat.h and autogenerate these - Fix pmfl constant used by SAM Due aka 21MHz diff --git a/library.properties b/library.properties index 59e6b00..1395fb1 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=FastAccelStepper -version=0.31.2 +version=0.31.3 license=MIT author=Jochen Kiemes maintainer=Jochen Kiemes diff --git a/src/FastAccelStepper.h b/src/FastAccelStepper.h index a6e70c3..e50f19b 100644 --- a/src/FastAccelStepper.h +++ b/src/FastAccelStepper.h @@ -94,6 +94,34 @@ class FastAccelStepperEngine { uint8_t driver_type = DRIVER_DONT_CARE); #endif +#if defined(SUPPORT_TASK_RATE_CHANGE) + // For e.g. esp32 the repetition rate of the stepper task can be changed. + // The default delay is 4ms. + // + // The steppertask is looping with: + // manageSteppers() + // wdt_reset() + // delay() + // + // The actual repetition rate of the stepper task is delay + execution time of manageSteppers() + // + // This function is primary of interest in conjunction with setForwardPlanningTimeInMs(). + // If the delay is larger then forward planning time, then the stepper queue will always + // run out of commands, which lead to a sudden stop of the motor. If the delay is 0, + // then the stepper task will constantly looping, which may lead to the task blocking other + // tasks. Consequently, this function is intended for advanced users. + // + // There is not planned to test this functionality, because automatic testing is only + // available for avr devices and those continue to use fixed 4ms rate. + // + // Please be aware, that the configured tick rate aka portTICK_PERIOD_MS is relevant. + // Apparently, arduino-esp32 has FreeRTOS configured to have a tick-rate of 1000Hz + inline void task_rate(uint8_t delay_ms) { + _delay_ms = delay_ms; + }; + uint8_t _delay_ms; +#endif + // Comments to valid pins: // // clang-format off diff --git a/src/StepperISR_esp32.cpp b/src/StepperISR_esp32.cpp index 55cded8..1ad68a9 100644 --- a/src/StepperISR_esp32.cpp +++ b/src/StepperISR_esp32.cpp @@ -106,8 +106,6 @@ int8_t StepperQueue::queueNumForStepPin(uint8_t step_pin) { return -1; } //************************************************************************************************* void StepperTask(void *parameter) { FastAccelStepperEngine *engine = (FastAccelStepperEngine *)parameter; - const TickType_t delay_4ms = - (DELAY_MS_BASE + portTICK_PERIOD_MS - 1) / portTICK_PERIOD_MS; while (true) { engine->manageSteppers(); #if ESP_IDF_VERSION_MAJOR == 4 @@ -115,7 +113,8 @@ void StepperTask(void *parameter) { // causes an issue. esp_task_wdt_reset(); #endif - vTaskDelay(delay_4ms); + const TickType_t delay_time = (engine->_delay_ms + portTICK_PERIOD_MS - 1) / portTICK_PERIOD_MS; + vTaskDelay(delay_time); } } @@ -131,6 +130,7 @@ void fas_init_engine(FastAccelStepperEngine *engine, uint8_t cpu_core) { #define STACK_SIZE 3000 #define PRIORITY (configMAX_PRIORITIES - 1) #endif + engine->_delay_ms = DELAY_MS_BASE; if (cpu_core > 1) { xTaskCreate(StepperTask, "StepperTask", STACK_SIZE, engine, PRIORITY, NULL); } else { diff --git a/src/fas_arch/common_esp32.h b/src/fas_arch/common_esp32.h index 5f5c171..806ab69 100644 --- a/src/fas_arch/common_esp32.h +++ b/src/fas_arch/common_esp32.h @@ -45,6 +45,9 @@ // have more than one core #define SUPPORT_CPU_AFFINITY +// have adjustable stepper task rate +#define SUPPORT_TASK_RATE_CHANGE + #define LL_TOGGLE_PIN(dirPin) \ gpio_ll_set_level(&GPIO, (gpio_num_t)dirPin, \ gpio_ll_get_level(&GPIO, (gpio_num_t)dirPin) ^ 1)