Basic DC motor control test, rpm feedback by simple impulse signal, PID speed control.

Dependencies:   FastPWM mbed FastIO MODSERIAL

Committer:
dzoni
Date:
Wed Mar 28 09:32:05 2018 +0000
Revision:
7:1aba48efb1c3
Parent:
6:cc38171e6a4b
Child:
8:5ce5fe1ce503
Added PID controller to control motor speed (RPM). Compiles OK, ready for functional test.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dzoni 0:bd186184ef2a 1 #include "mbed.h"
dzoni 1:70c514e10598 2 #include "FastPWM.h"
dzoni 2:70918f7f8451 3 #include "FastIO.h"
dzoni 7:1aba48efb1c3 4 #include "PID.h"
dzoni 0:bd186184ef2a 5
dzoni 4:7cb8986200a7 6 #define MODSERIAL_DEFAULT_RX_BUFFER_SIZE 16
dzoni 4:7cb8986200a7 7 #define MODSERIAL_DEFAULT_TX_BUFFER_SIZE 64
dzoni 4:7cb8986200a7 8 #include "MODSERIAL.h"
dzoni 4:7cb8986200a7 9
dzoni 5:ec4d6e435822 10 #define IMPULSE_SENSOR_R_PIN (PA_9)
dzoni 5:ec4d6e435822 11 #define PWM_OUT_R_PIN (PA_6)
dzoni 4:7cb8986200a7 12
dzoni 3:f6c30ada5370 13 //------------------------------------
dzoni 3:f6c30ada5370 14 // Hyperterminal configuration
dzoni 3:f6c30ada5370 15 // 9600 bauds, 8-bit data, no parity
dzoni 3:f6c30ada5370 16 //------------------------------------
dzoni 4:7cb8986200a7 17 MODSERIAL pcLink(SERIAL_TX, SERIAL_RX);
dzoni 4:7cb8986200a7 18
dzoni 7:1aba48efb1c3 19 static const us_timestamp_t periodImpSens = 125000; // 125 msec
dzoni 7:1aba48efb1c3 20 static const us_timestamp_t periodLEDBlink = 100000; // 100 msec
dzoni 7:1aba48efb1c3 21 static const us_timestamp_t periodPWMWrite = 250000; // 250 msec
dzoni 7:1aba48efb1c3 22 static const us_timestamp_t periodRPMSetpoint = 10000000; // 10 sec
dzoni 4:7cb8986200a7 23
dzoni 7:1aba48efb1c3 24 static us_timestamp_t tStampImpSens = 0;
dzoni 7:1aba48efb1c3 25 static us_timestamp_t tStampLEDBlink = 0;
dzoni 7:1aba48efb1c3 26 static us_timestamp_t tStampPWMWrite = 0;
dzoni 7:1aba48efb1c3 27 static us_timestamp_t tStampRPMSetpoint = 0;
dzoni 7:1aba48efb1c3 28
dzoni 7:1aba48efb1c3 29 static us_timestamp_t tStamp = 0;
dzoni 4:7cb8986200a7 30
dzoni 4:7cb8986200a7 31 static unsigned int uiImpSens = 0U;
dzoni 5:ec4d6e435822 32 static unsigned int uiImpSensTemp = 0U;
dzoni 5:ec4d6e435822 33 static int iImpSensLastState = 0;
dzoni 7:1aba48efb1c3 34 static float fPwmDuty = 0.0;
dzoni 7:1aba48efb1c3 35 static float fRPMSetpoint = 0.0f;
dzoni 2:70918f7f8451 36
dzoni 5:ec4d6e435822 37 static void setup(void);
dzoni 5:ec4d6e435822 38 static void tskImpSens(void);
dzoni 5:ec4d6e435822 39 static void tskLEDBlink(void);
dzoni 5:ec4d6e435822 40 static void tskPWMWrite(void);
dzoni 7:1aba48efb1c3 41 static void tskRPMSetpoint(void);
dzoni 5:ec4d6e435822 42 static void tskBackground(void);
dzoni 5:ec4d6e435822 43
dzoni 7:1aba48efb1c3 44 FastPWM mypwm(PWM_OUT_R_PIN);
dzoni 7:1aba48efb1c3 45
dzoni 7:1aba48efb1c3 46 FastIn<IMPULSE_SENSOR_R_PIN> pinImpulseSensorIn;
dzoni 7:1aba48efb1c3 47 FastIn<USER_BUTTON> pinUserButtonIn;
dzoni 7:1aba48efb1c3 48
dzoni 7:1aba48efb1c3 49 PID pid_RPM_Right_motor(1.0f, 0.0f, 0.0f, (((float)periodPWMWrite)/1000000.0f));
dzoni 7:1aba48efb1c3 50
dzoni 7:1aba48efb1c3 51 DigitalOut myled(LED1);
dzoni 7:1aba48efb1c3 52
dzoni 7:1aba48efb1c3 53 Timer myTimer;
dzoni 7:1aba48efb1c3 54
dzoni 7:1aba48efb1c3 55
dzoni 5:ec4d6e435822 56 static inline void DO_TASK(us_timestamp_t tskPeriod, us_timestamp_t &tskTimer, us_timestamp_t timeStamp, void (*tskFunction)(void))
dzoni 5:ec4d6e435822 57 {
dzoni 5:ec4d6e435822 58 if (tskPeriod < (timeStamp - tskTimer))
dzoni 5:ec4d6e435822 59 {
dzoni 5:ec4d6e435822 60 tskTimer = timeStamp;
dzoni 5:ec4d6e435822 61 (*tskFunction)();
dzoni 5:ec4d6e435822 62 }
dzoni 5:ec4d6e435822 63 }
dzoni 5:ec4d6e435822 64
dzoni 5:ec4d6e435822 65 static inline void BACKGROUND(void (*tskFunction)(void))
dzoni 5:ec4d6e435822 66 {
dzoni 5:ec4d6e435822 67 (*tskFunction)();
dzoni 5:ec4d6e435822 68 }
dzoni 4:7cb8986200a7 69
dzoni 5:ec4d6e435822 70
dzoni 5:ec4d6e435822 71 int main(void)
dzoni 5:ec4d6e435822 72 {
dzoni 5:ec4d6e435822 73 setup();
dzoni 5:ec4d6e435822 74
dzoni 5:ec4d6e435822 75 while(1)
dzoni 5:ec4d6e435822 76 {
dzoni 5:ec4d6e435822 77 tStamp = myTimer.read_high_resolution_us();
dzoni 5:ec4d6e435822 78
dzoni 7:1aba48efb1c3 79 DO_TASK(periodLEDBlink, tStampLEDBlink, tStamp, &tskLEDBlink);
dzoni 7:1aba48efb1c3 80 DO_TASK(periodPWMWrite, tStampPWMWrite, tStamp, &tskPWMWrite);
dzoni 7:1aba48efb1c3 81 DO_TASK(periodImpSens, tStampImpSens, tStamp, &tskImpSens);
dzoni 7:1aba48efb1c3 82 DO_TASK(periodRPMSetpoint, tStampRPMSetpoint, tStamp, &tskRPMSetpoint);
dzoni 5:ec4d6e435822 83
dzoni 5:ec4d6e435822 84 BACKGROUND(&tskBackground);
dzoni 5:ec4d6e435822 85 }
dzoni 5:ec4d6e435822 86 }
dzoni 5:ec4d6e435822 87
dzoni 5:ec4d6e435822 88
dzoni 5:ec4d6e435822 89 void setup(void)
dzoni 5:ec4d6e435822 90 {
dzoni 4:7cb8986200a7 91 pcLink.baud(115200);
dzoni 4:7cb8986200a7 92 pcLink.format(8, SerialBase::None, 1);
dzoni 4:7cb8986200a7 93
dzoni 5:ec4d6e435822 94 mypwm.period_us(2000);
dzoni 5:ec4d6e435822 95 mypwm.write(0.5);
dzoni 0:bd186184ef2a 96
dzoni 4:7cb8986200a7 97 myTimer.start();
dzoni 7:1aba48efb1c3 98
dzoni 7:1aba48efb1c3 99 //Analog input from 0.0 to 100.0 impulses per measurement period
dzoni 7:1aba48efb1c3 100 pid_RPM_Right_motor.setInputLimits(0.0f, 100.0f);
dzoni 7:1aba48efb1c3 101
dzoni 7:1aba48efb1c3 102 //Pwm output from 0.0 to 1.0
dzoni 7:1aba48efb1c3 103 pid_RPM_Right_motor.setOutputLimits(0.0f, 1.0f);
dzoni 7:1aba48efb1c3 104
dzoni 7:1aba48efb1c3 105 //If there's a bias.
dzoni 7:1aba48efb1c3 106 pid_RPM_Right_motor.setBias(0.0f);
dzoni 7:1aba48efb1c3 107 pid_RPM_Right_motor.setMode(AUTO_MODE);
dzoni 7:1aba48efb1c3 108
dzoni 7:1aba48efb1c3 109 //We want the process variable to be 0.0 RPM
dzoni 7:1aba48efb1c3 110 pid_RPM_Right_motor.setSetPoint(0.0f);
dzoni 5:ec4d6e435822 111 }
dzoni 5:ec4d6e435822 112
dzoni 5:ec4d6e435822 113 void tskImpSens(void)
dzoni 5:ec4d6e435822 114 {
dzoni 5:ec4d6e435822 115 uiImpSens = uiImpSensTemp;
dzoni 5:ec4d6e435822 116 uiImpSensTemp = 0U;
dzoni 4:7cb8986200a7 117
dzoni 6:cc38171e6a4b 118 pcLink.printf("IMP: %u imp. \r", uiImpSens);
dzoni 5:ec4d6e435822 119 }
dzoni 4:7cb8986200a7 120
dzoni 5:ec4d6e435822 121 void tskLEDBlink(void)
dzoni 5:ec4d6e435822 122 {
dzoni 5:ec4d6e435822 123 myled = !myled;
dzoni 5:ec4d6e435822 124 }
dzoni 1:70c514e10598 125
dzoni 5:ec4d6e435822 126 void tskPWMWrite(void)
dzoni 5:ec4d6e435822 127 {
dzoni 7:1aba48efb1c3 128 // fPwmDuty = fPwmDuty + 0.1;
dzoni 4:7cb8986200a7 129
dzoni 7:1aba48efb1c3 130 // if (1.0 < fPwmDuty)
dzoni 7:1aba48efb1c3 131 // {
dzoni 7:1aba48efb1c3 132 // fPwmDuty = 0.0;
dzoni 7:1aba48efb1c3 133 // }
dzoni 7:1aba48efb1c3 134
dzoni 7:1aba48efb1c3 135 //Update the process variable.
dzoni 7:1aba48efb1c3 136 pid_RPM_Right_motor.setProcessValue((float)uiImpSens);
dzoni 7:1aba48efb1c3 137
dzoni 7:1aba48efb1c3 138 //Set the new output.
dzoni 7:1aba48efb1c3 139 fPwmDuty = pid_RPM_Right_motor.compute();
dzoni 7:1aba48efb1c3 140
dzoni 7:1aba48efb1c3 141 mypwm.write(fPwmDuty);
dzoni 7:1aba48efb1c3 142
dzoni 7:1aba48efb1c3 143 pcLink.printf("PWM: %.2f %%\tIMP: %u imp.\tSET: %.2f imp.\t\r", mypwm.read() * 100, uiImpSens, fRPMSetpoint);
dzoni 7:1aba48efb1c3 144
dzoni 7:1aba48efb1c3 145 // pcLink.printf("\r\nPWM: %.2f %% \r\n", mypwm.read() * 100);
dzoni 7:1aba48efb1c3 146 }
dzoni 7:1aba48efb1c3 147
dzoni 7:1aba48efb1c3 148 void tskRPMSetpoint(void)
dzoni 7:1aba48efb1c3 149 {
dzoni 7:1aba48efb1c3 150 fRPMSetpoint += 10.0f;
dzoni 7:1aba48efb1c3 151 if (100.0f < fRPMSetpoint)
dzoni 5:ec4d6e435822 152 {
dzoni 7:1aba48efb1c3 153 fRPMSetpoint = 0.0f;
dzoni 0:bd186184ef2a 154 }
dzoni 5:ec4d6e435822 155
dzoni 7:1aba48efb1c3 156 pid_RPM_Right_motor.setSetPoint(fRPMSetpoint);
dzoni 0:bd186184ef2a 157 }
dzoni 5:ec4d6e435822 158
dzoni 5:ec4d6e435822 159 void tskBackground(void)
dzoni 5:ec4d6e435822 160 {
dzoni 5:ec4d6e435822 161 // Impulse sensor - pulse counting
dzoni 5:ec4d6e435822 162 int iTemp = pinImpulseSensorIn.read();
dzoni 5:ec4d6e435822 163 if (iTemp != iImpSensLastState)
dzoni 5:ec4d6e435822 164 {
dzoni 5:ec4d6e435822 165 iImpSensLastState = iTemp;
dzoni 5:ec4d6e435822 166 uiImpSensTemp++;
dzoni 5:ec4d6e435822 167 }
dzoni 5:ec4d6e435822 168 }