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); }