Go Down

Topic: max with a rotary encoder (Read 18420 times) previous topic - next topic


OK, I got it. I think I had something a bit different in mind, like this one:
(this is what I have).

Googling for "rotary encoder" results in wildly different things than the one from the first link on this thread.
I think it should have been called "rotary switch" rather than "rotary encoder" in the first place. I guess that the wording "encoder" comes from the fact that the switch position is returned as BCD (on 4 bits), so one would need a decoder to interface it with a system.

The rotary switch pictured above has a zero position (among 9 others, numbered). You can rotate it both directions and the rotation is not very smooth (wouldn't make a good volume control, from this perspective). The only application I can see for these would be some (mostly) static/predefined settings, like a temperature threshold, or for setting some voltage or frequency level. And since the writing on them is pretty small, I would like to have some feedback, eventually showing a meaningful value rather than a number between 0 to 9.


I think a quadrature rotary encoder with a push button is a very nice and intuitive user interface. Turn encoder to see function options available and press switch to select it. However as others have said a quality rotary encoders seem to be costly and the cheap mechanical one I got is not very precise in it's detents Vs steps.

I read one article about converting a stepping motor to act like a rotary encoder. It required a little external components but sounded like a need project to play with. Some steppers have very nice feeling 'jogs' and with a nice heavy knob might have a very nice feel.



Check this out:
One can turn it manually (like a rotary "encoder", but connected on an analog pin), or remotely (infrared).


OK, I got it. I think I had something a bit different in mind, like this one:

Your link calls this a Rotary DIP Switch, which very accurately describes where you'd use it.  Instead of having to toggle binary values on a DIP switch, you can enter the value in decimal with one of those devices.  Any sort of configuration setting that's not changed very often.

One can turn it manually (like a rotary "encoder", but connected on an analog pin), or remotely (infrared).

A potentiometer is a very basic electronic component, even radioshack stocks a huge assortment of crappy quality ones.  The arduino has 10-bit ADC, so ideally I'd be able to get 1024 different values over 3/4 of a turn of rotation, in practice, these pots aren't very good and have a lot of drift unless I ignore the bottom 2-3 bits.  This is useless for my application.  I do have some 10-turn pots with very complex knobs that show the value through the 10 rotations that were originally about $300 each and are physically larger than I expect my finished project to be.  But they are very impractical for what I'm doing becuase of size and price.

I also have an optical rotary encoder with about 1000 steps/rev that's around the same size and price as the 10 turn pots and gives perfect squarewave outputs.  But I can't use it either for the same reason.

A rotary encoder has continuous rotation, which is exactly what I need and are not limited by bits of precision that mean I need a $0.50 device to be stable over 5V/1000 steps = 5mV fluctuations.

If I wanted to use an IR remote, it would be easier to simply take the input from there instead of turning a pot.

Mark Mayhem

Thanks for the useful library, SunboX.

I tried using multiple instances of it, and it didn't work:

RotaryEncoder rotary1(7, 8, 9);
RotaryEncoder rotary2(10, 11, 12);

It is only returning readings from the rotary2 encoder.  What needs to be changed in the library so multiple encoders can be used?



I used exactly that code from RotaryEncoder.h, RotaryEncoder.cpp and the example code from "how to run it" in RotaryEncoderTest.pde. I connected the encoderPins pinA to Arduino pin 3, encoderPins pinB to Arduino pin 4, encoderPushButton to Arduino pin 2 and common to ground, but I couldn't get any output from void loop() in RotaryEncoderTest.pde.

Than i included a Serial.println("Start"); statement in the very beginning of void setup() of RotaryEncoderTest.pde. To verify that the RotaryEncoder object gets created I included a Serial.print("Encoder Object created"); message in RotaryEncoder.cpp, which worked fine. But still I didn't get any message from RotaryEncoderTest.pde.

Please, where is my mistake? :-/

Mark Mayhem

gatonero -

Check out Keith Neufeld's 'Quadrature' library.  It has solved all my encoder needs.  It allows for multiple encoders, works on overflow interrupt, and is easy to send over serial.

Here is his explanation:

And here is the library download:

There are examples, but if you need any more, let me know, and I'll post some code


I testes this also before. But with the example code while compiling, I'm getting this error message:

/usr/lib/gcc/avr/4.3.0/../../../../avr/include/stdlib.h:111: error: expected `)' before 'int'

/usr/lib/gcc/avr/4.3.0/../../../../avr/include/stdlib.h:111: error: expected `)' before 'int'

