Go Down

Topic: (still) unable to read an encoder (Read 850 times) previous topic - next topic

leo_groeneveld

Jun 02, 2014, 07:12 pm Last Edit: Jun 02, 2014, 07:18 pm by mechatron Reason: 1
Hi,

After thinking about a good code I "came up" with the following code:

Code: [Select]

#define encoder0PinA 2

volatile int val = 0;
volatile int PinB = 3;

void setup()
{
 pinMode(encoder0PinA, INPUT);
 pinMode(PinB, INPUT);
 attachInterrupt(0, doEncoderA, CHANGE);  // encoder pin on interrupt 0 (pin 2)
 Serial.begin (9600);
 Serial.print("Encoderpositie = ");
 Serial.println(val);
}

void loop()
{
//Do stuff here
}

void doEncoderA()
{
 if ((encoder0PinA == HIGH) && (PinB == LOW))
   {
     val = val + 1;
   }
 else
   {
     if ((encoder0PinA == HIGH) && (PinB == HIGH))
       {
         val = val - 1;
       }
     else
       {
         if ((encoder0PinA == LOW) && (PinB == HIGH))
           {
             val = val + 1;
           }
         else
           {
             if ((encoder0PinA == LOW) && (PinB == LOW))
             {
             val = val -1;
             }
           }}}
Serial.print("Encoderpositie = ");            
Serial.println(val);          
}


I now think this isn't such a good code after all.

This is what happens:



After rotating for a short while the uC crashes and stalls.

This is the setup I use. I'm using a stock rotary encoder. The resistors are pull down resistors.



2 problems so far
1) the code stalls
2) as long/short as the code is working no adding or subtraction

In my mind the code should be ok?

What am I missing?

Leo
to boldly code what no man has coded before

wildbill

Code: [Select]
  if ((encoder0PinA == HIGH) && (PinB == LOW))


encoder0PinA and PinB are pin numbers, they don't represent the state of the pins; you need digitalRead.

Serial print commands shouldn't be in your interrupt routine - move them to loop.

leo_groeneveld

#2
Jun 02, 2014, 07:53 pm Last Edit: Jun 02, 2014, 08:14 pm by mechatron Reason: 1
Ok, thanks.

I have changed the code and the code doesn't stall anymore.
I also receive different numbers now instead of only zero's.

Code: [Select]

#define encoder0PinA 2

volatile int val = 0;
volatile int PinB = 3;
volatile int valA;
volatile int valB;
int valold;

void setup()
{
 pinMode(encoder0PinA, INPUT);
 pinMode(PinB, INPUT);
 digitalWrite(encoder0PinA, HIGH);
 digitalWrite(PinB, HIGH);
 attachInterrupt(0, doEncoderA, CHANGE);  // encoder pin on interrupt 0 (pin 2)
 Serial.begin (9600);
 Serial.print("Encoderpositie = ");
 Serial.println(val);
 valold = val;
}

void loop()
{
if (valold != val)
 {
   Serial.print("Encoderpositie = ");            
   Serial.println(val);
   valold = val;  
 }
}

void doEncoderA()
{
valA = digitalRead(encoder0PinA);
valB = digitalRead(PinB);
 if ((valA == HIGH) && (valB == LOW))
   {
     val = val + 1;
   }
 else
   {
     if ((valA == HIGH) && (valB == HIGH))
       {
         val = val - 1;
       }
     else
       {
         if ((valA == LOW) && (valB == HIGH))
           {
             val = val + 1;
           }
         else
           {
             if ((valA == LOW) && (valB == LOW))
             {
             val = val -1;
             }
           }}}  
}


But the numbers are erratic. The trends seem to be ok (overall rising or falling numbers) but not every step gives the same difference. The differences can be really high (higher then some missed values by the serial monitor). Sometimes the trend can even shortly reverse while rotating in one direction???

Why is it so hard to read an encoder?

EDIT:
I have added two 0,1 uF capacitors between the A and B and ground and it seems to be a bit better now. (maybe it's only better in my mind but I have a feeling it really is a bit better now) Maybe the erratic behaviour is caused by bouncing?
to boldly code what no man has coded before

MarkT

For a phototransistor output encoder you have to provide the right
value of pull up resistor, the built-in pullups may be too high.

You might need schmidt-triggers to cleanup the signals too.

An oscilloscope would help a lot, but static readings with a mutimeter
may be useful too.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

raschemmel

Post a schematic of your wiring with labels for the pins.
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

leo_groeneveld

#5
Jun 03, 2014, 05:30 am Last Edit: Jun 03, 2014, 05:34 am by mechatron Reason: 1


This is how the setup is made.
to boldly code what no man has coded before

raschemmel

Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

Go Up