RPM measurement with encoder sensor.

Dependencies:   CenteredPwmOut MODSERIAL ThreePhaseBridge mbed tsi_sensor

main.cpp

Committer:
acracan
Date:
2014-07-08
Revision:
1:9859d09037e2
Parent:
0:c3b35a017390

File content as of revision 1:9859d09037e2:

#include "mbed.h"
#include "ThreePhaseBridge.h"
#include "tsi_sensor.h"
#include "MODSERIAL.h"

/* This defines will be replaced by PinNames soon */
#if defined (TARGET_KL25Z) || defined (TARGET_KL46Z)
  #define ELEC0 9
  #define ELEC1 10
#elif defined (TARGET_KL05Z)
  #define ELEC0 9
  #define ELEC1 8
#else
  #error TARGET NOT DEFINED
#endif


const int maxRpm = 6500;
const int pulseWidthRpmThreshold = 1500;
const float minPulseWidth = 3e-6;
const float pulseWidthScaleFactor = 11.2e-6;
const float pwmPeriod = 33.35e-6;
const int tsiReadPeriod = 10000;
const int pcUpdatePeriod = 1000000;

ThreePhaseBridge bridge(
    PTD3,   /* SW1 */
    PTC11,  /* SW2 */
    PTC8,   /* SW3 */
    PTC12,  /* SW4 */
    PTC9,   /* SW5 */
    PTC13,  /* SW6 */
    ThreePhaseBridge::ActiveLow
);

Timer motorSpinTimer;
int motorSpinPeriod = 6000;
int motorRpm = 1500;

MODSERIAL pc(USBTX, USBRX);
Timer pcUpdateTimer;

InterruptIn rpmSig(D5);
Timer rpmSigTimer;
int rpmSigPeriod = 0;

TSIAnalogSlider tsi(ELEC0, ELEC1, 40);
Timer tsiReadTimer;

void onRpmSigRisingEdge();
void motorSpin();
void readSlider();
void pcStatusUpdate();

int main() {
    bridge.period(pwmPeriod);
    bridge.pulsewidth(minPulseWidth);
    motorSpinTimer.start();
//    bridge.overflow();
    rpmSig.mode(PullNone);
    rpmSig.rise(onRpmSigRisingEdge);
    rpmSigTimer.start();
    tsiReadTimer.start();
    pcUpdateTimer.start();
    
    while(1) {
        motorSpin();
        readSlider();
        pcStatusUpdate();
    }
}

float pulseWidthValue(int rpm)
{
    if (rpm < pulseWidthRpmThreshold)
        return minPulseWidth;
    return minPulseWidth + pulseWidthScaleFactor * (rpm - pulseWidthRpmThreshold) / (maxRpm - pulseWidthRpmThreshold);
}

int rpmToSpinPeriod(int rpm)
{
    return 10000000 / rpm;
}

void onRpmSigRisingEdge()
{
    static int queue[16], queueStart = 0, queueEnd = 0;
    static uint64_t sum = 0;
    int time;
    
    time = rpmSigTimer.read_us();
    rpmSigTimer.reset();
    if (queueStart == queueEnd && sum != 0) {
        sum -= queue[queueStart];
        queueStart = (queueStart + 1) & 15;
    }
    sum += time;
    queue[queueEnd] = time;
    queueEnd = (queueEnd + 1) & 15;
    
    if (queueStart == queueEnd)
        rpmSigPeriod = sum / 16;
    else
        rpmSigPeriod = sum / ((queueEnd + 16 - queueStart) & 15);
}

void motorSpin()
{
    if (motorSpinTimer.read_us() < motorSpinPeriod)
        return;
    motorSpinTimer.reset();
    bridge.spin(ThreePhaseBridge::CW);
}

void readSlider()
{
    if (tsiReadTimer.read_us() < tsiReadPeriod)
        return;
    tsiReadTimer.reset();
    motorRpm = 1500 + (tsi.readPercentage()) * 5000;
    motorSpinPeriod = rpmToSpinPeriod(motorRpm);
}

void pcStatusUpdate()
{
    if (pcUpdateTimer.read_us() < pcUpdatePeriod)
        return;
    pcUpdateTimer.reset();
//    pc.printf("RPM: %d\n\r", motorRpm);
//    pc.printf("Sensor: %d\n\r", 60000000/ (rpmSigPeriod * 10) );
    pc.printf("Ref period: %d\n\r", motorSpinPeriod * 6);
    pc.printf("Sensor period: %d\n\r", rpmSigPeriod * 10 / 7);
}