Library for driving a motor with one PWM and one DIR signal using PI control.

Fork of Motor2 by Reiko Randoja

Revision:
8:63a67086a1b5
Parent:
5:99fa6dffea40
Child:
9:bec5a728405f
diff -r fbd3fa0445e5 -r 63a67086a1b5 motor.cpp
--- a/motor.cpp	Tue Sep 17 22:52:10 2013 +0000
+++ b/motor.cpp	Thu Sep 19 13:08:56 2013 +0000
@@ -7,7 +7,7 @@
     pwm.period_ms(1);
     setPoint = 0;
     pMulti = 16;
-    iDiv = 1;
+    iDiv = 2;
     dMulti = 1;
     error = 0;
     prevError = 0;
@@ -15,13 +15,16 @@
     I = 0;
     minPwm = 100;
     pidMulti = 128;
-    iMax = 512 * pidMulti;
+    iMax = 1024 * pidMulti;
     
     currentSpeed = 0;
     
     currentPWM = 0;
-    stallCounter = 0;
-    stallCounterLimit = 60;
+    stallCount = 0;
+    prevStallCount = 0;
+    stallWarningLimit = 60;
+    stallErrorLimit = 300;
+    stallLevel = 0;
 }
 
 void Motor::setPWM(int newPWM) {
@@ -53,44 +56,66 @@
     }
 }
 
-void Motor::pid() {    
+void Motor::pid() {
     prevError = error;
     error = setPoint - getDecoderCount();
-    
-    //float err = (float)error / 250.0;
-    float minPwmValue = minPwm;
-    
-    if (setPoint == 0) {
-        minPwmValue = 0;
-    } else if (setPoint < 0) {
-        minPwmValue = -minPwm;
-    }
-    
-    I += error * pidMulti / iDiv;
-    //constrain integral
-    if (I < -iMax) I = -iMax;
-    if (I > iMax) I = iMax;
-    
-    //D = error - prevError;
+
+    if (stallLevel != 2) {
+        
+        //float err = (float)error / 250.0;
+        float minPwmValue = minPwm;
+        
+        if (setPoint == 0) {
+            minPwmValue = 0;
+        } else if (setPoint < 0) {
+            minPwmValue = -minPwm;
+        }
+        
+        I += error * pidMulti / iDiv;
+        //constrain integral
+        if (I < -iMax) I = -iMax;
+        if (I > iMax) I = iMax;
+        
+        //D = error - prevError;
+        
+        //float newPWMvalue = minPwmValue + error * pMulti + I + dMulti * D;
+        int newPWMvalue = minPwmValue + error * pMulti + I / pidMulti;
     
-    //float newPWMvalue = minPwmValue + error * pMulti + I + dMulti * D;
-    int newPWMvalue = minPwmValue + error * pMulti + I / pidMulti;
-
-    //constrain pwm
-    if (newPWMvalue < -1000) newPWMvalue = -1000;
-    if (newPWMvalue > 1000) newPWMvalue = 1000;
-    
-    /*if ((currentSpeed < 5 && currentPWM == 1000 || currentSpeed > -5 && currentPWM == -1000) && stallCounter < stallCounterLimit) {
-        stallCounter++;
-    } else if (stallCounter > 0) {
-        stallCounter++;
+        //constrain pwm
+        if (newPWMvalue < -1000) newPWMvalue = -1000;
+        if (newPWMvalue > 1000) newPWMvalue = 1000;    
+        
+        prevStallCount = stallCount;
+        if ((currentSpeed < 5 && currentPWM == 1000 || currentSpeed > -5 && currentPWM == -1000) && 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();
+        }
     }
-    
-    if (stallCounter == stallCounterLimit) {
-        
-    }*/
-    
-    setPWM(newPWMvalue);
 }
 
 void Motor::resetPID() {
@@ -102,6 +127,18 @@
     setPWM(0);
 }
 
+int Motor::getStallLevel() {
+    return stallLevel;
+}
+
+void Motor::stallChange(void (*function)(void)) { 
+    stallChangeCallback.attach(function);
+}
+
+void Motor::stallEnd(void (*function)(void)) { 
+    stallEndCallback.attach(function);
+}
+
 void Motor::stallWarning(void (*function)(void)) { 
     stallWarningCallback.attach(function);
 }