[SOLVED] Rotary Encoder only increments

Hi All,

Learning the rotary encoder and i've managed to get this far

int PinA = 6;
int PinB = 7;
int Counter = 10;
int PinALastState = LOW;
int pinAState = LOW;

void setup() {
  pinMode (PinA, INPUT);
  pinMode (PinB, INPUT);
  Serial.begin (9600);
}

void loop() {
  pinAState = digitalRead(PinA);
  if ((PinALastState == LOW) && (pinAState == HIGH))
  {
    if (digitalRead(PinB) == LOW) {
      Counter--;
    } else {
      Counter++;
    }
    Serial.println(Counter);
  }
  PinALastState = pinAState;
}

for some reason the decrements do not seem to working it just increments no matter how i turn the knob.

Just guessing, but does the digital read of PinB ever go LOW?
I would write a test sketch to read both pins and print the values.
Then you should see something like this:

00
01
11
10

with possible repetitions.

No Vince, Just increments like below
2
3
4
5
6
7
8
9
10
11
12
13
14
15

here is my wiring just one 10K resistor between pin A and GND

half through it comes like this
169
170
169
170
171
172
173
172
171
170
169
170
171
172
173
172
173
174
175
176
177
176

and after a reset
2
1
0
-1
-2
-3
-4
-5
-6
-5
-6
-5
-4
-5
-6
-5
-4
-5
-4
-3
-2
-1
0
1
2
3
4
3
2
1
2
1
2

anishkgt:
here is my wiring just one 10K resistor between pin A and GND

Per the photo it doesn't look like the ground side of the resistor is connected to ground, maybe I'm not seeing well. Should you not also have a resistor to ground for channel B? What happens if you swap the blu/orn wires on the Arduino header?

anishkgt:
for some reason the decrements do not seem to working it just increments no matter how i turn the knob.

Check to see if you need to set the pinmode to "INPUT_PULLUP" or not.

Also..... one end of your resistor doesn't even seem to be connected to anything. The leg is just connected to a rail, but nothing else is connected to it. If that resistor is needed..... then the problem here is..... you need to review the basics of bread-boards. The rows of little hole sockets in different sections of the bread-board are not always electrically-connected in the same direction.

Southpark:
Check to see if you need to set the pinmode to "INPUT_PULLUP" or not.

Also..... one end of your resistor doesn't even seem to be connected to anything. The leg is just connected to a rail, but nothing else is connected to it. If that resistor is needed..... then the problem here is..... you need to re-learn/learn some things about breadboards.

changed the code to just INPUT and no visible change on the serial monitor.

The wiring is correct and the resistor is connected to GND and the other to pin A.

anishkgt:
The wiring is correct and the resistor is connected to GND and the other to pin A.

The wiring is not correct in this photo you provided. If you go back to the bread-board manual, and look at the internal wiring of the bread-board along that rail.... you will find that your resistor leg is connected to nothing.

Take a look at the red coloured arrow.

Also, if you intend that resistor leg to be connected to ground, then probably need to make sure that it really needs to be connected to ground (ie.......the purpose of that resistor).

dougp:
Per the photo it doesn't look like the ground side of the resistor is connected to ground, maybe I'm not seeing well. Should you not also have a resistor to ground for channel B? What happens if you swap the blu/orn wires on the Arduino header?

Added to resistor to pin B as well, no change. Swaped the wires in the arduino PINs A and B, no change there either.

Southpark:
The wiring is not correct in this photo you provided. If you go back to the bread-board manual, and look at the internal wiring of the bread-board along that rail.... you will find that your resistor leg is connected to nothing.

Take a look at the red coloured arrow.

checked and for some reason i missed that. but i've correct it now, not thing noticeable change tho.

re: photo in post #11 - where is the resistor for channel B?

Can you try what @vinceherman described in reply #1 and create a sketch that outputs the pin states instead of counting.

i had removed since it did not make a difference.

Tried the test what vinceherman mentioned and all seems to go high only.

int PinA = 6;
int PinB = 7;
int val;
int Counter = 1;
int PinALastState = LOW;
int pinAState = LOW;

void setup() {
  pinMode (PinA, INPUT);
  pinMode (PinB, INPUT);
  Serial.begin (9600);
}

void loop() {
  pinAState = digitalRead(PinA);
  if ((PinALastState == LOW) && (pinAState == HIGH))
  {
    if (digitalRead(PinA) == LOW) {
      Serial.println(0);
    } else {
      Serial.println(1);
    }
    //Serial.println(Counter);
  }
  PinALastState = pinAState;
}

anishkgt:
i had removed since it did not make a difference.

Since both channels are (presumably) electrically identical, I'd wire them both the same way.

change

  pinMode (PinA, INPUT);
  pinMode (PinB, INPUT);

to

  pinMode (PinA, INPUT_PULLUP);
  pinMode (PinB, INPUT_PULLUP);

And wire the encoder the standard way:
common to GND,
channels to pinA and pinB, no other connections, no physical resistors.

Then you have the standard setup.

Then check that the pins are being read correctly:

void loop ()
{
  Serial.print (digitalRead (pinA)) ; Serial.print (",") ; Serial.println (digitalRead (pinB)) ;
}

You can also use a multimeter to check the voltages on the pins directly as the encoder is turned
slowly.

And if this produces the expected results, then go back to the encoder logic.

Proceed step by step, from the most basic, checking everything at each stage is as expected
before proceeding to the next. That way you are far less likely to get confused, or assume
something that you haven't actually checked.

Tire @MarkT suggestion

int PinA = 6;
int PinB = 7;
int val;
int Counter = 1;
int PinALastState = LOW;
int pinAState = LOW;

void setup() {
  pinMode (PinA, INPUT_PULLUP);
  pinMode (PinB, INPUT_PULLUP);
  Serial.begin (9600);
}

void loop() {
  pinAState = digitalRead(PinA);
  if ((PinALastState == LOW) && (pinAState == HIGH))
  {
    if (digitalRead(PinA) == LOW) {
      Counter--;
    } else {
      Counter++;
    }
    Serial.print (digitalRead (PinA)) ; Serial.print (",") ; Serial.println (digitalRead (PinB)) ;
    //Serial.println(Counter);
  }
  PinALastState = pinAState;
}

The output is
1,0
1,0
1,1
1,1
1,1
1,1
1,1
1,1
1,1
1,0
1,0
1,0
1,0
1,1

Sifting through old posts last night I saw a thread - can't remember which topic - where the encoder itself was defective, IIRC it was made in a large country in the Orient. As a final check I suppose you could remove the Arduino connections and test the encoder in isolation. Wire up an LED and associated resistor to the channel B pin and see if there's any change when rotated.

anishkgt:

void loop() {

pinAState = digitalRead(PinA);
 if ((PinALastState == LOW) && (pinAState == HIGH))
 {
    // (... counter stuff ...)
    Serial.print (digitalRead (PinA)) ; Serial.print (",") ; Serial.println (digitalRead (PinB)) ;
   //Serial.println(Counter);
 }

You have put that line inside the "if ((PinALastState == LOW) && (pinAState == HIGH)) {}"
so it is normal that it only logs when pinA goes high.
But at least you can see that pinB is sometimes low and sometimes high when this happens,
presumably/hopefully depending on the turn direction.