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:
Sat Feb 22 02:23:06 2014 +0000
Revision:
3:a2dd8d8bde4c
Parent:
2:22ac2b4a8012
stuff;

Who changed what in which revision?

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