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

PololuEncoder.h

Committer:
DavidEGrayson
Date:
2014-02-20
Revision:
0:82ccff71d12a
Child:
1:138f5421c287

File content as of revision 0:82ccff71d12a:

#include <mbed.h>

#define POLOLU_ENCODER_EVENT_INC  0b01000000
#define POLOLU_ENCODER_EVENT_DEC  0b10000000
#define POLOLU_ENCODER_EVENT_ERR  0b11000000

#define POLOLU_ENCODER_BUFFER_SIZE 256

typedef uint8_t PololuEncoderEvent;

class PololuEncoderBuffer
{
    private:
    volatile uint32_t consumerIndex;  // The index in the ring buffer that will be consumed next.
    volatile uint32_t producerIndex;  // The index in the ring buffer that will be populated next, which is currently empty.
    volatile uint8_t buffer[POLOLU_ENCODER_BUFFER_SIZE];

    public:
    bool hasEvents() const
    {
        return consumerIndex != producerIndex;
    }
    
    bool hasSpace() const
    {
        return ((producerIndex + 1) % POLOLU_ENCODER_BUFFER_SIZE) != consumerIndex;
    }
    
    uint8_t readEvent()
    {
        uint8_t event = buffer[consumerIndex];
        consumerIndex = (consumerIndex + 1) % POLOLU_ENCODER_BUFFER_SIZE;
        return event;
    }
    
    void writeEvent(uint8_t event)
    {
        buffer[producerIndex] = event;
        producerIndex = (producerIndex + 1) % POLOLU_ENCODER_BUFFER_SIZE;    
    }
};

class PololuEncoder
{
    private:
    InterruptIn pinA;
    InterruptIn pinB;
    PololuEncoderBuffer * buffer;
    uint8_t id;
    
    public:
    PololuEncoder(PinName pinNameA, PinName pinNameB, PololuEncoderBuffer * buffer, uint8_t id)
      : pinA(pinNameA), pinB(pinNameB), buffer(buffer), id(id)
//    PololuEncoder(PinName pinNameA, PinName pinNameB, uint8_t id)
//      : pinA(pinNameA), pinB(pinNameB), id(id)
    {
        pinA.mode(PullUp);        // TODO: move this to the user code
        pinB.mode(PullUp);        // TODO: move this to the user code
        
        pinA.rise(this, &PololuEncoder::isr);
        pinA.fall(this, &PololuEncoder::isr);
        pinB.rise(this, &PololuEncoder::isr);
        pinB.fall(this, &PololuEncoder::isr);
    }
    
    void isr()
    {
        if (buffer->hasSpace())
        {
            buffer->writeEvent(0x23);
        }
    }
};