Emergency stop of RMT

Disraeli
Posts: 9
Joined: Tue Oct 28, 2025 9:02 pm

Emergency stop of RMT

Postby Disraeli » Wed Apr 15, 2026 9:33 am

Hello! I'm using ESP-IDF v5.5.1 and an ESP32 board to control a stepper motor using the RMT module, following the example from:
https://github.com/espressif/esp-idf/bl ... ple_main.c
How to properly and urgently stop RMT during command execution in ESP-IDF v5.5.1?
For example, an acceleration command is sent to RMT and the execution of this command is awaited:

Code: Select all

            
ESP_ERROR_CHECK(rmt_transmit(motor_chan, accel_motor_encoder, &steps, sizeof(uint32_t), &tx_config));
ESP_ERROR_CHECK(rmt_tx_wait_all_done(motor_chan, portMAX_DELAY));
But during the acceleration, the rotation limit is reached (e.g., a stepper motor rotary platform enters the optocoupler zone), and a pin interrupt fires, indicating that the movement must be stopped immediately.
The approach of disabling and re-enabling RMT

Code: Select all

rmt_disable(motor_chan);
vTaskDelay(pdMS_TO_TICKS(50));
rmt_enable(motor_chan);
does not work — everything freezes while waiting for the operation to complete. Register access as shown here: https://github.com/espressif/esp-idf/issues/1456 is disabled in ESP-IDF v5.5.1.
My initialization RMT:

Code: Select all

#define STEP_MOTOR_RESOLUTION_HZ 1000000
#define SAMPLE_POINTS_ACDEC  300
#define LOW_FREQ_HZ       50
#define MAIN_FREQ_HZ      1000
#define SYMBOL_DURATION     ((uint32_t)(STEP_MOTOR_RESOLUTION_HZ / MAIN_FREQ_HZ / 2))
#define BLOCK_SIZE            4000

rmt_channel_handle_t motor_chan = NULL;
rmt_encoder_handle_t accel_motor_encoder = NULL;
rmt_encoder_handle_t decel_motor_encoder = NULL;
rmt_encoder_handle_t uniform_motor_encoder = NULL;
rmt_encoder_handle_t copy_encoder = NULL;

rmt_copy_encoder_config_t copy_encoder_config_t = {};
static stepper_motor_curve_encoder_config_t decel_encoder_config = {
    .resolution = STEP_MOTOR_RESOLUTION_HZ,
    .sample_points = SAMPLE_POINTS_ACDEC,
    .start_freq_hz = MAIN_FREQ_HZ,
    .end_freq_hz = LOW_FREQ_HZ,
};
static stepper_motor_uniform_encoder_config_t uniform_encoder_config = {
    .resolution = STEP_MOTOR_RESOLUTION_HZ,
};
static stepper_motor_curve_encoder_config_t accel_encoder_config = {
    .resolution = STEP_MOTOR_RESOLUTION_HZ,
    .sample_points = SAMPLE_POINTS_ACDEC,
    .start_freq_hz = LOW_FREQ_HZ,
    .end_freq_hz = MAIN_FREQ_HZ,
};

ESP_LOGI(TAG_RMT, "Create RMT TX channel");
    rmt_tx_channel_config_t tx_chan_config = {
        .clk_src = RMT_CLK_SRC_DEFAULT,
        .gpio_num = STEP_MOTOR,
        .mem_block_symbols = 64,
        .resolution_hz = STEP_MOTOR_RESOLUTION_HZ,
        .trans_queue_depth = 10,
    };
    ESP_ERROR_CHECK(rmt_new_tx_channel(&tx_chan_config, &motor_chan));
    
    ESP_LOGI(TAG_RMT, "Create motor encoders");
    ESP_ERROR_CHECK(rmt_new_copy_encoder(&copy_encoder_config_t, &copy_encoder));
    ESP_ERROR_CHECK(rmt_new_stepper_motor_curve_encoder(&accel_encoder_config, &accel_motor_encoder));
    ESP_ERROR_CHECK(rmt_new_stepper_motor_uniform_encoder(&uniform_encoder_config, &uniform_motor_encoder));
    ESP_ERROR_CHECK(rmt_new_stepper_motor_curve_encoder(&decel_encoder_config, &decel_motor_encoder));

    ESP_LOGI(TAG_RMT, "Enable RMT channel");
    ESP_ERROR_CHECK(rmt_enable(motor_chan));

MicroController
Posts: 2669
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Emergency stop of RMT

Postby MicroController » Wed Apr 15, 2026 10:30 am

Irrespective of what the RMT is doing, you can quickly and at any time 'cut' its output by 'disconnecting' its signal from the respective IO pin, i.e. reconfiguring the pin to 'normal' GPIO output.

rmt_disable() is the clean way to stop the RMT, but apparently the ESP32 doesn't support "async stop" (SOC_RMT_SUPPORT_ASYNC_STOP), so you may want to immediately cut the output signal and then either rmt_disable() or just wait until the RMT finishes the current transmission.

Who is online

Users browsing this forum: Baidu [Spider], GPTBot, PerplexityBot and 1 guest