Incremental Rotary Encoder 400P/R

Hi guys !

I have a rotary encoder,samethink like this
http://www.ebay.com/itm/Encoder-400P-R-Incremental-Rotary-Encoder-400p-r-AB-phase-encoder-6mm/121355244021?_trksid=p2047675.c100005.m1851&_trkparms=aid%3D222007%26algo%3DSIC.MBE%26ao%3D1%26asc%3D27538%26meid%3D0518b865ab324b72b2f5447b0b43d145%26pid%3D100005%26prg%3D11353%26rk%3D1%26rkt%3D6%26sd%3D221379149398&rt=nc

I would like to display on LCD the number of pulses after title “LEG”.
i have try this code

/* Read Quadrature Encoder
  * Connect Encoder to Pins encoder0PinA, encoder0PinB, and +5V.
  *
  * Sketch by max wolf / www.meso.net
  * v. 0.1 - very basic functions - mw 20061220
  *
  */  

const int poten_pin=0;
int Input_val=0;

 int encoder0PinA = 8;
 int encoder0PinB = 9  ;
 int encoder0Pos = 0;
 int encoder0PinALast = LOW;
 int n = LOW;
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

 void setup() { 
   lcd.begin(16, 2);
   pinMode (encoder0PinA,INPUT);
   pinMode (encoder0PinB,INPUT);
   
   Serial.begin (9600);
   lcd.setCursor(0, 1);
   lcd.print("LEG:");
   lcd.setCursor(0, 0);
   lcd.print("DEG:");
   
 } 

 void loop() { 
   Input_val=analogRead(poten_pin);
   n = digitalRead(encoder0PinA);
    lcd.setCursor(4, 0);
    
     lcd.print(Input_val);
   if ((encoder0PinALast == LOW) && (n == HIGH)) {
     if (digitalRead(encoder0PinB) == LOW) {
       encoder0Pos--;
     } else {
       encoder0Pos++;
      
     }
     
     Serial.print (encoder0Pos);
 
     Serial.print ("/");
     lcd.setCursor(4, 1);
     
     lcd.print(encoder0Pos);
    
      delay(5);
   } 
   encoder0PinALast = n;
 }

seems to work fine when i rotate very slow.But when speed up dont count or lose count.
You think 400P/R are too many for arduino or i can do somethink with the code?

thanks

What happens is just what is to be expected. Your code blocks the cpu so that it is missing pulses. There are a number of culprits here.

The analog read The serial and lcd print commands The delay()

All of these are quite time consuming

hi you have to use the interrupts pin 2 and pin 3

stefa24: hi you have to use the interrupts pin 2 and pin 3

that do you mean interrupts pin 2,3 i cant use pin 8,9 that i want ? can you post me an example?

thanks for replay!

hi
arduino’s playground can show you some example
http://playground.arduino.cc/Main/RotaryEncoders
you can try this simple sketch

//valido per contare con interrupt

//#include <LiquidCrystal.h>
//LiquidCrystal lcd(9, 8, 7, 6, 5, 4);

#define encoder0PinA 2
volatile int count, countold;

void setup()
{
  count = 0;
  countold = 0; 
  //lcd.begin(16,4); // set up the LCD's number of columns and rows:

  // statosensore1=HIGH;  //stato iniziale del sensore
  pinMode(encoder0PinA, INPUT_PULLUP); 
  attachInterrupt(0, sensore1, FALLING); //sensore induttivo collegato al pin 2
  //   lcd.clear();
  Serial.begin(115200); // initialize serial communication:

}

void loop()
{
  if (countold != count)
  {

    //lcd.home();
    //lcd.print(count);
    //delay(500);

    Serial.println(count);
    //lcd.clear();
    //lcd.print(count);
    countold = count;
  }
}

void sensore1()
{
  count++;
}

stefa24: hi you have to use the interrupts pin 2 and pin 3

i saw what you mean. tryed pin 2 and 3.Now i can turn it little faster.

stefa24:
hi
arduino’s playground can show you some example
http://playground.arduino.cc/Main/RotaryEncoders
you can try this simple sketch

//valido per contare con interrupt

//#include <LiquidCrystal.h>
//LiquidCrystal lcd(9, 8, 7, 6, 5, 4);

#define encoder0PinA 2
volatile int count, countold;

void setup()
{
  count = 0;
  countold = 0;
  //lcd.begin(16,4); // set up the LCD’s number of columns and rows:

// statosensore1=HIGH;  //stato iniziale del sensore
  pinMode(encoder0PinA, INPUT_PULLUP);
  attachInterrupt(0, sensore1, FALLING); //sensore induttivo collegato al pin 2
  //  lcd.clear();
  Serial.begin(115200); // initialize serial communication:

}

