Add: main rotary encoder c file with basic counting

main
rkcf 2023-02-07 17:05:15 -06:00
parent 35ffd04b84
commit 58702666f2
1 changed files with 101 additions and 0 deletions

View File

@ -0,0 +1,101 @@
#include <stdio.h>
#include "esp_err.h"
#include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h"
#include "freertos/projdefs.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "driver/pulse_cnt.h"
#include "hal/pcnt_types.h"
/* Pinouts */
#define PCNT_A_PIN 1 /* Rotary Encoder A Pin */
#define PCNT_B_PIN 2 /* Rotary Encoder B Pin */
/* Pulse Count Settings */
#define PCNT_HIGH_LIMIT 100
#define PCNT_LOW_LIMIT -100
static QueueHandle_t pcnt_queue = NULL;
static const char *TAG = "RE Demo"; /* logging tag */
/* Pulse Counter Callback */
static bool pcnt_cb(pcnt_unit_handle_t unit, const pcnt_watch_event_data_t *edata, void *user_ctx) {
BaseType_t high_task_wakeup;
/* Put the watchpoint value in a queue to be handled later */
xQueueSendFromISR(pcnt_queue, &(edata->watch_point_value), &high_task_wakeup);
return (high_task_wakeup == pdTRUE);
}
/* Main Loop */
void app_main(void){
/* Configure the PCNT unit and get a handle */
ESP_LOGI(TAG, "Setting up Pulse Counter Unit");
pcnt_unit_config_t pcnt_unit_config = {
.high_limit = PCNT_HIGH_LIMIT,
.low_limit = PCNT_LOW_LIMIT
};
pcnt_unit_handle_t pcnt_unit = NULL;
ESP_ERROR_CHECK(pcnt_new_unit(&pcnt_unit_config, &pcnt_unit));
/* Configure PCNT A & B channels and get handles */
ESP_LOGI(TAG, "Setting up Pulse Counter Channels");
pcnt_chan_config_t pcnt_chan_a_config = {
.edge_gpio_num = PCNT_A_PIN,
.level_gpio_num = PCNT_B_PIN
};
pcnt_channel_handle_t pcnt_chan_a = NULL;
ESP_ERROR_CHECK(pcnt_new_channel(pcnt_unit, &pcnt_chan_a_config, &pcnt_chan_a));
pcnt_chan_config_t pcnt_chan_b_config = {
.edge_gpio_num = PCNT_B_PIN,
.level_gpio_num = PCNT_A_PIN
};
pcnt_channel_handle_t pcnt_chan_b = NULL;
ESP_ERROR_CHECK(pcnt_new_channel(pcnt_unit, &pcnt_chan_b_config, &pcnt_chan_b));
/* Configure edge/level actions on channels */
ESP_ERROR_CHECK(pcnt_channel_set_edge_action(pcnt_chan_a, PCNT_CHANNEL_EDGE_ACTION_DECREASE, PCNT_CHANNEL_EDGE_ACTION_INCREASE));
ESP_ERROR_CHECK(pcnt_channel_set_level_action(pcnt_chan_a, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_INVERSE));
ESP_ERROR_CHECK(pcnt_channel_set_edge_action(pcnt_chan_b, PCNT_CHANNEL_EDGE_ACTION_INCREASE, PCNT_CHANNEL_EDGE_ACTION_DECREASE));
ESP_ERROR_CHECK(pcnt_channel_set_level_action(pcnt_chan_b, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_INVERSE));
/* Install watch points */
ESP_LOGI(TAG, "Installing watch points and callback handler");
int watch_points[] = {PCNT_LOW_LIMIT, -50, 0, 50, PCNT_HIGH_LIMIT};
for (size_t i = 0; i < sizeof(watch_points) / sizeof(watch_points[0]); i++) {
ESP_ERROR_CHECK(pcnt_unit_add_watch_point(pcnt_unit, watch_points[i]));
}
/* Initialize pcnt event queue */
pcnt_queue = xQueueCreate(10, sizeof(int));
/* Install callback */
pcnt_event_callbacks_t cbs = {
.on_reach = pcnt_cb
};
ESP_ERROR_CHECK(pcnt_unit_register_event_callbacks(pcnt_unit, &cbs, NULL));
/* Enable, clear, and start pcnt Unit */
ESP_LOGI(TAG, "Starting Pulse Counter");
ESP_ERROR_CHECK(pcnt_unit_enable(pcnt_unit));
ESP_ERROR_CHECK(pcnt_unit_clear_count(pcnt_unit));
ESP_ERROR_CHECK(pcnt_unit_start(pcnt_unit));
/* Log counter value */
int pulse_count = 0;
int event_count = 0;
while (1) {
if (xQueueReceive(pcnt_queue, &event_count, pdMS_TO_TICKS(1000))) {
ESP_LOGI(TAG, "Watch point event, count: %d", event_count);
} else {
ESP_ERROR_CHECK(pcnt_unit_get_count(pcnt_unit, &pulse_count));
ESP_LOGI(TAG, "Pulse count: %d", pulse_count);
}
}
}