rotary_encoder_example_main.c 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: CC0-1.0
  5. */
  6. #include "freertos/FreeRTOS.h"
  7. #include "freertos/task.h"
  8. #include "freertos/queue.h"
  9. #include "esp_log.h"
  10. #include "driver/pulse_cnt.h"
  11. static const char *TAG = "example";
  12. #define EXAMPLE_PCNT_HIGH_LIMIT 100
  13. #define EXAMPLE_PCNT_LOW_LIMIT -100
  14. #define EXAMPLE_EC11_GPIO_A 0
  15. #define EXAMPLE_EC11_GPIO_B 2
  16. static bool example_pcnt_on_reach(pcnt_unit_handle_t unit, const pcnt_watch_event_data_t *edata, void *user_ctx)
  17. {
  18. BaseType_t high_task_wakeup;
  19. QueueHandle_t queue = (QueueHandle_t)user_ctx;
  20. // send event data to queue, from this interrupt callback
  21. xQueueSendFromISR(queue, &(edata->watch_point_value), &high_task_wakeup);
  22. return (high_task_wakeup == pdTRUE);
  23. }
  24. void app_main(void)
  25. {
  26. ESP_LOGI(TAG, "install pcnt unit");
  27. pcnt_unit_config_t unit_config = {
  28. .high_limit = EXAMPLE_PCNT_HIGH_LIMIT,
  29. .low_limit = EXAMPLE_PCNT_LOW_LIMIT,
  30. };
  31. pcnt_unit_handle_t pcnt_unit = NULL;
  32. ESP_ERROR_CHECK(pcnt_new_unit(&unit_config, &pcnt_unit));
  33. ESP_LOGI(TAG, "set glitch filter");
  34. pcnt_glitch_filter_config_t filter_config = {
  35. .max_glitch_ns = 1000,
  36. };
  37. ESP_ERROR_CHECK(pcnt_unit_set_glitch_filter(pcnt_unit, &filter_config));
  38. ESP_LOGI(TAG, "install pcnt channels");
  39. pcnt_chan_config_t chan_a_config = {
  40. .edge_gpio_num = EXAMPLE_EC11_GPIO_A,
  41. .level_gpio_num = EXAMPLE_EC11_GPIO_B,
  42. };
  43. pcnt_channel_handle_t pcnt_chan_a = NULL;
  44. ESP_ERROR_CHECK(pcnt_new_channel(pcnt_unit, &chan_a_config, &pcnt_chan_a));
  45. pcnt_chan_config_t chan_b_config = {
  46. .edge_gpio_num = EXAMPLE_EC11_GPIO_B,
  47. .level_gpio_num = EXAMPLE_EC11_GPIO_A,
  48. };
  49. pcnt_channel_handle_t pcnt_chan_b = NULL;
  50. ESP_ERROR_CHECK(pcnt_new_channel(pcnt_unit, &chan_b_config, &pcnt_chan_b));
  51. ESP_LOGI(TAG, "set edge and level actions for pcnt channels");
  52. ESP_ERROR_CHECK(pcnt_channel_set_edge_action(pcnt_chan_a, PCNT_CHANNEL_EDGE_ACTION_DECREASE, PCNT_CHANNEL_EDGE_ACTION_INCREASE));
  53. ESP_ERROR_CHECK(pcnt_channel_set_level_action(pcnt_chan_a, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_INVERSE));
  54. ESP_ERROR_CHECK(pcnt_channel_set_edge_action(pcnt_chan_b, PCNT_CHANNEL_EDGE_ACTION_INCREASE, PCNT_CHANNEL_EDGE_ACTION_DECREASE));
  55. ESP_ERROR_CHECK(pcnt_channel_set_level_action(pcnt_chan_b, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_INVERSE));
  56. ESP_LOGI(TAG, "add watch points and register callbacks");
  57. int watch_points[] = {EXAMPLE_PCNT_LOW_LIMIT, -50, 0, 50, EXAMPLE_PCNT_HIGH_LIMIT};
  58. for (size_t i = 0; i < sizeof(watch_points) / sizeof(watch_points[0]); i++) {
  59. ESP_ERROR_CHECK(pcnt_unit_add_watch_point(pcnt_unit, watch_points[i]));
  60. }
  61. pcnt_event_callbacks_t cbs = {
  62. .on_reach = example_pcnt_on_reach,
  63. };
  64. QueueHandle_t queue = xQueueCreate(10, sizeof(int));
  65. ESP_ERROR_CHECK(pcnt_unit_register_event_callbacks(pcnt_unit, &cbs, queue));
  66. ESP_LOGI(TAG, "enable pcnt unit");
  67. ESP_ERROR_CHECK(pcnt_unit_enable(pcnt_unit));
  68. ESP_LOGI(TAG, "clear pcnt unit");
  69. ESP_ERROR_CHECK(pcnt_unit_clear_count(pcnt_unit));
  70. ESP_LOGI(TAG, "start pcnt unit");
  71. ESP_ERROR_CHECK(pcnt_unit_start(pcnt_unit));
  72. // Report counter value
  73. int pulse_count = 0;
  74. int event_count = 0;
  75. while (1) {
  76. if (xQueueReceive(queue, &event_count, pdMS_TO_TICKS(1000))) {
  77. ESP_LOGI(TAG, "Watch point event, count: %d", event_count);
  78. } else {
  79. ESP_ERROR_CHECK(pcnt_unit_get_count(pcnt_unit, &pulse_count));
  80. ESP_LOGI(TAG, "Pulse count: %d", pulse_count);
  81. }
  82. }
  83. }