encoder y arduino

30
Incremental Encoders I Hands-On Arduino

Upload: fernando-escalante

Post on 28-Dec-2015

66 views

Category:

Documents


6 download

DESCRIPTION

Tutorial conexion entre arduino y encoder

TRANSCRIPT

Page 1: Encoder y Arduino

Incremental Encoders IHands-On Arduino

Page 2: Encoder y Arduino

Hands On Arduino: Encoders

Overview

• Motion Input!

• Encoder Basics!

• Unidirectional Decoding!

• Bi-Directional Decoding!

• Using Pin Change Interrupts!

• Using Assembly Language

Page 3: Encoder y Arduino

Hands On Arduino: Encoders

How Can We Input Motion?

• We need something that will change when the thing we want to measure moving moves.!

• Generally, something electrical!• Example: Potentiometers

(Resistance Changes)

Page 4: Encoder y Arduino

Hands On Arduino: Encoders

Types of Motion Input• Position!

• Encoder!• Potentiometer!

• Velocity!• Tachometer!• Rate Gyro!• Estimator!

• Acceleration!• Accelerometer

Page 5: Encoder y Arduino

Hands On Arduino: Encoders

What is an Encoder?

• A General concept.!

• Implementation depends on the application!

• Used for!• Data Compression!

• Information Security

Page 6: Encoder y Arduino

Hands On Arduino: Encoders

What does the Encoder Encode?

• Converts a change in position to digital signals.!

• The resolution depends upon the number of pulses in a specified distance!

• If measuring only in one direction, only one “channel” is required.!

• If measuring in both directions, two “channels” are needed: A & B, or I & Q.

Page 7: Encoder y Arduino

Hands On Arduino: Encoders

Pulse Technology

• Magnetic!

• Switch Contacts!

• Optical Reflective!

• Optical Transmissive

Page 8: Encoder y Arduino

Hands On Arduino: Encoders

Encoder & Decoder

DecoderEncoder

Page 9: Encoder y Arduino

Hands On Arduino: Encoders

Absolute Encoders

• Encoders where each position provides a unique “code.”!

• Often based on a Gray code, where the codes for adjacent positions differ by at most 1 bit.!

• No data compression, thus requires n channels.!

• More complicated to work with!

• Exact position is always known.

Page 10: Encoder y Arduino

Hands On Arduino: Encoders

Absolute Encoders• 8 bit absolute encoder disc!

• each ring corresponds to a different bit.!

• The number of PPR is 28 = 256!

• Requires 8 channels!

• only get 1x decoding!

• know where you are at startup!

• Gray code decoding

Page 11: Encoder y Arduino

Hands On Arduino: Encoders

Single Direction: Encode

Number of!Pulses per !Revolution!(PPR): N

1x Resolution: 360°/N!2x Resolution: 180°/N

EmitterDetector

T

T

A

Page 12: Encoder y Arduino

Hands On Arduino: Encoders

Single Direction: Decode

• Count the pulses (1x)!

• Count the transitions (2x)!

• The counting can be done by either:!• polling the channel!

• using the channel to trigger interrupts

An unsigned  long  (uint32_t) is recommended for the!counter!

Page 13: Encoder y Arduino

Hands On Arduino: Encoders

