Browse Source

new encoder try

main
Hendrik Langer 7 years ago
parent
commit
9b46ccdeca
  1. 12
      src/main.cpp
  2. 61
      src/rotary.cpp
  3. 9
      src/rotary.h

12
src/main.cpp

@ -8,12 +8,12 @@
* GND O O GND * GND O O GND
* 5V O O 5V * 5V O O 5V
* 3V3 O O 3V3 * 3V3 O O 3V3
* GND O < 36 * GND O < 36 only input, no pullups
* RX * * 17 * RX * * 17
* TX * < 38 ROTARY_A * TX * < 38 ROTARY_A only input, no pullups
* RST * BUTTON < 39 ROTARY_B * RST * BUTTON < 39 ROTARY_B only input, no pullups
* 0 * BUTTON < 34 * 0 * BUTTON < 34 only input, no pullups
* 22 * < 35 * 22 * < 35 only input, no pullups
* BME280_SDO 19 * LoRa_MISO ? * 32 * BME280_SDO 19 * LoRa_MISO ? * 32
* BME280_CS 23 * ? * 33 * BME280_CS 23 * ? * 33
* 18 x LoRa_CS * 25 MAX98_DIN * 18 x LoRa_CS * 25 MAX98_DIN
@ -313,5 +313,5 @@ void loop()
u8g2.sendBuffer(); u8g2.sendBuffer();
// bme280.printValues(); // bme280.printValues();
delay(100); delay(200);
} }

61
src/rotary.cpp

@ -1,13 +1,5 @@
/* interrupt routine for Rotary Encoders /* interrupt routine for Rotary Encoders
tested with Noble RE0124PVB 17.7FINB-24 http://www.nobleusa.com/pdf/xre.pdf - available at pollin.de idea from: https://github.com/marcmerlin/IoTuz/blob/95f53be6569c68f7fbef491bb36082870f82d629/IoTuz.cpp
and a few others, seems pretty universal
The average rotary encoder has three pins, seen from front: A C B
Clockwise rotation A(on)->B(on)->A(off)->B(off)
CounterCW rotation B(on)->A(on)->B(off)->A(off)
and may be a push switch with another two pins, pulled low at pin 8 in this case
raf@synapps.de 20120107
*/ */
@ -15,7 +7,11 @@
//using namespace std; //using namespace std;
Rotary::Rotary() {} Rotary* Rotary::instance = NULL;
Rotary::Rotary() {
instance = this;
}
bool Rotary::begin(uint8_t pinA, uint8_t pinB, uint8_t pinButton) { bool Rotary::begin(uint8_t pinA, uint8_t pinB, uint8_t pinButton) {
this->pinA = pinA; this->pinA = pinA;
@ -25,9 +21,6 @@ bool Rotary::begin(uint8_t pinA, uint8_t pinB, uint8_t pinButton) {
pinMode(pinB, INPUT_PULLUP); pinMode(pinB, INPUT_PULLUP);
pinMode(pinButton, INPUT_PULLUP); pinMode(pinButton, INPUT_PULLUP);
encoder = new ClickEncoder(pinA, pinB, pinButton, 4);
//encoder->setButtonOnPinZeroEnabled(true);
xTaskCreate( xTaskCreate(
&cTaskWrapper, /* Task function. */ &cTaskWrapper, /* Task function. */
"encoderTask", /* String with name of task. */ "encoderTask", /* String with name of task. */
@ -35,6 +28,10 @@ bool Rotary::begin(uint8_t pinA, uint8_t pinB, uint8_t pinButton) {
this, /* Parameter passed as input of the task */ this, /* Parameter passed as input of the task */
tskIDLE_PRIORITY+2, /* Priority of the task. */ tskIDLE_PRIORITY+2, /* Priority of the task. */
&taskHandle); /* Task handle. */ &taskHandle); /* Task handle. */
attachInterrupt(digitalPinToInterrupt(pinA), doEncoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(pinB), doEncoder, CHANGE);
return true; return true;
} }
@ -43,14 +40,13 @@ void Rotary::cTaskWrapper(void* parameters) {
} }
void Rotary::task(void *pvParameters) { void Rotary::task(void *pvParameters) {
xTaskToNotify = xTaskGetCurrentTaskHandle();
uint32_t ulNotificationValue;
while(true) { while(true) {
encoder->service(); ulNotificationValue = ulTaskNotifyTake( pdFALSE, portMAX_DELAY );
value += encoder->getValue(); int newPos = encoderPos/2;
if (value != last) { if (lastPos != newPos)
last = value; if (callback) callback(newPos);
if (callback) callback(value);
}
vTaskDelay(1 / portTICK_PERIOD_MS);
} }
vTaskDelete(NULL); vTaskDelete(NULL);
} }
@ -59,3 +55,28 @@ bool Rotary::registerCallback(std::function<void(int)> callback) {
this->callback = callback; this->callback = callback;
return true; return true;
} }
// Interrupt on changing state
void Rotary::doEncoder() {
if ((millis() - instance->debounceMillis) > instance->debounceDelay) {
instance->debounceMillis = millis();
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
static uint8_t old_AB = 0;
// grey code
// http://hades.mech.northwestern.edu/index.php/Rotary_Encoder
// also read up on 'Understanding Quadrature Encoded Signals'
// https://www.pjrc.com/teensy/td_libs_Encoder.html
// another interesting lib: https://github.com/0xPIT/encoder/blob/arduino/ClickEncoder.cpp
static int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
old_AB <<= 2;
old_AB |= ((digitalRead(instance->pinB))?(1<<1):0) | ((digitalRead(instance->pinA))?(1<<0):0);
instance->encoderPos += ( enc_states[( old_AB & 0x0f )]);
configASSERT( instance->xTaskToNotify != NULL );
vTaskNotifyGiveFromISR( instance->xTaskToNotify, &xHigherPriorityTaskWoken );
portYIELD_FROM_ISR(); //portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
}

9
src/rotary.h

@ -17,8 +17,13 @@ class Rotary {
Rotary(); Rotary();
bool begin(uint8_t pinA, uint8_t pinB, uint8_t pinButton); bool begin(uint8_t pinA, uint8_t pinB, uint8_t pinButton);
bool registerCallback(std::function<void(int)> callback); bool registerCallback(std::function<void(int)> callback);
ClickEncoder *encoder; static void IRAM_ATTR doEncoder(void);
int16_t last, value; static Rotary* instance;
volatile int encoderPos = 0;
int lastPos = 0;
uint32_t debounceMillis;
uint32_t debounceDelay = 1;
TaskHandle_t xTaskToNotify;
private: private:
uint8_t pinA; uint8_t pinA;
uint8_t pinB; uint8_t pinB;

Loading…
Cancel
Save