/
singlwolf
/
Radiola-2S3
Обзор
Документация
Войти
/
singlwolf
/
Radiola-2S3
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/RotaryEncoder.cpp
111 строк
3 KB
SinglWolf
Public access
27 мар 2026, 07:00
27 мар 2026, 07:00
642fcfc
Код
Авторство
О чём код?
// based on https://github.com/igorantolic/ai-esp32-rotary-encoder code // // // #include "esp_log.h" // #define LOG_TAG "RotaryEncoder" #include "RotaryEncoder.h" #include "rom/gpio.h" void IRAM_ATTR RotaryEncoder::readEncoder_ISR() { portENTER_CRITICAL_ISR(&(this->mux)); if (this->isEnabled) { this->old_AB <<= 2; uint32_t gpio_in = GPIO_REG_READ(GPIO_IN1_REG); int8_t ENC_PORT = 0; if (gpio_in & (1U << (this->encoderAPin - 32))) ENC_PORT |= (1 << 0); if (gpio_in & (1U << (this->encoderBPin - 32))) ENC_PORT |= (1 << 1); this->old_AB |= (ENC_PORT & 0x03); int8_t currentDirection = this->enc_states[this->old_AB & 0x0f]; if (currentDirection != 0) { this->encoder0Pos += currentDirection; // Применяем границы if (this->encoder0Pos > this->_maxEncoderValue) this->encoder0Pos = this->_circleValues ? this->_minEncoderValue : this->_maxEncoderValue; if (this->encoder0Pos < this->_minEncoderValue) this->encoder0Pos = this->_circleValues ? this->_maxEncoderValue : this->_minEncoderValue; } } portEXIT_CRITICAL_ISR(&(this->mux)); } RotaryEncoder::RotaryEncoder() { this->old_AB = 0; } void RotaryEncoder::setBoundaries(long minEncoderValue, long maxEncoderValue, bool circleValues) { this->_minEncoderValue = minEncoderValue * this->encoderSteps; this->_maxEncoderValue = maxEncoderValue * this->encoderSteps; this->_circleValues = circleValues; } long RotaryEncoder::readEncoder() { return (this->encoder0Pos / this->encoderSteps); } void RotaryEncoder::setEncoderValue(long newValue) { reset(newValue); } long RotaryEncoder::encoderChanged() { long _encoder0Pos = readEncoder(); long encoder0Diff = _encoder0Pos - this->lastReadEncoder0Pos; this->lastReadEncoder0Pos = _encoder0Pos; return encoder0Diff; } void RotaryEncoder::setup(void (*ISR_callback)(void)) { attachInterrupt(digitalPinToInterrupt(this->encoderAPin), ISR_callback, CHANGE); attachInterrupt(digitalPinToInterrupt(this->encoderBPin), ISR_callback, CHANGE); } void RotaryEncoder::begin(int8_t encoder_APin, int8_t encoder_BPin, uint8_t encoderSteps, bool internalPullup) { this->lastReadEncoder0Pos = 0; this->encoderAPin = encoder_APin; this->encoderBPin = encoder_BPin; this->encoderSteps = encoderSteps; pinMode(this->encoderAPin, internalPullup ? INPUT_PULLUP : INPUT); pinMode(this->encoderBPin, internalPullup ? INPUT_PULLUP : INPUT); } void RotaryEncoder::reset(long newValue_) { newValue_ = newValue_ * this->encoderSteps; this->encoder0Pos = newValue_; this->lastReadEncoder0Pos = this->encoder0Pos; if (this->encoder0Pos > this->_maxEncoderValue) this->encoder0Pos = this->_circleValues ? this->_minEncoderValue : this->_maxEncoderValue; if (this->encoder0Pos < this->_minEncoderValue) this->encoder0Pos = this->_circleValues ? this->_maxEncoderValue : this->_minEncoderValue; } void RotaryEncoder::enable() { this->isEnabled = true; } void RotaryEncoder::disable() { this->isEnabled = false; }