Sample Code: Pollingunsigned  long  count=0;  unsigned  long  timep,  time,  etime;  byte  A,Ap;  !void  setup()  {      Serial.begin(9600);      //connect  Channel  A  to  pin  3      pinMode(3,  INPUT);      //set  the  initial  time          timep  =  micros();        //set  the  initial  value  of  A      Ap  =  digitalRead(3);  }  

void  loop()  {      A  =  digitalRead(3);      if  (A^Ap)//is  there  a  difference?      {          count++;//if  so,  increment.      }      Ap  =  A;      time  =  micros();      etime  =  time  -­‐  timep;      if  (etime  >  1000000)//every  1  sec      {          Serial.println(count);          timep  =  time;//reset  timer      }  }

Page 14: Encoder y Arduino

Hands On Arduino: Encoders

Sample Code: Using Interrupts

unsigned  long  count=0;  unsigned  long  timep,  time,  etime;  void  setup()  {      Serial.begin(9600);      //connect  Channel  A  to  pin  3      pinMode(3,  INPUT);        attachInterrupt(1,transition,  CHANGE);      //set  the  initial  time      timep  =  micros();    }  !void  transition()  {      count++;  }  !

void  loop()  {      time  =  micros();      etime  =  time  -­‐  timep;      if  (etime  >  1000000)//  1  second      {          Serial.println(count);          timep  =  time;  //reset  timer      }  }  

Page 15: Encoder y Arduino

Hands On Arduino: Encoders

Sample Code: Velocity Estimation

//This  displays  the  number  of  transitions  //  per  second.  unsigned  long  count=0;  unsigned  long  timep,  time,  etime;  void  setup()  {      Serial.begin(9600);      //connect  Channel  A  to  pin  3      pinMode(3,  INPUT);        attachInterrupt(1,transition,  CHANGE);      //set  the  initial  time      timep  =  micros();    }  !void  transition()  {      count++;  }  !

void  loop()  {      time  =  micros();      etime  =  time  -­‐  timep;      if  (etime  >  1000000)//  1  second      {          Serial.println(count);          count  =  0;      //reset  the  counter          timep  =  time;  //reset  timer      }  }  

Page 16: Encoder y Arduino

Hands On Arduino: Encoders

Units, Units, Unite!

• Units are essential information for real systems.!

• The units relate to what the relevant quantity is.!

• The encoders have a fixed construction:!• Linear: pulses per inch, pulses per mm!

• Rotary: pulses per revolution.

Page 17: Encoder y Arduino

Hands On Arduino: Encoders

Units, Units, Unite!

• Example: a rotary encoder on a motor shaft with 512 pulses per revolution.!

• Since one revolution equals 360°, then !• for 1x decoding, each count means the motor has turned

360/512 = 0.7031°.!

• for 2x decoding, there are 512x2 = 1024 transitions per revolution, and each count corresponds to 360/1024 = 0.3516°

Page 18: Encoder y Arduino

Hands On Arduino: Encoders

Absolute Encoders

• Encoders where each position provides a unique “code.”!

• Often based on a Gray code, where the codes for adjacent positions differ by at most 1 bit.!

• No data compression, thus requires n channels.

Page 19: Encoder y Arduino

Hands On Arduino: Encoders

BiDirectional Encoding

Emitters Detectors

T

T

T

A

B

1 1

1 1

0 0 1 1 0 0

0 0 1 1 0 0

In-Phase

Quadrature

Page 20: Encoder y Arduino

Hands On Arduino: Encoders

BiDirectional Encoding

Page 21: Encoder y Arduino

Hands On Arduino: Encoders

BiDirectional Encoding

T

T

A

B

1 1

1 1

0 0 1 1 0 0

0 0 1 10 0

state: 1 2 3 4 1 2 3 4

State A B

1 1 1

2 1 0

3 0 0

4 0 1

Page 22: Encoder y Arduino

Hands On Arduino: Encoders

BiDirectional Encoding

A

B

A

B

t

t

t

t

FORWARD:

Reverse

B switches before A

A switches before B

Page 23: Encoder y Arduino

Hands On Arduino: Encoders

BiDirectional (1x) Decoding

• When B = 1, use the transitions of A to determine whether to increment or decrement the counter.

T

T

A

B

1 1

1 1

0 0 1 1 0 0

0 0 1 10 0

state: 1 2 3 4 1 2 3 4

Edge counter

A-­‐rising increment

A-­‐falling decrement

Page 24: Encoder y Arduino

Hands On Arduino: Encoders

BiDirectional (2x) Decoding

T

T

A

B

1 1

1 1

0 0 1 1 0 0

0 0 1 10 0

state: 1 2 3 4 1 2 3 4

B Edge counter

0 A-­‐rising decrement

0 A-­‐falling increment

1 A-­‐falling decrement

1 A-­‐rising increment

Page 25: Encoder y Arduino

Hands On Arduino: Encoders

BiDirectional (4x) Decoding

T

T

A

B

1 1

1 1

0 0 1 1 0 0

0 0 1 10 0

state: 1 2 3 4 1 2 3 4

prior!state

1 2 3 4

present state AB 11 10 00 01

1 11 X dec X inc

2 10 inc X dec X

3 00 X inc x dec

4 01 dec X inc x

X  =  do  nothing.

Page 26: Encoder y Arduino

Hands On Arduino: Encoders

BiDirectional (4x) Decoding

• switch…case !

• if…else…else!

• Array!

• Pin Position

Page 27: Encoder y Arduino

Hands On Arduino: Encoders

BD4x: Switch…Caselong  count=0;  unsigned  long  timep,  time,  etime;  boolean  A,B;  byte  state,  statep;  void  setup()  {      Serial.begin(9600);      pinMode(2,  INPUT);//Channel  A      pinMode(3,  INPUT);//Channel  B      attachInterrupt(0,Achange,CHANGE);      attachInterrupt(1,Bchange,CHANGE);      timep  =  micros();    //set  the  initial  time      //read  the  initial  value  of  A  &  B      A  =  digitalRead(2);        B  =  digitalRead(3);        //set  initial  state  value      if  ((A==HIGH)&&(B==HIGH))  statep  =  1;      if  ((A==HIGH)&&(B==LOW))  statep  =  2;      if  ((A==LOW)&&(B==LOW))  statep  =  3;      if  ((A==LOW)&&(B==HIGH))  statep  =  4;  }

void  loop()  {      time  =  micros();      etime  =  time  -­‐  timep;      if  (etime  >  1000000)      {          Serial.println(count);          timep  =  time;      }  }  

Page 28: Encoder y Arduino

Hands On Arduino: Encoders

BD4x: Switch…Casevoid  Achange()  {      A  =  digitalRead(2);        B  =  digitalRead(3);        //determine  state  value      if  ((A==HIGH)&&(B==HIGH))  state  =  1;      if  ((A==HIGH)&&(B==LOW))  state  =  2;      if  ((A==LOW)&&(B==LOW))  state  =  3;      if  ((A==LOW)&&(B==HIGH))  state  =  4;      switch  (state)      {          case  1:          {              if  (statep  ==  2)  count-­‐-­‐;              if  (statep  ==  4)  count++;              break;          }  

     case  2:          {              if  (statep  ==  1)  count++;              if  (statep  ==  3)  count-­‐-­‐;              break;          }          case  3:          {              if  (statep  ==  2)  count++;              if  (statep  ==  4)  count-­‐-­‐;              break;          }          default:          {              if  (statep  ==  1)  count-­‐-­‐;              if  (statep  ==  3)  count++;          }      }      statep  =  state;  }

Page 29: Encoder y Arduino

Hands On Arduino: Encoders

BD4x: Array

State prior 0 1 2 3

present AB 11 10 00 010 11 X dec X inc1 10 inc X dec X2 00 X inc x dec3 01 dec X inc x

Quadrature  Encoder  Matrix  (Array):    

QEM[16]  =  {0,-­‐1,0,1,1,0,-­‐1,0,0,1,0,-­‐1,-­‐1,0,1,0}

Index  =  4*state  +  statep;count  =  count  +  QEM[Index];

Page 30: Encoder y Arduino

Hands On Arduino: Encoders

BD4x: Arrayvoid  Achange()  {      A  =  digitalRead(2);        B  =  digitalRead(3);        //determine  state  value      if  ((A==HIGH)&&(B==HIGH))  state  =  0;      if  ((A==HIGH)&&(B==LOW))  state  =  1;      if  ((A==LOW)&&(B==LOW))  state  =  2;      if  ((A==LOW)&&(B==HIGH))  state  =  3;      index  =  4*state  +  statep;      count  =  count  +  QEM[index];      statep  =  state;  }  

void  Bchange()  {      A  =  digitalRead(2);        B  =  digitalRead(3);        //determine  state  value      if  ((A==HIGH)&&(B==HIGH))  state  =  0;      if  ((A==HIGH)&&(B==LOW))  state  =  1;      if  ((A==LOW)&&(B==LOW))  state  =  2;      if  ((A==LOW)&&(B==HIGH))  state  =  3;      index  =  4*state  +  statep;      count  =  count  +  QEM[index];      statep  =  state;  }