Rotary Encoder Not Woeking no matter what?

Hey all!
Ok so i got cheap rotary encoder that has no markings, i tried all possible libraries and this thing does not work. I even thought im stupid and maybe magically its a pot so i run button script to see if we register "clicks" and i can see high/low just fine when i treat rotation step as a button press (which is what encoder is anyway) now i try using libraries and no avail. No steps are detected, tried all libs i can find.

My connection: Middle Pin - GND, side pins to Arduino Meda 11, 12
Using internal pull ups

Am i doing something wrong?

At end of day i can write my own lib but my guess if there like 8 libs out there and non of them working for me then it should be error in my application?

Any ideas?

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

What Libraries did you try?

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Do you have a DMM to check if the voltages on the pins are pulsing as you turn the shaft.

Can you post a picture of your encoder please, to help us identify the type and pinout?

Thanks.. Tom... :slight_smile:

Do you have filters on the pins as well as shown on the bottom of page 2 here?

This is the PCINT code basics that detects rotary encoder turns on my board.
pinA and pinB are two pins on Port B, D8 to D13 on an Uno.
In my code, it is keeping track of fileNumber, which is allowed to go from 0 to 255, and wraps around from 255 to 0 ,1 etc if exceeded one direction, and 0 to 255, 254, etc if going the other direction.

volatile boolean fired = false;


 // handle pin change interrupt for D8 to D13 here
ISR (PCINT0_vect)
{
static byte pinA, pinB;  
static boolean ready;
static unsigned long lastFiredTime;


  byte newPinA = digitalRead (Encoder_A_Pin);
  byte newPinB = digitalRead (Encoder_B_Pin);
  
  if (pinA == newPinA && 
      pinB == newPinB)
      return;    // spurious interrupt


  // so we only record a turn on both the same (HH or LL)
  
  // Forward is: LH/HH or HL/LL
  // Reverse is: HL/HH or LH/LL


  if (newPinA == newPinB)
    {
    if (ready)
      {
        
      if (millis () - lastFiredTime >= ROTARY_DEBOUNCE_TIME)
        {
        if (newPinA == HIGH)  // must be HH now
          {
          if (pinA == LOW)
            fileNumber ++;
          else
            fileNumber --;
          }
        else
          {                  // must be LL now
          if (pinA == LOW)  
            fileNumber --;
          else
            fileNumber ++;        
          }
        if (fileNumber > MAX_FILE_NUMBER)
          fileNumber = 0;
        else if (fileNumber < 0)
          fileNumber = MAX_FILE_NUMBER;
        lastFiredTime = millis ();
        fired = true;
        }
        
      ready = false;
      }  // end of being ready
    }  // end of completed click
  else
    ready = true;
    
  pinA = newPinA;
  pinB = newPinB;
    
 }  // end of PCINT2_vect

sorry for delayed reply, for some reason did not get any email notification.
My connection is probably connect, im using filters now. though with one code my setup looked like capacitive antenna. If i get my finder close to encoder i get signal high without touching. Note i do have like 1ft of cable going to encoder.

Picture of wiring attached, along with schematics i used. White Blue + Blue are encoder pins, orange is common pin.
Blue and yellow goes to arduino pins 7,6 (running on MEGA 2560)

I tried all libraries i can and all examples.

For example this one:
from this page: http://arduinotronics.blogspot.com/2013/09/using-rotary-encoder-with-arduino.html

/* interrupt routine for Rotary Encoders


   The average rotary encoder has three pins, seen from front: A C B
   Clockwise rotation A(on)->B(on)->A(off)->B(off)
   CounterCW rotation B(on)->A(on)->B(off)->A(off)

   and may be a push switch with another two pins, pulled low at pin 8 in this case
  

*/

// usually the rotary encoders three pins have the ground pin in the middle
enum PinAssignments {
  encoderPinA = 6,   // right (labeled DT on our decoder, yellow wire)
  encoderPinB = 7,   // left (labeled CLK on our decoder, green wire)
  clearButton = 8    // switch (labeled SW on our decoder, orange wire)
// connect the +5v and gnd appropriately
};

volatile unsigned int encoderPos = 0;  // a counter for the dial
unsigned int lastReportedPos = 1;   // change management
static boolean rotating=false;      // debounce management

// interrupt service routine vars
boolean A_set = false;              
boolean B_set = false;


void setup() {

  pinMode(encoderPinA, INPUT_PULLUP); // new method of enabling pullups
  pinMode(encoderPinB, INPUT_PULLUP); 
  pinMode(clearButton, INPUT_PULLUP);
 // turn on pullup resistors (old method)
  //digitalWrite(encoderPinA, HIGH);
 // digitalWrite(encoderPinB, HIGH);
 // digitalWrite(clearButton, HIGH);

// encoder pin on interrupt 0 (pin 2)
  attachInterrupt(0, doEncoderA, CHANGE);
// encoder pin on interrupt 1 (pin 3)
  attachInterrupt(1, doEncoderB, CHANGE);

  Serial.begin(9600);  // output
}

// main loop, work is done by interrupt service routines, this one only prints stuff
void loop() { 
  rotating = true;  // reset the debouncer

  if (lastReportedPos != encoderPos) {
    Serial.print("Index:");
    Serial.println(encoderPos, DEC);
    lastReportedPos = encoderPos;
  }
  if (digitalRead(clearButton) == LOW )  {
    encoderPos = 0;
  }
}

