Skip to content

Commit

Permalink
Merge pull request #631 from NemesisXB/update_encoder
Browse files Browse the repository at this point in the history
Improve Rotary Encoder
  • Loading branch information
UncleRus authored May 16, 2024
2 parents 315294a + e844783 commit c6c2e0e
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 3 deletions.
11 changes: 11 additions & 0 deletions components/encoder/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,15 @@ menu "Rotary encoders"
int "Long press timeout, us"
default 500000

config RE_ACCELERATION_MIN_CUTOFF
int "Minimum Acceleration cutoff time (ms)"
default 200
help
At this time in milliseconds between rotary ticks we want to be at the minimum acceleration

config RE_ACCELERATION_MAX_CUTOFF
int "Maximum Acceleration cutoff time (ms)"
default 4
help
At this time in milliseconds between rotary ticks we want to be at the maximum acceleration
endmenu
41 changes: 38 additions & 3 deletions components/encoder/encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,33 @@ inline static void read_encoder(rotary_encoder_t *re)

re->store = (re->store << 4) | re->code;

if (re->store == 0xe817) inc = 1;
if (re->store == 0xd42b) inc = -1;
if ((re->store == 0xe817)||(re->store == 0x17e8)) inc = 1;
if ((re->store == 0xd42b)||(re->store == 0x2bd4)) inc = -1;

if (inc)
{
ev.type = RE_ET_CHANGED;
ev.diff = inc;
if (re->acceleration.coeff > 1)
{
int64_t nowMicros = esp_timer_get_time();
// at 200 ms, we want to have minimum acceleration
uint32_t accelerationMinCutoffMillis = CONFIG_RE_ACCELERATION_MIN_CUTOFF;
// at 4 ms, we want to have maximum acceleration
uint32_t accelerationMaxCutoffMillis = CONFIG_RE_ACCELERATION_MAX_CUTOFF;
uint32_t millisAfterLastMotion = (nowMicros - re->acceleration.last_time) / 1000u;
re->acceleration.last_time = nowMicros;

if (millisAfterLastMotion < accelerationMinCutoffMillis)
{
if (millisAfterLastMotion < accelerationMaxCutoffMillis)
{
millisAfterLastMotion = accelerationMaxCutoffMillis; // limit to maximum acceleration
}
ev.diff = inc * ((int32_t)(re->acceleration.coeff / millisAfterLastMotion) == 0 ? 1 : (int32_t)(re->acceleration.coeff / millisAfterLastMotion));
}
}

ev.type = RE_ET_CHANGED;
xQueueSendToBack(_queue, &ev, 0);
}
}
Expand Down Expand Up @@ -252,3 +272,18 @@ esp_err_t rotary_encoder_remove(rotary_encoder_t *re)
xSemaphoreGive(mutex);
return ESP_ERR_NOT_FOUND;
}

esp_err_t rotary_encoder_enable_acceleration(rotary_encoder_t *re, uint16_t coeff)
{
CHECK_ARG(re);
re->acceleration.coeff = coeff;
re->acceleration.last_time = esp_timer_get_time();
return ESP_OK;
}

esp_err_t rotary_encoder_disable_acceleration(rotary_encoder_t *re)
{
CHECK_ARG(re);
re->acceleration.coeff = 0;
return ESP_OK;
}
23 changes: 23 additions & 0 deletions components/encoder/encoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ typedef enum {
RE_BTN_LONG_PRESSED = 2 //!< Button currently long pressed
} rotary_encoder_btn_state_t;

//Rotary encoder acceleration variables
typedef struct {
int64_t last_time;
uint16_t coeff;
} rotary_encoder_acceleration_t;
/**
* Rotary encoder descriptor
*/
Expand All @@ -68,6 +73,7 @@ typedef struct
size_t index;
uint64_t btn_pressed_time_us;
rotary_encoder_btn_state_t btn_state;
rotary_encoder_acceleration_t acceleration;
} rotary_encoder_t;

/**
Expand Down Expand Up @@ -115,6 +121,23 @@ esp_err_t rotary_encoder_add(rotary_encoder_t *re);
*/
esp_err_t rotary_encoder_remove(rotary_encoder_t *re);

/**
* @brief Enable acceleration on the rotary encoder
*
* @param re Encoder descriptor
* @param coeff Acceleration coefficient. Higher value means faster acceleration
* @return esp_err_t
*/
esp_err_t rotary_encoder_enable_acceleration(rotary_encoder_t *re, uint16_t coeff);

/**
* @brief Disable acceleration on the rotary encoder
*
* @param re Encoder descriptor
* @return `ESP_OK` on success
*/
esp_err_t rotary_encoder_disable_acceleration(rotary_encoder_t *re);

#ifdef __cplusplus
}
#endif
Expand Down
4 changes: 4 additions & 0 deletions examples/encoder/default/main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,13 @@ void test(void *arg)
break;
case RE_ET_BTN_CLICKED:
ESP_LOGI(TAG, "Button clicked");
rotary_encoder_enable_acceleration(&re, 100);
ESP_LOGI(TAG, "Acceleration enabled");
break;
case RE_ET_BTN_LONG_PRESSED:
ESP_LOGI(TAG, "Looooong pressed button");
rotary_encoder_disable_acceleration(&re);
ESP_LOGI(TAG, "Acceleration disabled");
break;
case RE_ET_CHANGED:
val += e.diff;
Expand Down

0 comments on commit c6c2e0e

Please sign in to comment.