Skip to content

Commit 63b957b

Browse files
committed
update encoder library
1 parent 504abb4 commit 63b957b

File tree

9 files changed

+279
-71
lines changed

9 files changed

+279
-71
lines changed

Arduino/libraries/ESP32Encoder-master/examples/Encoder/Encoder.ino

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
#include <ESP32Encoder.h>
32

43
ESP32Encoder encoder;
@@ -17,24 +16,24 @@ void setup(){
1716
// Enable the weak pull up resistors
1817
ESP32Encoder::useInternalWeakPullResistors=UP;
1918

20-
// Attache pins for use as encoder pins
19+
// use pin 19 and 18 for the first encoder
2120
encoder.attachHalfQuad(19, 18);
22-
// Attache pins for use as encoder pins
21+
// use pin 17 and 16 for the second encoder
2322
encoder2.attachHalfQuad(17, 16);
2423

2524
// set starting count value after attaching
2625
encoder.setCount(37);
2726

2827
// clear the encoder's raw count and set the tracked count to zero
2928
encoder2.clearCount();
30-
Serial.println("Encoder Start = "+String((int32_t)encoder.getCount()));
29+
Serial.println("Encoder Start = " + String((int32_t)encoder.getCount()));
3130
// set the lastToggle
3231
encoder2lastToggled = millis();
3332
}
3433

