Sven Kugathasan / Mbed OS SKAFMO_2

Dependencies:   PID

Committer:
mo713
Date:
Fri Mar 24 02:10:11 2017 +0000
Revision:
6:8d18cdcabc3a
Parent:
4:5eb8ac894d0f
Child:
7:3524b21c3828
Child:
10:e974ee1ea1f0
regexx

Who changed what in which revision?

UserRevisionLine numberNew contents of line
svenkugi 0:b6deec3905f4 1 /*_________________________________LIBRARIES__________________________________*/
svenkugi 0:b6deec3905f4 2
svenkugi 0:b6deec3905f4 3 #include "mbed.h"
svenkugi 0:b6deec3905f4 4 #include "rtos.h"
svenkugi 0:b6deec3905f4 5 #include "PID.h"
mo713 6:8d18cdcabc3a 6 #include "Regexp.h"
mo713 6:8d18cdcabc3a 7 #include "string.h"
mo713 6:8d18cdcabc3a 8 #include "stdlib.h"
mo713 6:8d18cdcabc3a 9 #include <string>
mo713 6:8d18cdcabc3a 10 #include <ctype.h>
svenkugi 0:b6deec3905f4 11
svenkugi 0:b6deec3905f4 12 /*_________________________________PIN SETUP__________________________________*/
svenkugi 0:b6deec3905f4 13
svenkugi 0:b6deec3905f4 14 //PhotoInterrupter Input Pins
svenkugi 0:b6deec3905f4 15 #define I1pin D2
svenkugi 0:b6deec3905f4 16 #define I2pin D11
svenkugi 0:b6deec3905f4 17 #define I3pin D12
svenkugi 0:b6deec3905f4 18
svenkugi 0:b6deec3905f4 19 //Incremental Encoder Input Pins
svenkugi 0:b6deec3905f4 20 #define CHA D7
svenkugi 0:b6deec3905f4 21 #define CHB D8
svenkugi 0:b6deec3905f4 22
svenkugi 0:b6deec3905f4 23 //Motor Drive output pins //Mask in output byte
svenkugi 0:b6deec3905f4 24 #define L1Lpin D4 //0x01
svenkugi 0:b6deec3905f4 25 #define L1Hpin D5 //0x02
svenkugi 0:b6deec3905f4 26 #define L2Lpin D3 //0x04
svenkugi 0:b6deec3905f4 27 #define L2Hpin D6 //0x08
svenkugi 0:b6deec3905f4 28 #define L3Lpin D9 //0x10
svenkugi 0:b6deec3905f4 29 #define L3Hpin D10 //0x20
svenkugi 0:b6deec3905f4 30
svenkugi 0:b6deec3905f4 31 //Photointerrupter Inputs as Interrupts
svenkugi 0:b6deec3905f4 32 InterruptIn InterruptI1(D2);
svenkugi 0:b6deec3905f4 33 InterruptIn InterruptI2(D11);
svenkugi 0:b6deec3905f4 34 InterruptIn InterruptI3(D12);
svenkugi 0:b6deec3905f4 35
svenkugi 0:b6deec3905f4 36 //Incremental Encoder Inputs as Interrupts
svenkugi 0:b6deec3905f4 37 InterruptIn InterruptCHA(D7);
svenkugi 0:b6deec3905f4 38 DigitalIn InterruptCHB(D8);
svenkugi 0:b6deec3905f4 39
svenkugi 0:b6deec3905f4 40 //Motor Drive Outputs in PWM
svenkugi 0:b6deec3905f4 41 PwmOut L1L(L1Lpin);
svenkugi 0:b6deec3905f4 42 PwmOut L1H(L1Hpin);
svenkugi 0:b6deec3905f4 43 PwmOut L2L(L2Lpin);
svenkugi 0:b6deec3905f4 44 PwmOut L2H(L2Hpin);
svenkugi 0:b6deec3905f4 45 PwmOut L3L(L3Lpin);
svenkugi 0:b6deec3905f4 46 PwmOut L3H(L3Hpin);
svenkugi 0:b6deec3905f4 47
svenkugi 0:b6deec3905f4 48 //Status LED
svenkugi 0:b6deec3905f4 49 DigitalOut led1(LED1);
svenkugi 0:b6deec3905f4 50
svenkugi 0:b6deec3905f4 51 //Initialise the serial port
svenkugi 0:b6deec3905f4 52 Serial pc(SERIAL_TX, SERIAL_RX);
svenkugi 0:b6deec3905f4 53
svenkugi 0:b6deec3905f4 54 //Initialize Threads
svenkugi 0:b6deec3905f4 55 Thread thread;
svenkugi 0:b6deec3905f4 56
svenkugi 0:b6deec3905f4 57 //Timer
svenkugi 0:b6deec3905f4 58 Timer rps; // Measures Time for complete revolution
svenkugi 0:b6deec3905f4 59 Timer partial_rps; // Measures Time for partial revolutions
svenkugi 0:b6deec3905f4 60 Timer tmp; // Profiler Timer
svenkugi 0:b6deec3905f4 61
svenkugi 0:b6deec3905f4 62 //PID Controller
svenkugi 0:b6deec3905f4 63 PID velocity_pid(0.5, 0.5, 0.1, 0.05); // (P, I, D, WAIT)
svenkugi 0:b6deec3905f4 64 PID dist_pid(2, 0.0, 0.005, 0.05); // (P, I, D, WAIT)
svenkugi 0:b6deec3905f4 65
svenkugi 0:b6deec3905f4 66 /*________________________Motor Drive States__________________________________*/
svenkugi 0:b6deec3905f4 67
svenkugi 0:b6deec3905f4 68 //Mapping from sequential drive states to motor phase outputs
svenkugi 0:b6deec3905f4 69 /*
svenkugi 0:b6deec3905f4 70 State L1 L2 L3
svenkugi 0:b6deec3905f4 71 0 H - L
svenkugi 0:b6deec3905f4 72 1 - H L
svenkugi 0:b6deec3905f4 73 2 L H -
svenkugi 0:b6deec3905f4 74 3 L - H
svenkugi 0:b6deec3905f4 75 4 - L H
svenkugi 0:b6deec3905f4 76 5 H L -
svenkugi 0:b6deec3905f4 77 6 - - -
svenkugi 0:b6deec3905f4 78 7 - - -
svenkugi 0:b6deec3905f4 79 */
svenkugi 0:b6deec3905f4 80
svenkugi 0:b6deec3905f4 81 //Drive state to output table
svenkugi 0:b6deec3905f4 82 const int8_t driveTable[] = {0x12,0x18,0x09,0x21,0x24,0x06,0x00,0x00};
svenkugi 0:b6deec3905f4 83
svenkugi 0:b6deec3905f4 84 //Mapping from interrupter inputs to sequential rotor states. 0x00 and 0x07 are not valid
svenkugi 0:b6deec3905f4 85 const int8_t stateMap[] = {0x07,0x05,0x03,0x04,0x01,0x00,0x02,0x07};
svenkugi 0:b6deec3905f4 86
svenkugi 0:b6deec3905f4 87 //Alternative if phase order of input or drive is reversed
svenkugi 0:b6deec3905f4 88 //const int8_t stateMap_Reverse[] = {0x07,0x01,0x03,0x02,0x05,0x00,0x04,0x07};
svenkugi 0:b6deec3905f4 89
svenkugi 0:b6deec3905f4 90 /*____________________Global Variable Initialization__________________________*/
svenkugi 0:b6deec3905f4 91
svenkugi 0:b6deec3905f4 92 //Phase lead to make motor spin: 2 for forwards, -2 for backwards
svenkugi 0:b6deec3905f4 93 const int8_t lead = -2;
svenkugi 0:b6deec3905f4 94 int8_t direction = 1; //Default Setting: Backwards rotation
svenkugi 0:b6deec3905f4 95
svenkugi 0:b6deec3905f4 96 //Rotor Offset
svenkugi 0:b6deec3905f4 97 uint8_t orState=0;
svenkugi 0:b6deec3905f4 98
svenkugi 0:b6deec3905f4 99 //Disk State
svenkugi 0:b6deec3905f4 100 uint8_t intState=0; //Current Optical Disk state
svenkugi 0:b6deec3905f4 101
svenkugi 0:b6deec3905f4 102 //State Variables
svenkugi 0:b6deec3905f4 103 const uint8_t num_states = 6; //Number of states in one rotation
svenkugi 0:b6deec3905f4 104 uint32_t count = 0; //Counts number of states traversed
svenkugi 0:b6deec3905f4 105 int8_t completed = 0; //Checks if rotation completed
svenkugi 0:b6deec3905f4 106 int8_t driveto = 0; //Holds value of new motor drive state
svenkugi 0:b6deec3905f4 107
svenkugi 0:b6deec3905f4 108 //Debug Variables
svenkugi 0:b6deec3905f4 109 bool flag = false;
svenkugi 0:b6deec3905f4 110 float test_time=0;
svenkugi 0:b6deec3905f4 111 uint8_t test = 0;
svenkugi 0:b6deec3905f4 112
svenkugi 0:b6deec3905f4 113 //Angular Velocity Variables
svenkugi 0:b6deec3905f4 114 float period = 0; //Time taken to complete one rotation
svenkugi 0:b6deec3905f4 115 float angular_vel = 0; //Revolution per second
svenkugi 0:b6deec3905f4 116 float test_vel = 0;
svenkugi 0:b6deec3905f4 117
svenkugi 0:b6deec3905f4 118 float PWM_freq = 0.001f; //500Hz (> Motor LP cut-off frequency = 10Hz)
svenkugi 0:b6deec3905f4 119 float dutyout = 1.0f; //Initialized at 50% duty cycle
svenkugi 0:b6deec3905f4 120 float dutyout_max = 1.0f; //Maximum Duty Cycle
svenkugi 0:b6deec3905f4 121
svenkugi 0:b6deec3905f4 122 //float velocity_set = 10.0;
svenkugi 0:b6deec3905f4 123 uint32_t revstates_count = 0; //Global Variable to pass into interrupt
svenkugi 0:b6deec3905f4 124 float rev_target = 0.0f;
svenkugi 0:b6deec3905f4 125 float vel_target = 10.0f;
svenkugi 0:b6deec3905f4 126
svenkugi 0:b6deec3905f4 127 uint8_t pulse_count = 0;
svenkugi 0:b6deec3905f4 128 float total_rev = 0.0f;
svenkugi 0:b6deec3905f4 129 float partial_rev = 0.0f;
svenkugi 0:b6deec3905f4 130 float drive_vel = 0.0f;
svenkugi 0:b6deec3905f4 131
svenkugi 0:b6deec3905f4 132 /*_____Basic Functions (Motor Drive, Synchronization, Reading Rotor State)____*/
svenkugi 0:b6deec3905f4 133
svenkugi 0:b6deec3905f4 134 //Set a given drive state
svenkugi 0:b6deec3905f4 135 void motorOut(int8_t driveState){
svenkugi 0:b6deec3905f4 136
svenkugi 0:b6deec3905f4 137 //Lookup the output byte from the drive state.
svenkugi 0:b6deec3905f4 138 int8_t driveOut = driveTable[driveState & 0x07];
svenkugi 0:b6deec3905f4 139
svenkugi 0:b6deec3905f4 140 //Turn off first (PWM)
svenkugi 0:b6deec3905f4 141 if (~driveOut & 0x01) L1L = 0;
svenkugi 0:b6deec3905f4 142 if (~driveOut & 0x02) L1H.write(dutyout); L1H.period(PWM_freq);
svenkugi 0:b6deec3905f4 143 if (~driveOut & 0x04) L2L = 0;
svenkugi 0:b6deec3905f4 144 if (~driveOut & 0x08) L2H.write(dutyout); L2H.period(PWM_freq);
svenkugi 0:b6deec3905f4 145 if (~driveOut & 0x10) L3L = 0;
svenkugi 0:b6deec3905f4 146 if (~driveOut & 0x20) L3H.write(dutyout); L3H.period(PWM_freq);
svenkugi 0:b6deec3905f4 147
svenkugi 0:b6deec3905f4 148 //Then turn on (PWM)
svenkugi 0:b6deec3905f4 149 if (driveOut & 0x01) L1L.write(dutyout); L1L.period(PWM_freq);
svenkugi 0:b6deec3905f4 150 if (driveOut & 0x02) L1H = 0;
svenkugi 0:b6deec3905f4 151 if (driveOut & 0x04) L2L.write(dutyout); L2L.period(PWM_freq);
svenkugi 0:b6deec3905f4 152 if (driveOut & 0x08) L2H = 0;
svenkugi 0:b6deec3905f4 153 if (driveOut & 0x10) L3L.write(dutyout); L3L.period(PWM_freq);
svenkugi 0:b6deec3905f4 154 if (driveOut & 0x20) L3H = 0;
svenkugi 3:7ee013b0976e 155
svenkugi 0:b6deec3905f4 156 }
svenkugi 0:b6deec3905f4 157
svenkugi 0:b6deec3905f4 158 //Convert photointerrupter inputs to a rotor state
svenkugi 0:b6deec3905f4 159 inline int8_t readRotorState(){
svenkugi 0:b6deec3905f4 160 return stateMap[InterruptI1.read() + 2*InterruptI2.read() + 4*InterruptI3.read()];
svenkugi 0:b6deec3905f4 161 }
svenkugi 0:b6deec3905f4 162
svenkugi 0:b6deec3905f4 163 //Basic synchronisation routine
svenkugi 0:b6deec3905f4 164 int8_t motorHome() {
svenkugi 0:b6deec3905f4 165 dutyout = 1.0f;
svenkugi 0:b6deec3905f4 166
svenkugi 3:7ee013b0976e 167 //Put the motor in drive state X (e.g. 5) tp avoid initial jittevbo
svenkugi 0:b6deec3905f4 168 motorOut(5);
svenkugi 0:b6deec3905f4 169 wait(1.0);
svenkugi 0:b6deec3905f4 170
svenkugi 0:b6deec3905f4 171 //Put the motor in drive state 0 and wait for it to stabilise
svenkugi 0:b6deec3905f4 172 motorOut(0);
svenkugi 0:b6deec3905f4 173 wait(1.0);
svenkugi 0:b6deec3905f4 174
svenkugi 0:b6deec3905f4 175 //Get the rotor state
svenkugi 0:b6deec3905f4 176 return readRotorState();
svenkugi 0:b6deec3905f4 177 }
mo713 6:8d18cdcabc3a 178 void serial_com()
mo713 6:8d18cdcabc3a 179 {
mo713 6:8d18cdcabc3a 180
mo713 6:8d18cdcabc3a 181 pc.baud(9600);
mo713 6:8d18cdcabc3a 182
mo713 6:8d18cdcabc3a 183 string input;
mo713 6:8d18cdcabc3a 184
mo713 6:8d18cdcabc3a 185 int position_r;
mo713 6:8d18cdcabc3a 186 int position_v;
mo713 6:8d18cdcabc3a 187
mo713 6:8d18cdcabc3a 188 float r;
mo713 6:8d18cdcabc3a 189 float v;
mo713 6:8d18cdcabc3a 190 string note;
mo713 6:8d18cdcabc3a 191 int duration;
mo713 6:8d18cdcabc3a 192 int ind1=1;
mo713 6:8d18cdcabc3a 193 int ind2=0;
mo713 6:8d18cdcabc3a 194
mo713 6:8d18cdcabc3a 195
mo713 6:8d18cdcabc3a 196 char temp [255];
mo713 6:8d18cdcabc3a 197
mo713 6:8d18cdcabc3a 198 /////////////
mo713 6:8d18cdcabc3a 199
mo713 6:8d18cdcabc3a 200
mo713 6:8d18cdcabc3a 201 while (1) {
mo713 6:8d18cdcabc3a 202
mo713 6:8d18cdcabc3a 203 pc.printf("Please enter\r\n");
mo713 6:8d18cdcabc3a 204 pc.scanf("%s",&temp);
mo713 6:8d18cdcabc3a 205 input=temp;
mo713 6:8d18cdcabc3a 206 const char *buf = input.c_str();
mo713 6:8d18cdcabc3a 207 MatchState ms;
mo713 6:8d18cdcabc3a 208 ms.Target ((char*)buf);
mo713 6:8d18cdcabc3a 209
mo713 6:8d18cdcabc3a 210 char note_start=ms.Match("^[T]");
mo713 6:8d18cdcabc3a 211
mo713 6:8d18cdcabc3a 212 char note_mask = ms.Match ("[ABCDEFG]([#^]?)[1-8]$");
mo713 6:8d18cdcabc3a 213
mo713 6:8d18cdcabc3a 214 char mv_mask = ms.Match ("^([RV]([-]?)(%d+)([.]?)(%d*))(([V]?)([-]?)(%d*)([.]?)(%d*))$");
mo713 6:8d18cdcabc3a 215
mo713 6:8d18cdcabc3a 216 if (note_mask == REGEXP_MATCHED && note_start==REGEXP_MATCHED)
mo713 6:8d18cdcabc3a 217 {
mo713 6:8d18cdcabc3a 218 pc.printf("Note sequence match\r\n");
mo713 6:8d18cdcabc3a 219 pc.printf("Note sequence is %s\r\n",input.substr(1).c_str());
mo713 6:8d18cdcabc3a 220 pc.printf("Durations are ...\r\n");
mo713 6:8d18cdcabc3a 221 for(int i=1;i<=input.length();i++)
mo713 6:8d18cdcabc3a 222 {
mo713 6:8d18cdcabc3a 223
mo713 6:8d18cdcabc3a 224 if(isdigit(input[i]))
mo713 6:8d18cdcabc3a 225 {
mo713 6:8d18cdcabc3a 226
mo713 6:8d18cdcabc3a 227 duration=(int)(input[i]-'0');
mo713 6:8d18cdcabc3a 228 pc.printf("The note is %s with duration %d\r\n",input.substr(ind1,i-ind1).c_str(),duration);
mo713 6:8d18cdcabc3a 229
mo713 6:8d18cdcabc3a 230 ind1=i+1;
mo713 6:8d18cdcabc3a 231 }
mo713 6:8d18cdcabc3a 232
mo713 6:8d18cdcabc3a 233 }
mo713 6:8d18cdcabc3a 234
mo713 6:8d18cdcabc3a 235 }
mo713 6:8d18cdcabc3a 236
mo713 6:8d18cdcabc3a 237
mo713 6:8d18cdcabc3a 238 else if (note_start == REGEXP_NOMATCH || note_mask==REGEXP_NOMATCH)
mo713 6:8d18cdcabc3a 239 {
mo713 6:8d18cdcabc3a 240 if (mv_mask == REGEXP_MATCHED)
mo713 6:8d18cdcabc3a 241 {
mo713 6:8d18cdcabc3a 242 pc.printf("Match\r\n");
mo713 6:8d18cdcabc3a 243 position_r=input.find('R');
mo713 6:8d18cdcabc3a 244 position_v=input.find('V');
mo713 6:8d18cdcabc3a 245
mo713 6:8d18cdcabc3a 246 pc.printf("Position of r is %d\r\n",position_r);
mo713 6:8d18cdcabc3a 247 pc.printf("Position of v is %d\r\n",position_v);
mo713 6:8d18cdcabc3a 248
mo713 6:8d18cdcabc3a 249
mo713 6:8d18cdcabc3a 250 if(position_v==-1)
mo713 6:8d18cdcabc3a 251 {
mo713 6:8d18cdcabc3a 252 r=atof(input.substr(position_r+1).c_str());
mo713 6:8d18cdcabc3a 253 pc.printf("Sping for %.3f rotations\r\n",r);
mo713 6:8d18cdcabc3a 254 }
mo713 6:8d18cdcabc3a 255
mo713 6:8d18cdcabc3a 256 else if(position_r==-1)
mo713 6:8d18cdcabc3a 257 {
mo713 6:8d18cdcabc3a 258 v=atof(input.substr(position_v+1).c_str());
mo713 6:8d18cdcabc3a 259 pc.printf("Spin at speed of %.3f indefinitely\r\n",v);
mo713 6:8d18cdcabc3a 260 }
mo713 6:8d18cdcabc3a 261
mo713 6:8d18cdcabc3a 262 else
mo713 6:8d18cdcabc3a 263 {
mo713 6:8d18cdcabc3a 264
mo713 6:8d18cdcabc3a 265 if(input.at(position_v+1)=='-')
mo713 6:8d18cdcabc3a 266 {
mo713 6:8d18cdcabc3a 267 r=atof(input.substr(position_r+1,position_v-1).c_str());
mo713 6:8d18cdcabc3a 268 v=atof(input.substr(position_v+2).c_str());
mo713 6:8d18cdcabc3a 269 }
mo713 6:8d18cdcabc3a 270 else
mo713 6:8d18cdcabc3a 271 {
mo713 6:8d18cdcabc3a 272 r=atof(input.substr(position_r+1,position_v-1).c_str());
mo713 6:8d18cdcabc3a 273 v=atof(input.substr(position_v+1).c_str());
mo713 6:8d18cdcabc3a 274 }
mo713 6:8d18cdcabc3a 275 pc.printf("Spin for %.3f rotations at speed of %.3f\r\n",r,v);
mo713 6:8d18cdcabc3a 276
mo713 6:8d18cdcabc3a 277 }
mo713 6:8d18cdcabc3a 278
mo713 6:8d18cdcabc3a 279
mo713 6:8d18cdcabc3a 280
mo713 6:8d18cdcabc3a 281
mo713 6:8d18cdcabc3a 282 }
mo713 6:8d18cdcabc3a 283
mo713 6:8d18cdcabc3a 284 else if(mv_mask==REGEXP_NOMATCH)
mo713 6:8d18cdcabc3a 285 pc.printf("Invalid input\r\n");
mo713 6:8d18cdcabc3a 286 }
mo713 6:8d18cdcabc3a 287 else
mo713 6:8d18cdcabc3a 288 {
mo713 6:8d18cdcabc3a 289 pc.printf("Mask error\r\n");
mo713 6:8d18cdcabc3a 290 }
mo713 6:8d18cdcabc3a 291
mo713 6:8d18cdcabc3a 292
mo713 6:8d18cdcabc3a 293
mo713 6:8d18cdcabc3a 294 }
mo713 6:8d18cdcabc3a 295
mo713 6:8d18cdcabc3a 296
mo713 6:8d18cdcabc3a 297 }
mo713 6:8d18cdcabc3a 298
svenkugi 0:b6deec3905f4 299
svenkugi 0:b6deec3905f4 300 /*________________Advanced Functions (Speed and Position Control)_____________*/
svenkugi 0:b6deec3905f4 301
svenkugi 0:b6deec3905f4 302 // Function has no PID
svenkugi 0:b6deec3905f4 303 void rotation_control(int8_t num_revs, int8_t sign){
svenkugi 0:b6deec3905f4 304
svenkugi 0:b6deec3905f4 305 revstates_count = num_revs*num_states;
svenkugi 0:b6deec3905f4 306
svenkugi 0:b6deec3905f4 307 intState = readRotorState();
svenkugi 0:b6deec3905f4 308 driveto = (intState-orState+(sign*lead)+6)%6;
svenkugi 0:b6deec3905f4 309 motorOut(driveto);
svenkugi 0:b6deec3905f4 310
svenkugi 0:b6deec3905f4 311 while(!completed){
svenkugi 0:b6deec3905f4 312
svenkugi 0:b6deec3905f4 313 //pc.printf("Angular velocity: %f \n", angular_vel);
svenkugi 0:b6deec3905f4 314 pc.printf("Partial Angular: %f \n", test_vel);
svenkugi 0:b6deec3905f4 315 //pc.printf("Count: %d \r\n", (count/6));
svenkugi 0:b6deec3905f4 316
svenkugi 0:b6deec3905f4 317 }
svenkugi 0:b6deec3905f4 318 }
svenkugi 0:b6deec3905f4 319
svenkugi 0:b6deec3905f4 320 // Funciton involves PID
svenkugi 3:7ee013b0976e 321 void position_control(float num_revs, float vel_target){
svenkugi 0:b6deec3905f4 322
svenkugi 3:7ee013b0976e 323 if(num_revs < 0){
svenkugi 3:7ee013b0976e 324 direction = -1;
svenkugi 3:7ee013b0976e 325 }
svenkugi 3:7ee013b0976e 326
svenkugi 3:7ee013b0976e 327 rev_target = abs(num_revs);
svenkugi 0:b6deec3905f4 328
svenkugi 0:b6deec3905f4 329 velocity_pid.setInputLimits(0.0, 50.0);
svenkugi 0:b6deec3905f4 330 velocity_pid.setOutputLimits(0.0, 1.0);
svenkugi 0:b6deec3905f4 331 velocity_pid.setMode(1);
svenkugi 0:b6deec3905f4 332 velocity_pid.setSetPoint(vel_target);
svenkugi 0:b6deec3905f4 333
svenkugi 0:b6deec3905f4 334 dist_pid.setInputLimits(0.0, 1000.0);
svenkugi 0:b6deec3905f4 335 dist_pid.setOutputLimits(0.2, 1.0);
svenkugi 0:b6deec3905f4 336 dist_pid.setMode(1);
svenkugi 0:b6deec3905f4 337 dist_pid.setSetPoint(rev_target);
svenkugi 0:b6deec3905f4 338
svenkugi 0:b6deec3905f4 339 intState = readRotorState();
svenkugi 4:5eb8ac894d0f 340 driveto = (intState-orState+(direction*lead)+6)%6;
svenkugi 0:b6deec3905f4 341 motorOut(driveto);
svenkugi 0:b6deec3905f4 342
svenkugi 0:b6deec3905f4 343 while(!completed){
svenkugi 0:b6deec3905f4 344
svenkugi 0:b6deec3905f4 345 //pc.printf("dutyout: %f \r\n", dutyout);
svenkugi 0:b6deec3905f4 346 pc.printf("Angular velocity: %f \r\n", angular_vel);
svenkugi 0:b6deec3905f4 347 pc.printf("Count: %d \r\n", count);
svenkugi 0:b6deec3905f4 348 //pc.printf("Total_rev: %f \r\n", total_rev);
svenkugi 0:b6deec3905f4 349 //pc.printf("\n");
svenkugi 0:b6deec3905f4 350 wait(0.05);
svenkugi 0:b6deec3905f4 351 }
svenkugi 0:b6deec3905f4 352
svenkugi 0:b6deec3905f4 353 }
svenkugi 0:b6deec3905f4 354
svenkugi 0:b6deec3905f4 355 void changestate_isr(){
svenkugi 0:b6deec3905f4 356
svenkugi 0:b6deec3905f4 357 // Profiling: Test time duration of ISR
svenkugi 0:b6deec3905f4 358 /*if(test == 0){
svenkugi 0:b6deec3905f4 359 tmp.start();
svenkugi 0:b6deec3905f4 360 test = 1;
svenkugi 0:b6deec3905f4 361 }
svenkugi 0:b6deec3905f4 362
svenkugi 0:b6deec3905f4 363 else{
svenkugi 0:b6deec3905f4 364 tmp.stop();
svenkugi 0:b6deec3905f4 365 test_time = tmp.read();
svenkugi 0:b6deec3905f4 366 tmp.reset();
svenkugi 0:b6deec3905f4 367 test = 0;
svenkugi 0:b6deec3905f4 368 }*/
svenkugi 0:b6deec3905f4 369
svenkugi 0:b6deec3905f4 370 // Measure time for 360 Rotation
svenkugi 0:b6deec3905f4 371 if(driveto == 0x04){ //Next time drivestate=4, 360 degrees revolution
svenkugi 0:b6deec3905f4 372 if(flag){
svenkugi 0:b6deec3905f4 373 rps.stop();
svenkugi 0:b6deec3905f4 374 angular_vel = 1/(rps.read());
svenkugi 0:b6deec3905f4 375 rps.reset();
svenkugi 0:b6deec3905f4 376 flag = 0;
svenkugi 0:b6deec3905f4 377 }
svenkugi 0:b6deec3905f4 378 }
svenkugi 0:b6deec3905f4 379
svenkugi 0:b6deec3905f4 380 if(driveto == 0x04){ //First time drivestate=4, Timer started at 0 degrees
svenkugi 0:b6deec3905f4 381 pulse_count = 0;
svenkugi 0:b6deec3905f4 382 rps.start();
svenkugi 0:b6deec3905f4 383 flag = 1;
svenkugi 0:b6deec3905f4 384 }
svenkugi 0:b6deec3905f4 385
svenkugi 0:b6deec3905f4 386 // Measure number of revolutions
svenkugi 0:b6deec3905f4 387 count++;
svenkugi 0:b6deec3905f4 388
svenkugi 0:b6deec3905f4 389 //Turn-off when target reached
svenkugi 0:b6deec3905f4 390 if(total_rev >= rev_target){
svenkugi 0:b6deec3905f4 391 completed = 1;
svenkugi 0:b6deec3905f4 392 dutyout = 0;
svenkugi 0:b6deec3905f4 393 motorOut(0);
svenkugi 0:b6deec3905f4 394 led1 = 0;
svenkugi 0:b6deec3905f4 395 __disable_irq();
svenkugi 0:b6deec3905f4 396 }
svenkugi 0:b6deec3905f4 397 else{
svenkugi 0:b6deec3905f4 398 intState = readRotorState();
svenkugi 0:b6deec3905f4 399 driveto = (intState-orState+direction*lead+6)%6;
svenkugi 0:b6deec3905f4 400 motorOut(driveto);
svenkugi 0:b6deec3905f4 401 }
svenkugi 0:b6deec3905f4 402
svenkugi 0:b6deec3905f4 403 }
svenkugi 0:b6deec3905f4 404
svenkugi 0:b6deec3905f4 405 void pid_isr(){
svenkugi 0:b6deec3905f4 406
svenkugi 0:b6deec3905f4 407 led1 = !led1;
svenkugi 0:b6deec3905f4 408 //tmp.start();
svenkugi 0:b6deec3905f4 409
svenkugi 0:b6deec3905f4 410 //117 Pulses per revolution
svenkugi 0:b6deec3905f4 411 pulse_count++;
svenkugi 0:b6deec3905f4 412
svenkugi 0:b6deec3905f4 413 //Measure Time to do 3 degrees of rotation
svenkugi 0:b6deec3905f4 414 if(test == 0){
svenkugi 0:b6deec3905f4 415 partial_rps.start();
svenkugi 0:b6deec3905f4 416 test = 1;
svenkugi 0:b6deec3905f4 417 }
svenkugi 0:b6deec3905f4 418 else{
svenkugi 0:b6deec3905f4 419 partial_rps.stop();
svenkugi 0:b6deec3905f4 420 test_vel = 1/((117.0f * partial_rps.read()));
svenkugi 0:b6deec3905f4 421 partial_rps.reset();
svenkugi 0:b6deec3905f4 422 test = 0;
svenkugi 0:b6deec3905f4 423 }
svenkugi 0:b6deec3905f4 424
svenkugi 0:b6deec3905f4 425 //Partial Revolution Count
svenkugi 0:b6deec3905f4 426 partial_rev = pulse_count/117.0f;
svenkugi 0:b6deec3905f4 427
svenkugi 0:b6deec3905f4 428 //Total Revolution Count
svenkugi 0:b6deec3905f4 429 total_rev = (count/6.0f) + partial_rev;
svenkugi 0:b6deec3905f4 430
svenkugi 0:b6deec3905f4 431 //Calculate new PID Control Point
svenkugi 0:b6deec3905f4 432 if((total_rev/rev_target) > 0.7f){
svenkugi 0:b6deec3905f4 433 dist_pid.setProcessValue(total_rev);
svenkugi 0:b6deec3905f4 434 dutyout = dist_pid.compute();
svenkugi 0:b6deec3905f4 435 }
svenkugi 0:b6deec3905f4 436 else{
svenkugi 0:b6deec3905f4 437 velocity_pid.setProcessValue(test_vel);
svenkugi 0:b6deec3905f4 438 dutyout = velocity_pid.compute();
svenkugi 0:b6deec3905f4 439 }
svenkugi 0:b6deec3905f4 440
svenkugi 0:b6deec3905f4 441 //dist_pid.setProcessValue(total_rev);
svenkugi 0:b6deec3905f4 442 //dutyout = dist_pid.compute();
svenkugi 0:b6deec3905f4 443
svenkugi 0:b6deec3905f4 444 //tmp.stop();
svenkugi 0:b6deec3905f4 445 //test_time = tmp.read();
svenkugi 0:b6deec3905f4 446 //tmp.reset();
svenkugi 0:b6deec3905f4 447 }
svenkugi 0:b6deec3905f4 448
svenkugi 0:b6deec3905f4 449 /*_______________________Testing and Tuning Function__________________________*/
svenkugi 0:b6deec3905f4 450
svenkugi 0:b6deec3905f4 451 /*Measures Angular Velocity using PhotoInterrupters by checking time taken to go
svenkugi 0:b6deec3905f4 452 from State 4 to State 4 in this case. Avoid sensor phasing as it measures one
svenkugi 0:b6deec3905f4 453 complete cycle */
svenkugi 0:b6deec3905f4 454
svenkugi 0:b6deec3905f4 455 void meas_velocity(){
svenkugi 0:b6deec3905f4 456
svenkugi 0:b6deec3905f4 457 intState = readRotorState();
svenkugi 0:b6deec3905f4 458 driveto = (intState-orState+direction*lead+6)%6;
svenkugi 0:b6deec3905f4 459 motorOut(driveto);
svenkugi 0:b6deec3905f4 460
svenkugi 0:b6deec3905f4 461 while (1) {
svenkugi 0:b6deec3905f4 462
svenkugi 0:b6deec3905f4 463 pc.printf("Rotations per second: %f \n\r", angular_vel);
svenkugi 0:b6deec3905f4 464
svenkugi 0:b6deec3905f4 465 }
svenkugi 0:b6deec3905f4 466 }
svenkugi 0:b6deec3905f4 467
svenkugi 0:b6deec3905f4 468 void PID_tuning(){
svenkugi 0:b6deec3905f4 469
svenkugi 0:b6deec3905f4 470 dutyout = 0.5;
svenkugi 0:b6deec3905f4 471
svenkugi 0:b6deec3905f4 472 intState = readRotorState();
svenkugi 0:b6deec3905f4 473 driveto = (intState-orState+lead+6)%6;
svenkugi 0:b6deec3905f4 474 motorOut(driveto);
svenkugi 0:b6deec3905f4 475
svenkugi 0:b6deec3905f4 476 while (1) {
svenkugi 0:b6deec3905f4 477
svenkugi 0:b6deec3905f4 478 // Testing Step Response by increasing D.C. from 0.5 to 0.7
svenkugi 0:b6deec3905f4 479 // Gradient is equal to Kc
svenkugi 0:b6deec3905f4 480
svenkugi 0:b6deec3905f4 481 if(count > 3000){
svenkugi 0:b6deec3905f4 482 dutyout = 0.7;
svenkugi 0:b6deec3905f4 483 }
svenkugi 0:b6deec3905f4 484
svenkugi 0:b6deec3905f4 485 pc.printf("Duty Cycle: %f ", dutyout);
svenkugi 0:b6deec3905f4 486 pc.printf("Rotations per second: %f ", angular_vel);
svenkugi 0:b6deec3905f4 487 pc.printf("Count: %d \n\r", count);
svenkugi 0:b6deec3905f4 488
svenkugi 0:b6deec3905f4 489 }
svenkugi 0:b6deec3905f4 490 }
svenkugi 0:b6deec3905f4 491
svenkugi 0:b6deec3905f4 492 /*__________________________Main Function_____________________________________*/
svenkugi 0:b6deec3905f4 493 int main(){
svenkugi 0:b6deec3905f4 494
svenkugi 0:b6deec3905f4 495 //Start of Program
svenkugi 0:b6deec3905f4 496 pc.printf("STARTING SKAFMO BRUSHLESS MOTOR PROJECT! \n\r");
svenkugi 0:b6deec3905f4 497 led1 = 1;
svenkugi 0:b6deec3905f4 498
svenkugi 0:b6deec3905f4 499 //Run the motor synchronisation: orState is subtracted from future rotor state inputs
svenkugi 0:b6deec3905f4 500 orState = motorHome();
svenkugi 0:b6deec3905f4 501 //pc.printf("Synchronization Complete: Rotor and Motor aligned with Offset: %x\n\r",orState);
svenkugi 0:b6deec3905f4 502
svenkugi 0:b6deec3905f4 503 //Interrupts (Optical Disk State Change): Drives to next state, Measures whole revolution count, Measures angular velocity over a whole revolution
svenkugi 0:b6deec3905f4 504 InterruptI1.rise(&changestate_isr);
svenkugi 0:b6deec3905f4 505 InterruptI1.fall(&changestate_isr);
svenkugi 0:b6deec3905f4 506 InterruptI2.rise(&changestate_isr);
svenkugi 0:b6deec3905f4 507 InterruptI2.fall(&changestate_isr);
svenkugi 0:b6deec3905f4 508 InterruptI3.rise(&changestate_isr);
svenkugi 0:b6deec3905f4 509 InterruptI3.fall(&changestate_isr);
svenkugi 0:b6deec3905f4 510
svenkugi 0:b6deec3905f4 511 //Interrupts (Incremental Encoder CHA Phase)
svenkugi 0:b6deec3905f4 512 InterruptCHA.rise(&pid_isr);
svenkugi 0:b6deec3905f4 513
svenkugi 3:7ee013b0976e 514 // Melody in a Thread
svenkugi 3:7ee013b0976e 515 // PID in Thread
svenkugi 0:b6deec3905f4 516
svenkugi 4:5eb8ac894d0f 517 position_control(350.34, 2.0); // Second parameter is 1 or -1 (Backwards or Forwards Rotation)
svenkugi 3:7ee013b0976e 518
svenkugi 3:7ee013b0976e 519 }