// Interrupt on A changing state
void doEncoderA(){
  // debounce
  if ( rotating ) delay (1);  // wait a little until the bouncing is done

  // Test transition, did things really change? 
  if( digitalRead(encoderPinA) != A_set ) {  // debounce once more
    A_set = !A_set;

    // adjust counter + if A leads B
    if ( A_set && !B_set ) 
      encoderPos += 1;

    rotating = false;  // no more debouncing until loop() hits again
  }
}

// Interrupt on B changing state, same as A above
void doEncoderB(){
  if ( rotating ) delay (1);
  if( digitalRead(encoderPinB) != B_set ) {
    B_set = !B_set;
    //  adjust counter - 1 if B leads A
    if( B_set && !A_set ) 
      encoderPos -= 1;

    rotating = false;
  }
}

encoder_filter.png

ok crushing my head against the wall i was relly curious why i’m getting so much noise… i looked with oscilloscope and it looked like i have antenna pocking up USB noise, my speakers etc…

after em 5 hours == bread board was defective so i did not have ground.

i will try gain sources i tried, hopefully they work


Update: no luck, tried code posted erlier + one below and nothing still works

I guess will need to write my own as i get readings from clicks if i treat encoder as button

/*
** Rotary Encoder Example
** Use the Sparkfun Rotary Encoder to vary brightness of LED
**
** Sample the encoder at 200Hz using the millis() function
*/

int brightness = 120;    // how bright the LED is, start at half brightness
int fadeAmount = 10;    // how many points to fade the LED by
unsigned long currentTime;
unsigned long loopTime;
const int pin_A = 7;  // pin 12
const int pin_B = 6;  // pin 11
unsigned char encoder_A;
unsigned char encoder_B;
unsigned char encoder_A_prev=0;

void setup()  {
 // declare pin 9 to be an output:
 pinMode(13, OUTPUT);
 pinMode(pin_A, INPUT);
 pinMode(pin_B, INPUT);
 currentTime = millis();
 loopTime = currentTime; 
} 

void loop()  {
 // get the current elapsed time
 currentTime = millis();
 if(currentTime >= (loopTime + 5)){
   // 5ms since last check of encoder = 200Hz  
   encoder_A = digitalRead(pin_A);    // Read encoder pins
   encoder_B = digitalRead(pin_B);   
   if((!encoder_A) && (encoder_A_prev)){
     // A has gone from high to low 
     if(encoder_B) {
       // B is high so clockwise
       // increase the brightness, dont go over 255
       if(brightness + fadeAmount <= 255) brightness += fadeAmount;               
     }   
     else {
       // B is low so counter-clockwise      
       // decrease the brightness, dont go below 0
       if(brightness - fadeAmount >= 0) brightness -= fadeAmount;               
     }   

   }   
   encoder_A_prev = encoder_A;     // Store value of A for next time    
   
   // set the brightness of pin 9:
   analogWrite(9, brightness);   
  
   loopTime = currentTime;  // Updates loopTime
 }
 // Other processing can be done here
                          
}

So non of code worked.... so i wrote my own that some what works but still soft and buggy, but it does detects direction of rotation on each click. Code below....

So i'm still wondering how come all other libraries don't work for me? it should not be possible! What could be wrong with me?

// Declare the pins for the Button and the LED
int Pin_A = 6;
int Pin_B = 7;
int LED = 13;

unsigned int lastReportedPos = 1;   // change management


void setup() {
   pinMode(Pin_A, INPUT);
   pinMode(LED, OUTPUT);

   Serial.begin (9600);
   Serial.println("start");
}

void loop(){

   int ValueA = digitalRead(Pin_A);
   int ValueB = digitalRead(Pin_B);
   
   if (lastReportedPos != ValueA) {
     //Value Change Detected on PinA
     
     //Check Pin A status
     if (ValueA == LOW){
        digitalWrite(LED,HIGH);
        Serial.println("Pin A - LOW");
        lastReportedPos = 0;
     } else {
        digitalWrite(LED, LOW);
        Serial.println("Pin A - HIGH");
        lastReportedPos = 1;
     }   

     //Assuming Pin B changes with pin A at the same time, lets just check state of the pin and print it
     if (ValueB == LOW){
        Serial.println("Pin B - LOW");
     } else {
        Serial.println("Pin B - HIGH");
     } 


     /* OK based on observations 
     A-Low, B-Low to A-High, B-High   ===>  CW
     A-Low, B-High to  A-High, B-Low  ===>  CCW
     */

     //Based on discowered logic, lets count dorections and clicks so we can have something like CW(15) where 15 is number of click detected untill direction change
     //note this gets to my spesific application of controlling motor speed, pretty much like a Gas in RC car

     if (ValueA == LOW && ValueB == LOW){
        //This may be moving in CW direction
        Serial.println("CW");
        
     }

     if(ValueA == LOW && ValueB == HIGH){
        //Lame and lazy... CCW directin? ******** fast speed tuurning makes direction errors, probably need to check previous values too and ignire unknown combinations to avoid probelms
        
        Serial.println("C-CW");
     }
       
   
   }

   
}