Encoder and interrupts

Status
Not open for further replies.

spencoid

Well-known member
This question has been asked a couple of times over the years with no answer. I am using the encoder library from the latest teensyduino installation. I am testing with teensy 3.2. I understand from previous "answers" that the default with encoder is to use interrupts. That is not the issue. The problem is that I need to specifically disable interrupts to get any data from the encoder. The very simple sketch below toggles an LED when the encoder count goes above or below 0. It works fine if first line is not commented out but there is no response if it is. I want to be assured that I am not missing encoder counts and it seems that if I disable interrupts this will not be the case. Is there a problem with my choice of pins? All pins on the teensy 3.2 are supposed to be interrupt enabled? What else?


Code:
//#define ENCODER_DO_NOT_USE_INTERRUPTS

#include <Encoder.h>

Encoder readEnc1(5, 6);

long readEncoder_1;
void setup(){
  pinMode(13, OUTPUT);
  pinMode(5, INPUT_PULLUP); // input encoder
  pinMode(6, INPUT_PULLUP); // input encoder 
  digitalWriteFast(LED_BUILTIN, HIGH);  // verify that LED works
}

void loop(){
    readEncoder_1 = readEnc1.read();
    if (readEncoder_1 < 0) {  // backward or clockwise
        digitalWriteFast(LED_BUILTIN, HIGH);
    }   
    if (readEncoder_1 > 0){ // forward or clockwise
        digitalWriteFast(LED_BUILTIN, LOW);
    }    
}
 
Last edited by a moderator:
Sorry I have not used the encode library in a long time, and usually I spun my own...

But looking at the code, I don't like certain parts of it, and don't really know if or how it works... But not sure how it works when you do use interrupts as well.


Maybe it is fine... I am just not sure how well it works with mucking with the pins, doing delays...

If it were me as a test, I would probably try doing the new operation as part of setup. i.e. have the global variable be a pointer and do an assignment to it in setup and see if it runs any different...

Maybe I need to find one of my encoders... Unless someone beat me to it.

One thing I noticed in my quick look through is I believe the library utility/direct_pin_read.h is WRONG for T4...

Code:
#elif defined(TEENSYDUINO) && (defined(KINETISK) || defined(KINETISL))

#define IO_REG_TYPE			uint8_t
#define PIN_TO_BASEREG(pin)             (portInputRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
#define DIRECT_PIN_READ(base, mask)     (((*(base)) & (mask)) ? 1 : 0)

#elif defined(__IMXRT1052__) || defined(__IMXRT1062__)

#define IO_REG_TYPE			uint32_t
[COLOR="#FF0000"]#define PIN_TO_BASEREG(pin)             (portOutputRegister(pin))[/COLOR]
#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
#define DIRECT_PIN_READ(base, mask)     (((*(base)) & (mask)) ? 1 : 0)

#elif defined(__SAM3X8E__)  // || defined(ESP8266)
My guess is the line in RED should be:
Code:
#define PIN_TO_BASEREG(pin)             (portInputRegister(pin))
 
Are you using an encoder with detents?

The detents are often set at a particular point in the quadrature cycle, so if you disable interrupts and happen to only poll read() when the encoder is at detents, the state of the pins doesn't appear to change, and you won't get counts.
 
I wouldn't touch the encoder pins in setup(), let the encoder library set them up, you may have stomped all
over the libraries attempt to configure those pins suitably for interrupts.
 
Status
Not open for further replies.
Back
Top