In file included from /home/christoph/bin/arduino-0015/hardware/cores/arduino/WProgram.h:6,

Couldn't determine program size: avr-size: '/tmp/build18656.tmp/quadrature_two_encoders.hex': No such file

Mark Mayhem

gatonero -

Oh yeah, I thought Keith was going to update.  Some libraries have the same problem in version 0013.

Adding this after all your #include statements should clear up the problem:

Code: [Select]
#undef int                    
#undef abs
#undef double
#undef float
#undef round


Thank You Mark. that works. I will post my further experiences with the arduino-quadratur library.


Apr 19, 2009, 12:50 am Last Edit: Apr 19, 2009, 12:56 am by gatonero Reason: 1
Very strange! Now the sketch gets compiled without any error messages. But like with the library RotaryEnconder no Serial.print() output. the Quadratur library. :o

My environment: Ubuntu 8.10 64bit, Arduino 0015 alpha


Jun 18, 2009, 11:11 am Last Edit: Jun 18, 2009, 11:29 am by boomy Reason: 1
This code helps me understanding what to do with debouncing.
I've read in the code that internal pull-ups are used for the A, B and switch.
So connecting the common rotary and switch to ground.
I'm just curious why I only see the Sensibility going up, and not down when I push the button. in the script above.

Code: [Select]

#include "RotaryEncoder.h"

RotaryEncoder rotary(2, 3, 4);

void setup()


void loop()
   Serial.print("Sensibility: ");

serial OUTPUT, turning the rotary CCW and CW
Sensibility: 40%
Sensibility: 46%
Sensibility: 48%
Sensibility: 49%
Sensibility: 50%
Sensibility: 51%
Sensibility: 52%

Also with Keith Neufeld's 'Quadrature' library I only see increments when rotating both ways..
60      0
61      0
62      0
63      0


Jun 18, 2009, 12:46 pm Last Edit: Jun 19, 2009, 03:17 am by boomy Reason: 1
Everything works now. (counting up & down) when I don't use the ethernetshield.
I think the ethernetshield messed the overflow interrupt up or something like it.

Everytime I put the ethernet board on Arduino, the RotaryEncoder only counts up OR down, but not both ways.
What I've understood was "RotaryEncoder.h" is using the timer/counter on port 11.
Port 11 is also in use by the ethernet board.
See also the http://www.arduino.cc/en/Main/ArduinoEthernetShield for the ports in use.

To use the other timer, I've checked the datasheet and so I modified the RotaryEncoder.cpp with the following:
TIMSK1 |= (1 << TOIE1);
Deleted the compiled.o file and uploaded the code to the board.
The modified code works without an ethernet board, but again when I use the ethernet board, it only counts down, not up.
Also some other flickering is noticable in the lights.

Now I'm looking for a way to use the ethernet controller and the rotary library. I hope this is technically possible.
but I'm a bit lost now.  :-/


Food to read:


Ok, don't mention the time I wrote this.
I just gave myself some food to read in my previous post, and came up with the idea to exchange the ports 3 & 4 with port 7 and 8.
This solved my problems for the rotary encoder.
I think I now can use the ethernetboard AND the rotary encoder.

   * Timer0 (System timing, PWM 5 and 6)
     Used to keep track of the time the program has been running. The millis() function to return the number of milliseconds since the program started using a global incremented in the timer 0 ISR. Timer 0 is also used for PWM outputs on digital pins 5 and 6.

   * Timer1 (PWM 9 and 10)
     Used to drive PWM outputs for digital pins 9 and 10.
   * Timer2 (PWM 3 and 11)
     Used to drive PWM outputs for digital pins 3 and 11.

And also that my rotary was only counting one way (pin 4, and not 3 who allready was in use).

I slowly begin to understand how to define and the differences the interrupts have, I realy would like to understand more of it.


Did someone try the Sunny's library with a 3bit Gray Code encoder?

I'd like to get result with a TW-700198
from sparkfun.com/datasheets/Components/TW-700198.pdf

Go Up