3534
void loop(){
3635
// Loop and read the count
37-
Serial.println("Encoder count = "+String((int32_t)encoder.getCount())+" "+String((int32_t)encoder2.getCount()));
36+
Serial.println("Encoder count = " + String((int32_t)encoder.getCount()) + " " + String((int32_t)encoder2.getCount()));
3837
delay(100);
3938

4039
// every 5 seconds toggle encoder 2
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#include <Arduino.h>
2+
#include <ESP32Encoder.h>
3+
#include <Adafruit_GFX.h>
4+
#include <Adafruit_SSD1306.h>
5+
#include "esp_task_wdt.h"
6+
7+
static IRAM_ATTR void enc_cb(void* arg) {
8+
ESP32Encoder* enc = (ESP32Encoder*) arg;
9+
//Serial.printf("enc cb: count: %d\n", enc->getCount());
10+
static bool leds = false;
11+
digitalWrite(LED_BUILTIN, (int)leds);
12+
leds = !leds;
13+
}
14+
15+
extern bool loopTaskWDTEnabled;
16+
extern TaskHandle_t loopTaskHandle;
17+
18+
ESP32Encoder encoder(true, enc_cb);
19+
Adafruit_SSD1306 display(128, 32, &Wire);
20+
21+
static const char* LOG_TAG = "main";
22+
23+
void setup(){
24+
loopTaskWDTEnabled = true;
25+
pinMode(LED_BUILTIN, OUTPUT);
26+
Serial.begin(115200);
27+
// Encoder A and B pins connected with 1K series resistor to pins 4 and 5, common pin to ground.
28+
// |- A --- 1K --- pin 4
29+
// >=[enc]|- GND
30+
// |- B --- 1K --- pin 5
31+
32+
ESP32Encoder::useInternalWeakPullResistors=UP;
33+
encoder.attachSingleEdge(4, 5);
34+
encoder.clearCount();
35+
encoder.setFilter(1023);
36+
37+
if (! display.begin(SSD1306_SWITCHCAPVCC, 0x3c))
38+
{
39+
for (;;) {
40+
Serial.println("display init failed");
41+
}
42+
}
43+
display.cp437(true);
44+
display.clearDisplay();
45+
display.setTextSize(2);
46+
display.setTextColor(WHITE);
47+
display.setCursor(0,0);
48+
display.display();
49+
esp_log_level_set("*", ESP_LOG_DEBUG);
50+
esp_log_level_set("main", ESP_LOG_DEBUG);
51+
esp_log_level_set("ESP32Encoder", ESP_LOG_DEBUG);
52+
esp_task_wdt_add(loopTaskHandle);
53+
}
54+
55+
void loop(){
56+
57+
display.clearDisplay();
58+
display.setCursor(0,0);
59+
display.printf("E: %lld\n", encoder.getCount());
60+
display.display();
61+
Serial.printf("Enc count: %d\n", encoder.getCount());
62+
delay(500);
63+
64+
}

Arduino/libraries/ESP32Encoder-master/src/ESP32Encoder.cpp

Lines changed: 99 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -6,64 +6,105 @@
66
*/
77

88
#include <ESP32Encoder.h>
9+
#include <soc/pcnt_struct.h>
10+
#include "esp_log.h"
11+
12+
static const char* TAG = "ESP32Encoder";
13+
914

1015
//static ESP32Encoder *gpio2enc[48];
1116
//
1217
//
1318
enum puType ESP32Encoder::useInternalWeakPullResistors=DOWN;
14-
ESP32Encoder *ESP32Encoder::encoders[MAX_ESP32_ENCODERS] = { NULL, NULL, NULL,
15-
NULL,
16-
NULL, NULL, NULL, NULL };
19+
ESP32Encoder *ESP32Encoder::encoders[MAX_ESP32_ENCODERS] = { NULL, };
1720

1821
bool ESP32Encoder::attachedInterrupt=false;
1922
pcnt_isr_handle_t ESP32Encoder::user_isr_handle = NULL;
2023

21-
ESP32Encoder::ESP32Encoder() {
22-
attached = false;
23-
aPinNumber = (gpio_num_t) 0;
24-
bPinNumber = (gpio_num_t) 0;
25-
working = false;
26-
direction = false;
27-
unit = (pcnt_unit_t) -1;
24+
ESP32Encoder::ESP32Encoder(bool always_interrupt_, enc_isr_cb_t enc_isr_cb, void* enc_isr_cb_data):
25+
always_interrupt{always_interrupt_},
26+
aPinNumber{(gpio_num_t) 0},
27+
bPinNumber{(gpio_num_t) 0},
28+
unit{(pcnt_unit_t) -1},
29+
fullQuad{false},
30+
countsMode{2},
31+
count{0},
32+
r_enc_config{},
33+
_enc_isr_cb(enc_isr_cb),
34+
_enc_isr_cb_data(enc_isr_cb_data),
35+
attached{false},
36+
direction{false},
37+
working{false}
38+
{
2839
}
2940

30-
ESP32Encoder::~ESP32Encoder() {
31-
// TODO Auto-generated destructor stub
32-
}
41+
ESP32Encoder::~ESP32Encoder() {}
3342

3443
/* Decode what PCNT's unit originated an interrupt
3544
* and pass this information together with the event type
3645
* the main program using a queue.
3746
*/
38-
static void IRAM_ATTR pcnt_example_intr_handler(void *arg) {
39-
ESP32Encoder * ptr;
40-
47+
#ifdef CONFIG_IDF_TARGET_ESP32S2
48+
#define COUNTER_H_LIM cnt_thr_h_lim_lat_un
49+
#define COUNTER_L_LIM cnt_thr_l_lim_lat_un
50+
#define thres0_lat cnt_thr_thres0_lat_un
51+
#define thres1_lat cnt_thr_thres1_lat_un
52+
53+
#elif CONFIG_IDF_TARGET_ESP32S3
54+
#define COUNTER_H_LIM cnt_thr_h_lim_lat_un
55+
#define COUNTER_L_LIM cnt_thr_l_lim_lat_un
56+
#define thres0_lat cnt_thr_thres0_lat_un
57+
#define thres1_lat cnt_thr_thres1_lat_un
58+
#else
59+
#define COUNTER_H_LIM h_lim_lat
60+
#define COUNTER_L_LIM l_lim_lat
61+
#endif
62+
63+
64+
65+
static void IRAM_ATTR esp32encoder_pcnt_intr_handler(void *arg) {
66+
ESP32Encoder * esp32enc = {};
4167
uint32_t intr_status = PCNT.int_st.val;
42-
int i;
43-
44-
for (i = 0; i < PCNT_UNIT_MAX; i++) {
68+
for (uint8_t i = 0; i < PCNT_UNIT_MAX; i++) {
4569
if (intr_status & (BIT(i))) {
46-
ptr = ESP32Encoder::encoders[i];
47-
/* Save the PCNT event type that caused an interrupt
48-
to pass it to the main program */
49-
50-
int64_t status=0;
51-
if(PCNT.status_unit[i].h_lim_lat){
52-
status=ptr->r_enc_config.counter_h_lim;
53-
}
54-
if(PCNT.status_unit[i].l_lim_lat){
55-
status=ptr->r_enc_config.counter_l_lim;
70+
pcnt_unit_t unit = static_cast<pcnt_unit_t>(i);
71+
esp32enc = ESP32Encoder::encoders[i];
72+
if(PCNT.status_unit[i].COUNTER_H_LIM){
73+
esp32enc->count += esp32enc->r_enc_config.counter_h_lim;
74+
pcnt_counter_clear(unit);
75+
} else if(PCNT.status_unit[i].COUNTER_L_LIM){
76+
esp32enc->count += esp32enc->r_enc_config.counter_l_lim;
77+
pcnt_counter_clear(unit);
78+
} else if(esp32enc->always_interrupt && (PCNT.status_unit[i].thres0_lat || PCNT.status_unit[i].thres1_lat)) {
79+
int16_t c;
80+
pcnt_get_counter_value(unit, &c);
81+
esp32enc->count += c;
82+
pcnt_set_event_value(unit, PCNT_EVT_THRES_0, -1);
83+
pcnt_set_event_value(unit, PCNT_EVT_THRES_1, 1);
84+
pcnt_event_enable(unit, PCNT_EVT_THRES_0);
85+
pcnt_event_enable(unit, PCNT_EVT_THRES_1);
86+
pcnt_counter_clear(unit);
87+
if (esp32enc->_enc_isr_cb) {
88+
esp32enc->_enc_isr_cb(esp32enc->_enc_isr_cb_data);
89+
}
5690
}
57-
//pcnt_counter_clear(ptr->unit);
5891
PCNT.int_clr.val = BIT(i); // clear the interrupt
59-
ptr->count = status + ptr->count;
6092
}
6193
}
6294
}
6395

96+
97+
98+
99+
100+
void ESP32Encoder::detatch(){
101+
pcnt_counter_pause(unit);
102+
ESP32Encoder::encoders[unit]=NULL;
103+
104+
}
64105
void ESP32Encoder::attach(int a, int b, enum encType et) {
65106
if (attached) {
66-
Serial.println("All ready attached, FAIL!");
107+
ESP_LOGE(TAG, "attach: already attached");
67108
return;
68109
}
69110
int index = 0;
@@ -74,7 +115,7 @@ void ESP32Encoder::attach(int a, int b, enum encType et) {
74115
}
75116
}
76117
if (index == MAX_ESP32_ENCODERS) {
77-
Serial.println("Too many encoders, FAIL!");
118+
ESP_LOGE(TAG, "Too many encoders, FAIL!");
78119
return;
79120
}
80121

@@ -149,30 +190,32 @@ void ESP32Encoder::attach(int a, int b, enum encType et) {
149190
r_enc_config .counter_h_lim = _INT16_MAX;
150191
r_enc_config .counter_l_lim = _INT16_MIN ;
151192

152-
pcnt_unit_config(&r_enc_config);
193+
pcnt_unit_config(&r_enc_config);
153194
}
154195

155-
156196
// Filter out bounces and noise
157-
pcnt_set_filter_value(unit, 250); // Filter Runt Pulses
158-
pcnt_filter_enable(unit);
159-
197+
setFilter(250); // Filter Runt Pulses
160198

161-
/* Enable events on maximum and minimum limit values */
199+
/* Enable events on maximum and minimum limit values */
162200
pcnt_event_enable(unit, PCNT_EVT_H_LIM);
163201
pcnt_event_enable(unit, PCNT_EVT_L_LIM);
164-
165202
pcnt_counter_pause(unit); // Initial PCNT init
166-
pcnt_counter_clear(unit);
167203
/* Register ISR handler and enable interrupts for PCNT unit */
168-
if(attachedInterrupt==false){
169-
attachedInterrupt=true;
170-
esp_err_t er = pcnt_isr_register(pcnt_example_intr_handler,(void *) NULL, (int)0,
204+
if(! attachedInterrupt){
205+
esp_err_t er = pcnt_isr_register(esp32encoder_pcnt_intr_handler,(void *) NULL, (int)0,
171206
(pcnt_isr_handle_t *)&ESP32Encoder::user_isr_handle);
172207
if (er != ESP_OK){
173-
Serial.println("Encoder wrap interupt failed");
208+
ESP_LOGE(TAG, "Encoder wrap interrupt failed");
174209
}
210+
attachedInterrupt=true;
211+
}
212+
if (always_interrupt){
213+
pcnt_set_event_value(unit, PCNT_EVT_THRES_0, -1);
214+
pcnt_set_event_value(unit, PCNT_EVT_THRES_1, 1);
215+
pcnt_event_enable(unit, PCNT_EVT_THRES_0);
216+
pcnt_event_enable(unit, PCNT_EVT_THRES_1);
175217
}
218+
pcnt_counter_clear(unit);
176219
pcnt_intr_enable(unit);
177220
pcnt_counter_resume(unit);
178221

@@ -198,7 +241,7 @@ int64_t ESP32Encoder::getCountRaw() {
198241
return c;
199242
}
200243
int64_t ESP32Encoder::getCount() {
201-
return getCountRaw() + count;
244+
return count + getCountRaw();
202245
}
203246

204247
int64_t ESP32Encoder::clearCount() {
@@ -214,3 +257,13 @@ int64_t ESP32Encoder::resumeCount() {
214257
return pcnt_counter_resume(unit);
215258
}
216259

260+
void ESP32Encoder::setFilter(uint16_t value) {
261+
if(value>1023)value=1023;
262+
if(value==0) {
263+
pcnt_filter_disable(unit);
264+
} else {
265+
pcnt_set_filter_value(unit, value);
266+
pcnt_filter_enable(unit);
267+
}
268+
269+
}

0 commit comments

Comments
 (0)