Go Down

Topic: Encoder Output (Read 6113 times) previous topic - next topic


It seems like 90% of time, the encoders only go in one directions. Regardless of which way I turn them.

Thats because you have Serial.prints and delays in the loop. It slows it down so it skips transitions. I bet if you turn the knobs really slowly its ok.

I didn't realise the Serial.print was any more than trace. If you want to capture the turns and send them to Processing, then you need to buffer the events and send them to Processing in batches, when no knob turning is going on.

Is that possible? What is the end goal of your project? Etch-a-sketch?
I write books about Arduino and Electronics: http://simonmonk.org


Apr 22, 2011, 07:27 pm Last Edit: Apr 22, 2011, 07:30 pm by imagiro1 Reason: 1
Yes, the end project is an Etch-a-sketch. It's for an art project. I should mention, I am not an art major. I'm an electrical engineer who's not very good at coding.

I've changed my void loop to look like this
Code: [Select]
void loop()
 for(int i = 0 ; i < 12 ; i = i+4){
   d_send[i] = getEncoderTurn_1();
   d_send[i+1] = getEncoderTurn_2();
   d_send[i+2] = getSwitch_1();
   d_send[i+3] = getSwitch_2();

 for (int i = 0; i < 12; i++){


And added this variable:
Code: [Select]
char d_send[12];

But it seems to have a larger problem. When I open the serial monitor, it freezes the serial monitor. When I run the processing code, I just get blanks and then it freezes it too. Ha.

Also, before I changed the code, I noticed it would just keep sending m and n. These were dummy values I created to see what the Arduino was sending when I wasn't clicking the button. It should never be sending m and n. It should only send M or N depending which switch it pressed. This is part of the code I posted earlier. Thanks again for the help.


It wouldn't be as good, but I have to say pots as potential divers on two analog inputs wouldn't have all these problems.

Worth considering.
I write books about Arduino and Electronics: http://simonmonk.org


You lost me Si. I don't have anything hooked up to the analogue inputs.


Imagiro1, all I meant was that you could use potentiometers (variable resistors) instead of the rotary encoders.

With one end connected to +V the other to GND and the slider to an analog in, you can read a value between 0 and 1023 for the position of the knob using analogRead(pin).

I write books about Arduino and Electronics: http://simonmonk.org


Yes, but then it wouldn't be able to go around in circuits. Pots would stop when they hit their limits.


Look for Arduino Quadrature on google there is sketch that works well.

I work with 10 rotary encoders with push buttons with an Maga card without any trouble !


Grag38, thanks for the tip. A few questions about the code... (I'll post the code since there are a few versions)

Code: [Select]
/* read a rotary encoder with interrupts
   Encoder hooked up with common to GROUND,
   encoder0PinA to pin 2, encoder0PinB to pin 4 (or pin 3 see below)
   it doesn't matter which encoder pin you use for A or B 

   uses Arduino pullups on A & B channel outputs
   turning on the pullups saves having to hook up resistors
   to the A & B channel outputs


#define encoder0PinA  2
#define encoder0PinB  4

volatile unsigned int encoder0Pos = 0;

void setup() {

  pinMode(encoder0PinA, INPUT);
  digitalWrite(encoder0PinA, HIGH);       // turn on pullup resistor
  pinMode(encoder0PinB, INPUT);
  digitalWrite(encoder0PinB, HIGH);       // turn on pullup resistor

  attachInterrupt(0, doEncoder, CHANGE);  // encoder pin on interrupt 0 - pin 2
  Serial.begin (9600);
  Serial.println("start");                // a personal quirk


void loop(){
// do some stuff here - the joy of interrupts is that they take care of themselves

void doEncoder() {
  /* If pinA and pinB are both high or both low, it is spinning
   * forward. If they're different, it's going backward.
   * For more information on speeding up this process, see
   * [Reference/PortManipulation], specifically the PIND register.
  if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB)) {
  } else {

  Serial.println (encoder0Pos, DEC);

1. What does encoder0Pos return if I don't pass it through the Serial.print? Sorry, I don't have the encoder with me right now to test it. The other code I was using would return -1,0, or 1. So I could convert it to send 'A' or 'B' depending on the direction.

2. Do I have to call doEncoder from the void Loop?

3. Do I need resistors? I'm guessing No, since of the digitalWrite High.

4. Could I use interrupts to read if the button is being pressed?

5. Ahhhh, this might be the killer. I believe my board has only 2 interrupts. I would need 4 right? http://arduino.cc/en/Main/ArduinoBoardDuemilanove



Ha. Got it working. Thanks Grag38 and Si. Best Etch-a-Sketch ever!

Go Up