Can you post a sketch with just your encoder code? It may help if you removed the Max code to focus just on the encoder until we get that going. You can send information on the encoder status using Serial.print.

After you get the encoder working you can add in the Max code.

You should close the duplicate thread so responses don't get split between the two.

If you pay $100 for your industrial-grade encoder you get nicely conditioned, pristine square waves out of your 2 outputs. A $2 encoder, however, is really two (three if it has a push-button) mechanical switches in a housing, and they are surprisingly bouncy. The Playground code is good for the former, but not the latter. Have a read of http://www.ganssle.com/debouncing.pdf, you will see (page 16) that using interrupts on the output of undebounced switches is a really bad idea unless you are sure the flip-flops in your micro can handle the bounce rise-times & pulse widths.

The solution is to use the debounce code in Ganslee document (page 20), triggered on a 1 ms timer interrupt. I've spent the last few evenings getting the following code to work, and it's really reliable. I've used the FrequencyTimer2 lib from the Playground, but since you have a fixed frequency you can probably hack it down significantly. The core routine (the timer interrupt) appears below, I have omitted the timer setup.

Note that there are four transitions that you can update the value of encoder0Pos on, I am only using one because my encoder goes through all 4 states in one "click", so I get one step per "click". Uncomment the others if yours is different. Note also that encoder0Pos needs to be declared volatile, this prevents the compiler from caching its value if you set it then read it back immediately (the interrupt may have triggered & the value updated between the two operations, you want the updated value, not the one you just wrote).

Add another element to the State[] array and process it in the same manner if you want to debounce the push-button as well. My encoder doesn't have one, so neither does my code.

The code assumes that A & B are connected to pins configured as input ( pinMode(encoder0PinA, INPUT); ), with the internal pullups enabled ( digitalWrite(encoder0PinA, HIGH); ), and the common pin to ground.

// if we just pressed the button (i.e. the input went from LOW to HIGH), // and we've waited long enough since the last press to ignore any noise... if (reading != _instance->_buttonPrevious)// && millis() - _instance->_time > 100) { _instance->_buttonState = reading;

// ... and remember when the last button press was //_instance->_time = millis(); }

What practical application are you using the rotary encoder in? I've got a bunch of them myself, small and good looking, but I cannot figure out a good use for them (actually, I always find a software way to get around using them).

OK, I see.Now, I think you would need some feedback for the rotary encoder setting anyway, on an LCD, or some flashing light or something. In this case, can't you have just a push button, and handle the setting through software? (That is, push the button until you reach the desired frequency, and when you reach maximum go back to 0).

That is basically what a rotary encoder is except that as you turn the knob it keeps pressing the button for you.

It's a user interface design choice. There is never an instance where you can't replace a rotary encoder with buttons but there's many cases where the enoder is nicer...volume knob on an amp, jog wheel on a cell phone, etc. In this case, I have a range of a couple of hundred values, it will be tedious with buttons, but it's just 10 revolutions of the knob for 200 ticks.

In this case, I need coarse and fine adjustments, the encoder has a built in button (push in the knob), so I can have it work as push for coarse leave out for fine. That's harder to do intuitively with buttons.

I don't know why it makes a difference having an LCD to give feedback. The encoder doesn't have a "zero" position anyway. As long as I turn clockwise the number should increase (until the end condition) and counterclockwise should decrease (until the other end condition). In this case, I'll probably just have the number stay put at the end, not wrap around, or maybe go into a function menu.