Library for decoding quadrature encoders. Uses a ring buffer so you can be sure to process every tick in the order that it happened. This library is not really intended for public use yet and does not have much documentation.

Dependents:   LineFollowing DeadReckoning

Committer:
DavidEGrayson
Date:
Thu Feb 20 18:54:43 2014 +0000
Revision:
1:138f5421c287
Parent:
0:82ccff71d12a
Child:
2:22ac2b4a8012
Stuff;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
DavidEGrayson 0:82ccff71d12a 1 #include <mbed.h>
DavidEGrayson 0:82ccff71d12a 2
DavidEGrayson 1:138f5421c287 3 #define POLOLU_ENCODER_EVENT_INC 0x40
DavidEGrayson 1:138f5421c287 4 #define POLOLU_ENCODER_EVENT_DEC 0x80
DavidEGrayson 1:138f5421c287 5 #define POLOLU_ENCODER_EVENT_ERR 0xC0
DavidEGrayson 0:82ccff71d12a 6
DavidEGrayson 0:82ccff71d12a 7 #define POLOLU_ENCODER_BUFFER_SIZE 256
DavidEGrayson 0:82ccff71d12a 8
DavidEGrayson 0:82ccff71d12a 9 typedef uint8_t PololuEncoderEvent;
DavidEGrayson 0:82ccff71d12a 10
DavidEGrayson 0:82ccff71d12a 11 class PololuEncoderBuffer
DavidEGrayson 0:82ccff71d12a 12 {
DavidEGrayson 0:82ccff71d12a 13 private:
DavidEGrayson 0:82ccff71d12a 14 volatile uint32_t consumerIndex; // The index in the ring buffer that will be consumed next.
DavidEGrayson 0:82ccff71d12a 15 volatile uint32_t producerIndex; // The index in the ring buffer that will be populated next, which is currently empty.
DavidEGrayson 0:82ccff71d12a 16 volatile uint8_t buffer[POLOLU_ENCODER_BUFFER_SIZE];
DavidEGrayson 0:82ccff71d12a 17
DavidEGrayson 0:82ccff71d12a 18 public:
DavidEGrayson 0:82ccff71d12a 19 bool hasEvents() const
DavidEGrayson 0:82ccff71d12a 20 {
DavidEGrayson 0:82ccff71d12a 21 return consumerIndex != producerIndex;
DavidEGrayson 0:82ccff71d12a 22 }
DavidEGrayson 0:82ccff71d12a 23
DavidEGrayson 0:82ccff71d12a 24 bool hasSpace() const
DavidEGrayson 0:82ccff71d12a 25 {
DavidEGrayson 0:82ccff71d12a 26 return ((producerIndex + 1) % POLOLU_ENCODER_BUFFER_SIZE) != consumerIndex;
DavidEGrayson 0:82ccff71d12a 27 }
DavidEGrayson 0:82ccff71d12a 28
DavidEGrayson 0:82ccff71d12a 29 uint8_t readEvent()
DavidEGrayson 0:82ccff71d12a 30 {
DavidEGrayson 0:82ccff71d12a 31 uint8_t event = buffer[consumerIndex];
DavidEGrayson 0:82ccff71d12a 32 consumerIndex = (consumerIndex + 1) % POLOLU_ENCODER_BUFFER_SIZE;
DavidEGrayson 0:82ccff71d12a 33 return event;
DavidEGrayson 0:82ccff71d12a 34 }
DavidEGrayson 0:82ccff71d12a 35
DavidEGrayson 0:82ccff71d12a 36 void writeEvent(uint8_t event)
DavidEGrayson 0:82ccff71d12a 37 {
DavidEGrayson 0:82ccff71d12a 38 buffer[producerIndex] = event;
DavidEGrayson 0:82ccff71d12a 39 producerIndex = (producerIndex + 1) % POLOLU_ENCODER_BUFFER_SIZE;
DavidEGrayson 0:82ccff71d12a 40 }
DavidEGrayson 0:82ccff71d12a 41 };
DavidEGrayson 0:82ccff71d12a 42
DavidEGrayson 0:82ccff71d12a 43 class PololuEncoder
DavidEGrayson 0:82ccff71d12a 44 {
DavidEGrayson 0:82ccff71d12a 45 public:
DavidEGrayson 0:82ccff71d12a 46 PololuEncoder(PinName pinNameA, PinName pinNameB, PololuEncoderBuffer * buffer, uint8_t id)
DavidEGrayson 0:82ccff71d12a 47 : pinA(pinNameA), pinB(pinNameB), buffer(buffer), id(id)
DavidEGrayson 0:82ccff71d12a 48 {
DavidEGrayson 0:82ccff71d12a 49 pinA.mode(PullUp); // TODO: move this to the user code
DavidEGrayson 0:82ccff71d12a 50 pinB.mode(PullUp); // TODO: move this to the user code
DavidEGrayson 0:82ccff71d12a 51
DavidEGrayson 0:82ccff71d12a 52 pinA.rise(this, &PololuEncoder::isr);
DavidEGrayson 0:82ccff71d12a 53 pinA.fall(this, &PololuEncoder::isr);
DavidEGrayson 0:82ccff71d12a 54 pinB.rise(this, &PololuEncoder::isr);
DavidEGrayson 0:82ccff71d12a 55 pinB.fall(this, &PololuEncoder::isr);
DavidEGrayson 1:138f5421c287 56
DavidEGrayson 1:138f5421c287 57 previousState = readState();
DavidEGrayson 0:82ccff71d12a 58 }
DavidEGrayson 0:82ccff71d12a 59
DavidEGrayson 0:82ccff71d12a 60 void isr()
DavidEGrayson 0:82ccff71d12a 61 {
DavidEGrayson 1:138f5421c287 62 uint8_t event = 0;
DavidEGrayson 1:138f5421c287 63 uint8_t newState = readState();
DavidEGrayson 1:138f5421c287 64 switch((previousState << 2) | newState)
DavidEGrayson 0:82ccff71d12a 65 {
DavidEGrayson 1:138f5421c287 66 case 0x1: // 0b0001
DavidEGrayson 1:138f5421c287 67 case 0x7: // 0b0111
DavidEGrayson 1:138f5421c287 68 case 0xE: // 0b1110
DavidEGrayson 1:138f5421c287 69 case 0x8: // 0b1000
DavidEGrayson 1:138f5421c287 70 event = id | POLOLU_ENCODER_EVENT_INC;
DavidEGrayson 1:138f5421c287 71 count += 1;
DavidEGrayson 1:138f5421c287 72 break;
DavidEGrayson 1:138f5421c287 73 case 0x2: // 0b0010
DavidEGrayson 1:138f5421c287 74 case 0xB: // 0b1011
DavidEGrayson 1:138f5421c287 75 case 0xD: // 0b1101
DavidEGrayson 1:138f5421c287 76 case 0x4: // 0b0100
DavidEGrayson 1:138f5421c287 77 event = id | POLOLU_ENCODER_EVENT_DEC;
DavidEGrayson 1:138f5421c287 78 count -= 1;
DavidEGrayson 1:138f5421c287 79 break;
DavidEGrayson 1:138f5421c287 80 case 0x3: // 0b0011
DavidEGrayson 1:138f5421c287 81 case 0x6: // 0b0110
DavidEGrayson 1:138f5421c287 82 case 0x9: // 0b1001
DavidEGrayson 1:138f5421c287 83 case 0xC: // 0b1100
DavidEGrayson 1:138f5421c287 84 event = id | POLOLU_ENCODER_EVENT_ERR;
DavidEGrayson 1:138f5421c287 85 break;
DavidEGrayson 1:138f5421c287 86 }
DavidEGrayson 1:138f5421c287 87 previousState = newState;
DavidEGrayson 1:138f5421c287 88
DavidEGrayson 1:138f5421c287 89 if (event != 0 && buffer->hasSpace())
DavidEGrayson 1:138f5421c287 90 {
DavidEGrayson 1:138f5421c287 91 buffer->writeEvent(event);
DavidEGrayson 0:82ccff71d12a 92 }
DavidEGrayson 0:82ccff71d12a 93 }
DavidEGrayson 1:138f5421c287 94
DavidEGrayson 1:138f5421c287 95 int32_t getCount()
DavidEGrayson 1:138f5421c287 96 {
DavidEGrayson 1:138f5421c287 97 return count;
DavidEGrayson 1:138f5421c287 98 }
DavidEGrayson 1:138f5421c287 99
DavidEGrayson 1:138f5421c287 100 private:
DavidEGrayson 1:138f5421c287 101 uint8_t readState()
DavidEGrayson 1:138f5421c287 102 {
DavidEGrayson 1:138f5421c287 103 return pinA | (pinB << 1);
DavidEGrayson 1:138f5421c287 104 }
DavidEGrayson 1:138f5421c287 105
DavidEGrayson 1:138f5421c287 106 InterruptIn pinA;
DavidEGrayson 1:138f5421c287 107 InterruptIn pinB;
DavidEGrayson 1:138f5421c287 108 PololuEncoderBuffer * buffer;
DavidEGrayson 1:138f5421c287 109 uint8_t previousState;
DavidEGrayson 1:138f5421c287 110 volatile uint8_t id;
DavidEGrayson 1:138f5421c287 111 volatile int32_t count;
DavidEGrayson 0:82ccff71d12a 112 };