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 02:11:00 2014 +0000
Revision:
0:82ccff71d12a
Child:
1:138f5421c287
Got basics working.  When any interrupt fires, it adds an event 0x23 to the buffer.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
DavidEGrayson 0:82ccff71d12a 1 #include <mbed.h>
DavidEGrayson 0:82ccff71d12a 2
DavidEGrayson 0:82ccff71d12a 3 #define POLOLU_ENCODER_EVENT_INC 0b01000000
DavidEGrayson 0:82ccff71d12a 4 #define POLOLU_ENCODER_EVENT_DEC 0b10000000
DavidEGrayson 0:82ccff71d12a 5 #define POLOLU_ENCODER_EVENT_ERR 0b11000000
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 private:
DavidEGrayson 0:82ccff71d12a 46 InterruptIn pinA;
DavidEGrayson 0:82ccff71d12a 47 InterruptIn pinB;
DavidEGrayson 0:82ccff71d12a 48 PololuEncoderBuffer * buffer;
DavidEGrayson 0:82ccff71d12a 49 uint8_t id;
DavidEGrayson 0:82ccff71d12a 50
DavidEGrayson 0:82ccff71d12a 51 public:
DavidEGrayson 0:82ccff71d12a 52 PololuEncoder(PinName pinNameA, PinName pinNameB, PololuEncoderBuffer * buffer, uint8_t id)
DavidEGrayson 0:82ccff71d12a 53 : pinA(pinNameA), pinB(pinNameB), buffer(buffer), id(id)
DavidEGrayson 0:82ccff71d12a 54 // PololuEncoder(PinName pinNameA, PinName pinNameB, uint8_t id)
DavidEGrayson 0:82ccff71d12a 55 // : pinA(pinNameA), pinB(pinNameB), id(id)
DavidEGrayson 0:82ccff71d12a 56 {
DavidEGrayson 0:82ccff71d12a 57 pinA.mode(PullUp); // TODO: move this to the user code
DavidEGrayson 0:82ccff71d12a 58 pinB.mode(PullUp); // TODO: move this to the user code
DavidEGrayson 0:82ccff71d12a 59
DavidEGrayson 0:82ccff71d12a 60 pinA.rise(this, &PololuEncoder::isr);
DavidEGrayson 0:82ccff71d12a 61 pinA.fall(this, &PololuEncoder::isr);
DavidEGrayson 0:82ccff71d12a 62 pinB.rise(this, &PololuEncoder::isr);
DavidEGrayson 0:82ccff71d12a 63 pinB.fall(this, &PololuEncoder::isr);
DavidEGrayson 0:82ccff71d12a 64 }
DavidEGrayson 0:82ccff71d12a 65
DavidEGrayson 0:82ccff71d12a 66 void isr()
DavidEGrayson 0:82ccff71d12a 67 {
DavidEGrayson 0:82ccff71d12a 68 if (buffer->hasSpace())
DavidEGrayson 0:82ccff71d12a 69 {
DavidEGrayson 0:82ccff71d12a 70 buffer->writeEvent(0x23);
DavidEGrayson 0:82ccff71d12a 71 }
DavidEGrayson 0:82ccff71d12a 72 }
DavidEGrayson 0:82ccff71d12a 73 };