Allegro A3930 BLDC driver
a3930.cpp
- Committer:
- Reiko
- Date:
- 2013-11-10
- Revision:
- 1:464cd2cb852e
- Parent:
- 0:a6123d12f08b
File content as of revision 1:464cd2cb852e:
#include "a3930.h" A3930::A3930(PinName PWMpin, PCA9555 *ioExt, unsigned int dirPin, unsigned int brakePin, unsigned int coastPin, PinName tachoPin, PinName diroPin) : pwm(PWMpin), extIO(ioExt), dirPinNumber(dirPin), brakePinNumber(brakePin), coastPinNumber(coastPin), interruptTacho(tachoPin), interruptDiro(diroPin) { pwmPeriod = 1.0f / 50000.0f; PwmOut pwm(PWMpin); pwm.period(pwmPeriod); setPoint = 0; pMulti = 0.8; iMulti = 0.1; dMulti = 0.01; error = 0; prevError = 0; P = 0; I = 0; minPwm = 0.5; currentSpeed = 0; currentPWM = 0; stallCount = 0; prevStallCount = 0; stallWarningLimit = 60; stallErrorLimit = 300; stallLevel = 0; extIO->setPin(brakePinNumber); extIO->setPin(coastPinNumber); extIO->clearPin(dirPinNumber); /*interruptDiro.rise(this, &A3930::diroRise); interruptDiro.fall(this, &A3930::diroFall);*/ interruptTacho.rise(this, &A3930::tachoChanged); interruptTacho.fall(this, &A3930::tachoChanged); interruptDiro.attach_asserted(this, &A3930::diroRise); interruptDiro.attach_deasserted(this, &A3930::diroFall); /*interruptTacho.attach_asserted(this, &A3930::tachoChanged); interruptTacho.attach_deasserted(this, &A3930::tachoChanged);*/ interruptDiro.setSamplesTillAssert(3); //interruptTacho.setSamplesTillAssert(2); interruptDiro.setSampleFrequency(500); //interruptTacho.setSampleFrequency(1000); } void A3930::setPWM(float newPWM) { currentPWM = newPWM; if (newPWM < -0.5) { pwm = -1 * newPWM; extIO->setPin(dirPinNumber); //extIO->setPin(coastPinNumber); extIO->setPin(brakePinNumber); } else if (newPWM > 0.5) { pwm = newPWM; extIO->clearPin(dirPinNumber); //extIO->setPin(coastPinNumber); extIO->setPin(brakePinNumber); } else { extIO->clearPin(brakePinNumber); } } void A3930::setRawPWM(float newPWM) { currentPWM = newPWM; pwm = newPWM; } int A3930::getSpeed() { return currentSpeed; } int A3930::getDecoderCount() { currentSpeed = pulses; pulses = 0; return currentSpeed; } void A3930::diroRise() { diro = 1; } void A3930::diroFall() { diro = 0; } void A3930::tachoChanged() { if (diro) { pulses++; } else { pulses--; } } void A3930::setSpeed(int newSpeed) { setPoint = newSpeed; if (newSpeed == 0) { resetPID(); } } void A3930::pid() { prevError = error; error = setPoint - getDecoderCount(); if (stallLevel != 2) { float err = (float)error / 100.0; float minPwmValue = minPwm; if (setPoint == 0) { minPwmValue = 0; } else if (setPoint < 0) { minPwmValue = -minPwm; } I += err * iMulti; //constrain integral if (I < -1) I = -1; if (I > 1) I = 1; float newPWMvalue = minPwmValue + err * pMulti + I; //constrain pwm if (newPWMvalue < -1) newPWMvalue = -1; if (newPWMvalue > 1) newPWMvalue = 1; prevStallCount = stallCount; if ((currentSpeed < 5 && currentPWM == 1 || currentSpeed > -5 && currentPWM == -1) && stallCount < stallErrorLimit) { stallCount++; } else if (stallCount > 0) { stallCount--; } setPWM(newPWMvalue); if ((stallCount == stallWarningLimit - 1) && (prevStallCount == stallWarningLimit)) { stallLevel = 0; stallEndCallback.call(); stallChangeCallback.call(); } else if ((stallCount == stallWarningLimit) && (prevStallCount == stallWarningLimit - 1)) { stallLevel = 1; stallWarningCallback.call(); stallChangeCallback.call(); } else if (stallCount == stallErrorLimit) { stallLevel = 2; stallErrorCallback.call(); stallChangeCallback.call(); resetPID(); } } else { stallCount--; if (stallCount == 0) { stallLevel = 0; stallEndCallback.call(); stallChangeCallback.call(); } } } void A3930::resetPID() { error = 0; prevError = 0; P = 0; I = 0; setPoint = 0; setPWM(0); } int A3930::getStallLevel() { return stallLevel; } void A3930::stallChange(void (*function)(void)) { stallChangeCallback.attach(function); } void A3930::stallEnd(void (*function)(void)) { stallEndCallback.attach(function); } void A3930::stallWarning(void (*function)(void)) { stallWarningCallback.attach(function); } void A3930::stallError(void (*function)(void)) { stallErrorCallback.attach(function); }