PID Based Motor Controller Code

Dependencies:   QEI Servo mbed

Files at this revision

API Documentation at this revision

Comitter:
taoqiuyang
Date:
Tue Apr 18 23:58:28 2017 +0000
Commit message:
PID_Based_Motor_Controller_Code

Changed in this revision

QEI.lib Show annotated file Show diff for this revision Revisions of this file
Servo.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 8bded3c460c7 QEI.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/QEI.lib	Tue Apr 18 23:58:28 2017 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/aberk/code/QEI/#5c2ad81551aa
diff -r 000000000000 -r 8bded3c460c7 Servo.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Servo.lib	Tue Apr 18 23:58:28 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/simon/code/Servo/#36b69a7ced07
diff -r 000000000000 -r 8bded3c460c7 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Apr 18 23:58:28 2017 +0000
@@ -0,0 +1,141 @@
+/*
+Simple PID-based Motor RPM Controller
+Purpose:    This code reads motor RPM with encoder, 
+            generate ESC-compatible control signal with PID controller
+            
+Note:   LED1: System Status Indicator, Blink = Main Loop is Running
+        LED2: Controller Timer Indicator, Blink = Controller is Updating        
+        ESC is connected to Pin 26
+        Encoder is connected to Pin29,Pin30, and Pin27 if has index channel
+        PID gains:  Kp, Ki, Kd
+
+Caution: This is a simple test code, no guarantee to performance or robustness 
+      
+Author: Qiuyang Tao
+*/
+ 
+#include "mbed.h"
+#include "Servo.h"
+#include "QEI.h"
+#define PULSE_PER_REV 200
+  
+Ticker ctrl_updt_timer;     //Timer
+Servo motor_ESC(p26);       //ESC is connected to Pin 26
+Serial pc(USBTX, USBRX);    //debug serial
+QEI wheel (p29, p30, NC, PULSE_PER_REV);  // <500,000 pulses per second//Use X4 encoding.
+//QEI wheel (p29, p30, p27, PULSE_PER_REV); // If encoder has index channel 
+
+//All LEDs Blinks at start up, indicates mbed is setting up ESC
+DigitalOut led1(LED1); //System Status Indicator, Blink = Main Loop is Running
+DigitalOut led2(LED2); //Controller Status Indicator, Blink = Controller is Updating  
+DigitalOut led3(LED3); //Controller Status Indicator, On = Motor RPM < Desired RPM
+//                                                         Motor is Aaccelerating
+//                                                   Off = Motor RPM > Desired RPM
+//                                                         Motor is De-Aaccelerating
+DigitalOut led4(LED4); //Encoder Counter Overflow
+
+
+//PID Related Variables - User 
+float setpoint_rpm=10000;   //Desired RPM = 10,000
+float dt=0.02; //Update Controller at 50Hz
+float Kp=0;
+float Ki=0;
+float Kd=0;
+
+
+//PID Related Variables 
+float error_rpm=0;
+float prev_error_rpm=0;
+float u=0;  //controller output, range = [0,1]
+float u_p=0;
+float u_i=0;
+float u_d=0;
+
+//Global Variables - User
+int use_index_channel=0;
+
+//use Unsigned long long if overflows frequently
+//unsigned long long motor_revolutions = 0;
+int motor_revolutions=0; //number of revolutions recorded by the encoder on the index channel
+int prev_motor_revolutions=0; //number of revolutions recorded by the encoder on the index channel
+int motor_pulses=0;      //Number of pulses recorded by the encoder
+int prev_motor_pulses=0;      //Number of pulses recorded by the encoder
+float motor_RPM=0;         //Motor angular velocity
+
+
+void controller_update_ISR() {
+    // get motor RPM
+    if (use_index_channel) {
+        motor_revolutions=wheel.getRevolutions();
+        motor_RPM=(motor_revolutions-prev_motor_revolutions)/dt;
+        prev_motor_revolutions=motor_revolutions;
+        //reset encoder counter if overflows
+        if(motor_revolutions>2147483647-setpoint_rpm*dt*10){
+                           //18446744073709551615; for Unsigned long long
+            wheel.reset();    
+            prev_motor_revolutions=0;
+            led4 = !led4;
+        }
+        
+    }else{
+        motor_pulses=wheel.getPulses();     
+        motor_RPM=(motor_pulses-prev_motor_pulses)/PULSE_PER_REV/dt;
+        prev_motor_pulses=motor_pulses;
+        //reset encoder counter if overflows
+        if(motor_pulses>2147483647-setpoint_rpm*dt*PULSE_PER_REV*10){
+                           //18446744073709551615; for Unsigned long long
+            wheel.reset();    
+            prev_motor_pulses=0;
+            led4 = !led4;
+        }
+    }
+    
+    //PID controller
+    error_rpm=setpoint_rpm-motor_RPM;   //e=r-u;
+    if (error_rpm>0){led3=1;} else {led3=0;} //Update Motor Status
+    u_p=Kp*error_rpm;  
+    u_i=u_i+Ki*dt*error_rpm;
+    u_d=Kd*(error_rpm-prev_error_rpm)/dt;
+    u= u_p + u_i + u_d;
+    prev_error_rpm=error_rpm;
+    
+    //Controller Saturation
+    if (u>1){u=1;}
+    if (u<0){u=0;}
+    
+    //Output ESC signal
+    motor_ESC = u;
+    
+    //Update LED2 status, tell user PID is updating
+    led2 = !led2;   
+    
+    //Watch dog can be added here in the future
+}
+ 
+int main() {
+    //pc.printf("Debug mode: \n");
+    led1 = 0;   //init LED1, Main Loop status
+    led2 = 0;   //init LED2, PID status
+    led3 = 0;   //init LED3, Motor status
+    led4 = 0;   //init LED4, Encoder Counter status
+    wait(0.5);
+    
+    //All LEDs Blinks at start up, indicates mbed is setting up ESC
+    motor_ESC = 0; //Generate zero speed signal for ESC startup
+    led1 = 1;led2 = 1;led3 = 1;led1 = 1;
+    wait(0.5);
+    led1 = 0;led2 = 0;led3 = 0;led1 = 0;
+    wait(0.5);
+    led1 = 1;led2 = 1;led3 = 1;led1 = 1;
+    wait(0.5);
+    led1 = 0;led2 = 0;led3 = 0;led1 = 0;
+    wait(0.5);
+    
+    
+    ctrl_updt_timer.attach(&controller_update_ISR, dt); //Update Controller at (1/dt) Hz
+    
+    while(1) {  //blink LED1
+        led1 = !led1;
+        wait(0.2);
+    }
+}
\ No newline at end of file
diff -r 000000000000 -r 8bded3c460c7 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue Apr 18 23:58:28 2017 +0000
@@ -0,0 +1,1 @@
+https://mbed.org/users/mbed_official/code/mbed/builds/97feb9bacc10
\ No newline at end of file