Using encoders off board without an interrupt

Currently I'm using a potentiometer to read a position, but I'd like to migrate to using an encoder. The problem is that I already have an interrupt routine that needs to run while the encoder position is tracked. If I were to use an interrupt routine here one would fail, which defeats the purpose entirely.

My question is does anyone know of some way, perhaps a chip, that you can track a rotary encoder and output a signal like a pwm or analog signal that the arduino can read. The encoder does not need to be absolute and does not need to spin more than 360 degrees (or 270 or whatever pot's already do), so the output could be a bounded number.

Does this kind of thing exist?

Which microcontroller/board are you using?

Most of the time interrupts are not neccesary because the proccessing speed is faster than the event, then you can check continiously the event in your main loop and catch all variations.

FWIW the attached code tracks an encoder in software with no interrupts. I wrote it purely as an academic exercise to see if I knew how an encoder actually works. Schematic attached also.

YMMV.

encoder.png

encoder_v4.ino (3.58 KB)

Does this kind of thing exist?

Yes
See attached or google
hardware solution to reading quadrature encoders

Quadrature decoder.pdf (337 KB)

What makes you think an interrupt would in any way be desirable for reading an encoder?

In fact, why are you using an interrupt presently for any function?

The software to read the encoder will depend upon the type of encoder you use. The following code is for a polled encoder with a detent at every quadrature index position around the dial. I was testing on an optical encoder so there is no debounce. The encoder has a built in switch which I use for reset in this sketch.

//Based on code from: http://bildr.org/2012/08/rotary-encoder-arduino/

//Added start up position check to make index +1/-1 from first move
//Polled rather than interrupts

int encoderPinA = 10;
int encoderPinB = 11;
int buttonPin = 5;

int lastEncoded = 0;
int encoderValue = 0;

int lastencoderValue = 0;

void setup() {
  Serial.begin (9600);

  pinMode(encoderPinA, INPUT_PULLUP); 
  pinMode(encoderPinB, INPUT_PULLUP);
  pinMode(buttonPin, INPUT_PULLUP);

  //get starting position
  int lastMSB = digitalRead(encoderPinA);
  int lastLSB = digitalRead(encoderPinB);

  Serial.print("Starting Position AB  " );
  Serial.print(lastMSB);
  Serial.println(lastLSB);

  //let start be lastEncoded so will index on first click
  lastEncoded = (lastMSB << 1) |lastLSB;

}

void loop(){ 

  int MSB = digitalRead(encoderPinA); //MSB = most significant bit
  int LSB = digitalRead(encoderPinB); //LSB = least significant bit

  int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
  int sum  = (lastEncoded << 2) | encoded; //adding it to the previous encoded value

  if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
  if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;

  lastEncoded = encoded; //store this value for next time


  if(encoderValue != lastencoderValue){
    Serial.print("Index:  ");
    Serial.println(encoderValue);

    Serial.print("Binary Sum:  ");
    for (int i = 3; i >=0; i--)//routine for printing full 4 bits, leading zeros
    {
        Serial.print((sum>>i) & 0x01);
    }

    Serial.println();
    lastencoderValue=encoderValue;
  }

  //reset index
  if(digitalRead(buttonPin)==LOW){
    encoderValue=0;
  }

}

dschmitty90: Currently I'm using a potentiometer to read a position, but I'd like to migrate to using an encoder. The problem is that I already have an interrupt routine that needs to run while the encoder position is tracked. If I were to use an interrupt routine here one would fail, which defeats the purpose entirely.

Why do you think you can't have two different interrupts coexisting?

MarkT: Why do you think you can't have two different interrupts coexisting?

Precisely my point. Misunderstanding of how interrupts work goes hand-in-hand with misunderstanding of why and whether it might be desirable or in fact undesirable to use interrupts at all.

Paul__B: misunderstanding of why and whether it might be desirable or in fact undesirable to use interrupts at all.

My local supplier lists Nick Gammon's code which uses interrupts for an encoder.

For what its worth I'm using an arduino mega with the adafruit wav shield.

The reason an interrupt should be used is because every pulse needs to be counted and added to a counter. If there's any delay in the main code it will miss a pulse and the count will be off. The reason I can't use an interrupt to read the encoder is because the wav shield already plays files on an interrupt, so if another interrupt was called, it would interrupt the interrupt, stopping playback, which defeats the purpose entirely.

That quadrature decoder looks promising and I've seen it before, but I'm having difficulty figuring out from the datasheet alone how to hook it up and what exactly the output is. Is there a resource with examples on these?

dschmitty90: The reason an interrupt should be used is because every pulse needs to be counted and added to a counter.

That's not a reason to use an interrupt.

dschmitty90: If there's any delay in the main code it will miss a pulse and the count will be off.

So ... the trick is to make sure there's no delays in the main code.

it would interrupt the interrupt, stopping playback,

No it would not.

If your sketch uses multiple ISRs, only one can run at a time, other interrupts will be ignored (turned off) until the current one is finished.

so is this wrong? http://arduino.cc/en/Reference/attachInterrupt

dschmitty90: the wav shield already plays files on an interrupt,

Do you have any idea what that means?

dschmitty90: if another interrupt was called, it would interrupt the interrupt, stopping playback, which defeats the purpose entirely.

Why would it stop playback?

dschmitty90: That quadrature decoder looks promising and I've seen it before, but I'm having difficulty figuring out from the datasheet alone how to hook it up and what exactly the output is. Is there a resource with examples on these?

They're very simple devices. There's billions and billions of examples on the web.

Paul_B: Misunderstanding of how interrupts work goes hand-in-hand with misunderstanding of why and whether it might be desirable or in fact undesirable to use interrupts at all.

Interrupts and mechanical switches are rarely a good combination. Switches bounce and cause dozens of interrupts when they're switching, causing as many problems as they solve.

(...and "Hardware debouncing" belongs in the same category as using interrupts with switches - sounds good on paper, terrible idea in practice)

Paul__B:

dschmitty90: the wav shield already plays files on an interrupt,

Do you have any idea what that means?

it means it's running an interrupt service routine, which is a function that runs somewhat parallel to the main function. If it's running on an ISR, then according to the attachInterrupt page another ISR that is supposed to be called would be ignored. Additionally, eliminating delays is unacceptable, it's a cheap solution and doesn't answer my question. Which has only been partially answered with the HCTL-2032 that was linked.

Does anyone have any experience with the HCTL-2032 chip? How it works and how it could interface with an arduino? I can't find any examples on the web.

dschmitty90: according to the attachInterrupt page another ISR that is supposed to be called would be ignored.

Where does it say that?

When I read it it said:

"...other interrupts will be ignored (turned off) until the current one is finished"

Does anyone have any experience with the HCTL-2032 chip? How it works

The how it works is in the data sheet. If you can't find any one who has used this chip with an arduino then you will have to do it yourself. If you can't do it yourself then you will have to pay some one to do it for you.

You do not understand interrupts and the wave shield. This video shows a project of mine that is producing audio through the wave shield and producing an animation on the matrix display at the same time. Notice the audio does not stop when the animation is going.

http://youtu.be/pL0pMAPkkVw

Ok so help me understand interrupts. If I’m playing something from the shield then is it not running an ISR? If I had the encoder hooked up to an interrupt pin and told it to look for pulses and run a function that just changed a counting variable, would they both work at the same time? If the encoder was moving as the file is playing, would it recognize it?

Think of it this way.
An interrupt is a call to a function triggered by hardware.

If that function is short enough, there is time before that function is called again. So another function can be triggered by a different piece of hardware. Providing the time to service that interrupt is shorter than the time between it’s own interrupt rate and the other one, both interrupt routines seem to be running at once. Only they are running one after the other.

Playing a wav file involves getting a byte from the SD card and bit banging the SPI to drive the D/A. It does this in a shorter time than the repetition rate you need to sustain the audio.

So if your rotary converter’s repetition rate and what you do in one is short enough then you seem to do both at the same time.