PCNT rotary encoder example producing extra pulses
Posted: Mon Nov 06, 2023 4:22 am
I've been trying to adapt the PCNT rotary encoder example https://github.com/espressif/esp-idf/b ... /README.md, but I seem to be getting the incorrect number of pulse when calling get_counter_value. I've tried this with a few different encoders, and I get the same behavior every time. On turn of the encoder, which produces one pulse on my oscilloscope, produces from 2-4 counts from the encoder implementation. I've included my code implementation of a simple loop to poll and check for encoder position changes. The code correctly recognizes the direction of rotation, but produces too many pulses. I've also included some sample output. Is there something obvious I'm missing here?
Code: Select all
[0;32mI (308) Rotary Encoder Pulse Tester: Initializing rotary encoder on pins 17 and 16.
[0;32mI (318) Rotary Encoder Pulse Tester: Initializing rotary encoder events.
[0;32mI (7138) Rotary Encoder Pulse Tester: Encoder position: 1
[0;32mI (7168) Rotary Encoder Pulse Tester: Encoder position: 2
[0;32mI (7178) Rotary Encoder Pulse Tester: Encoder position: 3
[0;32mI (7188) Rotary Encoder Pulse Tester: Encoder position: 4
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "rotary_encoder.h"
#define ROT_ENC_A_GPIO (17)
#define ROT_ENC_B_GPIO (16)
static const char *TAG = "Rotary Encoder Pulse Tester";
rotary_encoder_t *encoder = NULL;
int previous_encoder_position = 0;
void watch_rotary_encoder_events() {
int encoder_position;
TickType_t xLastWakeTime;
const TickType_t xFrequency = (10 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "Initializing rotary encoder events.");
xLastWakeTime = xTaskGetTickCount();
for( ;; )
{
vTaskDelayUntil( &xLastWakeTime, xFrequency );
encoder_position = encoder->get_counter_value(encoder);
if (encoder_position != previous_encoder_position) {
ESP_LOGI(TAG, "Previous encoder position: %d", previous_encoder_position);
previous_encoder_position = encoder_position;
}
}
}
void app_main() {
ESP_LOGI(TAG, "Initializing rotary encoder on pins %d and %d.", ROT_ENC_A_GPIO, ROT_ENC_B_GPIO);
rotary_encoder_config_t config = ROTARY_ENCODER_DEFAULT_CONFIG(
(rotary_encoder_dev_t)
0,
ROT_ENC_A_GPIO,
ROT_ENC_B_GPIO
);
ESP_ERROR_CHECK(rotary_encoder_new_ec11(&config, &encoder));
// Filter out glitch (1us)
ESP_ERROR_CHECK(encoder->set_glitch_filter(encoder, 1));
// Start encoder
ESP_ERROR_CHECK(encoder->start(encoder));
xTaskCreate(watch_rotary_encoder_events, "Watch Rotary Encoder Events", 2048, NULL, 3, NULL);
}