simple QEI library. no return speed, only return angle.

Dependents:   WRS_mechanamu_test

QEI.cpp

Committer:
sgrsn
Date:
2020-03-02
Revision:
2:62821df48957
Parent:
0:bffc97496048

File content as of revision 2:62821df48957:

#include "QEI.h"

const int8_t encodeTable[] = {0, -1,  1,  0, 1,  0,  0, -1, -1,  0,  0,  1, 0,  1, -1,  0 };

QEI::QEI(PinName A, PinName B, int ppr) : channelA(A), channelB(B), channelZ(NC)
{
    Timer tmp;
    _timer = &tmp;
    _ppr = ppr;
    init();
}

QEI::QEI(PinName A, PinName B, PinName Z, int ppr) : channelA(A), channelB(B), channelZ(Z)
{
    Timer tmp;
    _timer = &tmp;
    _ppr = ppr;
    init();
    channelZ.rise(this, &QEI::encodeZ);
    channelZ.fall(this, &QEI::encodeZ);
}

QEI::QEI(PinName A, PinName B, int ppr, Timer *timer) : channelA(A), channelB(B), channelZ(NC)
{
    _timer = timer;
    _ppr = ppr;
    init();
}

QEI::QEI(PinName A, PinName B, PinName Z, int ppr, Timer *timer) : channelA(A), channelB(B), channelZ(Z)
{
    _timer = timer;
    _ppr = ppr;
    init();
    channelZ.rise(this, &QEI::encodeZ);
    channelZ.fall(this, &QEI::encodeZ);
}

void QEI::init()
{
    channelA.rise(this, &QEI::encode);
    channelB.rise(this, &QEI::encode);
    channelA.fall(this, &QEI::encode);
    channelB.fall(this, &QEI::encode);
    currState = 0;
    prevState = 0;
    position = 0;
    _IsInterrupt = false;
    
    _timer -> start();
}

float QEI::getDegree()
{
    return float(position) * 360.0/(_ppr*4.0);
}

float QEI::getSpeed()
{
    static float last_time = 0;
    static float last_degree = 0;
    float current_time =_timer -> read();
    float dt = current_time - last_time;
    float current_degree = float(position) * 360.0/(_ppr*4.0);
    float speed = (current_degree - last_degree) / dt;
    last_degree = current_degree;
    last_time = current_time;
    return speed;
}

bool QEI::IsInterruptZ()
{
    bool tmp = _IsInterrupt;
    _IsInterrupt = false;
    return tmp;
}

void QEI::encode(void)
{
    int8_t chanA  = channelA.read();
    int8_t chanB  = channelB.read();
    currState = chanA | (chanB << 1);
    
    if (prevState != currState) {
        position += encodeTable[currState | (prevState<<2)];
        prevState = currState;
    }
}

void QEI::encodeZ()
{
    _IsInterrupt = true;
}