void loop()
{
  if (countold != count)
  {

//lcd.home();
    //lcd.print(count);
    //delay(500);

Serial.println(count);
    //lcd.clear();
    //lcd.print(count);
    countold = count;
  }
}

void sensore1()
{
  count++;
}

thanks for replay
your code is fast enough,but only count plus!

I use that code only to test the encoder

stefa24: I use that code only to test the encoder

coul you suggest me an example or code that full works?

I have never used all encoder signal. Did you see the arduino's playground? below a sketch from playground

Interrupt Example (the Encoder interrupts the processor). Uses both Interrupt pins

Code for reading encoder using 2 interrupts on pin 2 & pin3

Note: the code below uses 2 interrupts to read the full resolution of the encoder. The code above used 1 interrupt. It read half the resolution by only checking EncoderPin A for position, but it freed up an interrupt pin.

#define encoder0PinA 2

#define encoder0PinB 3

volatile unsigned int encoder0Pos = 0;

void setup() {

  pinMode(encoder0PinA, INPUT); 
  pinMode(encoder0PinB, INPUT); 
// 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);
}

void loop(){ //Do stuff here }

void doEncoderA(){

  // look for a low-to-high on channel A
  if (digitalRead(encoder0PinA) == HIGH) { 
    // check channel B to see which way encoder is turning
    if (digitalRead(encoder0PinB) == LOW) {  
      encoder0Pos = encoder0Pos + 1;         // CW
    } 
    else {
      encoder0Pos = encoder0Pos - 1;         // CCW
    }
  }
  else   // must be a high-to-low edge on channel A                                       
  { 
    // check channel B to see which way encoder is turning  
    if (digitalRead(encoder0PinB) == HIGH) {   
      encoder0Pos = encoder0Pos + 1;          // CW
    } 
    else {
      encoder0Pos = encoder0Pos - 1;          // CCW
    }
  }
  Serial.println (encoder0Pos, DEC);          
  // use for debugging - remember to comment out
}

void doEncoderB(){

  // look for a low-to-high on channel B
  if (digitalRead(encoder0PinB) == HIGH) {   
   // check channel A to see which way encoder is turning
    if (digitalRead(encoder0PinA) == HIGH) {  
      encoder0Pos = encoder0Pos + 1;         // CW
    } 
    else {
      encoder0Pos = encoder0Pos - 1;         // CCW
    }
  }
  // Look for a high-to-low on channel B
  else { 
    // check channel B to see which way encoder is turning  
    if (digitalRead(encoder0PinA) == LOW) {   
      encoder0Pos = encoder0Pos + 1;          // CW
    } 
    else {
      encoder0Pos = encoder0Pos - 1;          // CCW
    }
  }
}

stefa 24 thank you for replays

tryed some code from playground but still lose steps

code you post,when turn minus start count from 65534 64535 64536

also when go little faster for one time then program stop working.

any ideas?

If you are using unsigned 16 bit integers, then -1 is the same as 65535. If this is going to be a problem for you, then use signed integers.

 Serial.println (encoder0Pos, DEC);          
  // use for debugging - remember to comment out

Did you remember to comment out the serial print?

Paulcet: Serial.println (encoder0Pos, DEC);            // use for debugging - remember to comment out

Did you remember to comment out the serial print?

thanks for replay

sorry but i cant understand "comment out the serial print"

could you help a bit?

thanks

try

//Serial.println (encoder0Pos, DEC);

I posted this code in another thread. It might help you.

const char encTable[16] ={0, 1, -1, -0, -1, 0, -0, 1, 1, -0, 0, -1, -0, -1, 1, 0};//gives -1, 0 or 1 depending on encoder movement
byte encState;//remembering the encoder output and acting as index for encTable[]
byte inp;
volatile long actPos;//encoder position


void setup(){
    Serial.begin(115200);
    attachInterrupt(0, updateEnc, CHANGE);//monitor pin 2
    attachInterrupt(1, updateEnc, CHANGE);//monitor pin 3
}//setup()

void loop(){
  Serial.println(actPos);//report positioin twice a second
  delay(500);
}//loop()

void updateEnc(){
  encState = ((encState<<2)|((PIND>>2)&3))&15;//use encoder bits and last state to form index
  actPos += encTable[encState];//update actual position on encoder movement
}//updateEnc()

Hi nilton61

thank for replay.

the code work very nice,its fast enought.

thanks a lot.