Julius Bernth / Mbed OS Cuvette_Centrifuge_Test_v1-2_ParallelMode

Dependencies:   QEI LIS3DH_spi

Committer:
juliusbernth
Date:
Thu Aug 12 15:47:50 2021 +0000
Revision:
12:bc34f264e2f2
Parent:
11:62d2a592b1ae
Child:
13:32e1ae4221f7
Working with Estop;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
juliusbernth 0:64442857169c 1 /* mbed Microcontroller Library
juliusbernth 0:64442857169c 2 * Copyright (c) 2019 ARM Limited
juliusbernth 0:64442857169c 3 * SPDX-License-Identifier: Apache-2.0
juliusbernth 0:64442857169c 4 */
juliusbernth 0:64442857169c 5
juliusbernth 0:64442857169c 6 #include "mbed.h"
juliusbernth 0:64442857169c 7 #include "platform/mbed_thread.h"
juliusbernth 0:64442857169c 8 #include "Settings.h"
juliusbernth 0:64442857169c 9 #include "QEI.h"
juliusbernth 7:e36f61608c10 10 #include "math.h"
juliusbernth 0:64442857169c 11 //#include "LIS3DH.h"
juliusbernth 0:64442857169c 12
juliusbernth 0:64442857169c 13 /*
juliusbernth 0:64442857169c 14 Open issues:
juliusbernth 5:e9bb800a3742 15 - need to figure out how to handle transitions to error states
juliusbernth 5:e9bb800a3742 16 - Need to test how breaking is performed.
juliusbernth 5:e9bb800a3742 17 -Test onboard current limitation
juliusbernth 0:64442857169c 18 */
juliusbernth 0:64442857169c 19
juliusbernth 0:64442857169c 20 Timer encoderTimer;
juliusbernth 0:64442857169c 21 Timer buttonTimer;
juliusbernth 0:64442857169c 22 Timer testTimer;
juliusbernth 0:64442857169c 23
juliusbernth 0:64442857169c 24 Timeout buttonTimeout;
juliusbernth 0:64442857169c 25
juliusbernth 0:64442857169c 26 Thread PrintThread(osPriorityAboveNormal);
juliusbernth 0:64442857169c 27 Thread CentrifugeTestThread(osPriorityHigh);
juliusbernth 0:64442857169c 28 Thread ReadButtonThread(osPriorityNormal);
juliusbernth 0:64442857169c 29 Thread MotorControlThread(osPriorityRealtime);
juliusbernth 0:64442857169c 30
juliusbernth 0:64442857169c 31 double SPIN_T[6]; //times for spin cycle
juliusbernth 0:64442857169c 32
juliusbernth 0:64442857169c 33 QEI encoder(PA_14, PA_13, PA_15, 256, QEI::X4_ENCODING);
juliusbernth 0:64442857169c 34
juliusbernth 0:64442857169c 35 //LIS3DH accel = LIS3DH(SPI_MOSI, SPI_MISO, SPI_SCLK, SPI_CS,LIS3DH_DR_NR_LP_400HZ, LIS3DH_FS_2G);
juliusbernth 0:64442857169c 36
juliusbernth 0:64442857169c 37 DigitalOut EN_FAULTA (D2);
juliusbernth 0:64442857169c 38 DigitalOut STBY (D8);
juliusbernth 0:64442857169c 39 DigitalOut PHA (D3);
juliusbernth 9:b1f53e4eb453 40 //DigitalOut PHB (D7);
juliusbernth 0:64442857169c 41 PwmOut PWMA (D5);
juliusbernth 9:b1f53e4eb453 42 //PwmOut PWMB (D4);
juliusbernth 0:64442857169c 43 PwmOut REF_PWM_A (D15);
juliusbernth 0:64442857169c 44 PwmOut REF_PWM_B (D14);
juliusbernth 7:e36f61608c10 45 AnalogIn pinAx(A0);
juliusbernth 7:e36f61608c10 46 AnalogIn pinAy(A1);
juliusbernth 7:e36f61608c10 47 AnalogIn pinAz(A2);
juliusbernth 7:e36f61608c10 48
juliusbernth 9:b1f53e4eb453 49 DigitalOut PHB (D7);
juliusbernth 9:b1f53e4eb453 50 DigitalOut EN_FAULTB (D11);
juliusbernth 9:b1f53e4eb453 51 PwmOut PWMB (D4);
juliusbernth 9:b1f53e4eb453 52 PwmOut REF_PWMB (D14);
juliusbernth 9:b1f53e4eb453 53
juliusbernth 7:e36f61608c10 54 DigitalOut pinSt(A3);
juliusbernth 0:64442857169c 55
juliusbernth 0:64442857169c 56 Serial pc(USBTX,USBRX);
juliusbernth 0:64442857169c 57
juliusbernth 0:64442857169c 58 DigitalOut pinStatusLED (D13);
juliusbernth 8:41cd1fc8cbbe 59
juliusbernth 8:41cd1fc8cbbe 60 DigitalIn pinButton (PC_8);
juliusbernth 8:41cd1fc8cbbe 61 DigitalOut pinLedWhite (PC_6);
juliusbernth 8:41cd1fc8cbbe 62 DigitalOut pinLedRed (PC_5);
juliusbernth 0:64442857169c 63
juliusbernth 0:64442857169c 64 /* Still to allocate
juliusbernth 0:64442857169c 65
juliusbernth 0:64442857169c 66 DigitalOut pinBuzzer
juliusbernth 0:64442857169c 67 DigitalOut pinPowerLED
juliusbernth 0:64442857169c 68
juliusbernth 0:64442857169c 69 */
juliusbernth 0:64442857169c 70
juliusbernth 0:64442857169c 71 //global variables
juliusbernth 0:64442857169c 72 double speedFilterConstant;
juliusbernth 5:e9bb800a3742 73 char state;
juliusbernth 0:64442857169c 74 double currentPulses;
juliusbernth 0:64442857169c 75 double lastPulses;
juliusbernth 0:64442857169c 76 double lastSpeedRPM;
juliusbernth 0:64442857169c 77 double Tnow;
juliusbernth 5:e9bb800a3742 78 double demandSpeed_RPM = 0.0;
juliusbernth 5:e9bb800a3742 79 double currentSpeedRPM;
juliusbernth 0:64442857169c 80 double deltaError;
juliusbernth 0:64442857169c 81 double lastError;
juliusbernth 0:64442857169c 82 double integralTerm;
juliusbernth 0:64442857169c 83 double output;
juliusbernth 0:64442857169c 84
juliusbernth 9:b1f53e4eb453 85 double _MagFil;
juliusbernth 9:b1f53e4eb453 86
juliusbernth 0:64442857169c 87 Ticker tickerMotorControl;
juliusbernth 0:64442857169c 88 Ticker tickerPrint;
juliusbernth 0:64442857169c 89 Ticker tickerReleaseButton;
juliusbernth 0:64442857169c 90
juliusbernth 0:64442857169c 91 Semaphore semMotorControl(0);
juliusbernth 0:64442857169c 92 Semaphore semPrint(0);
juliusbernth 0:64442857169c 93 Semaphore semStartTest(0);
juliusbernth 0:64442857169c 94 Semaphore semButton(0);
juliusbernth 0:64442857169c 95
juliusbernth 3:4f215646a42b 96 Mutex mut1;
juliusbernth 0:64442857169c 97
juliusbernth 0:64442857169c 98 double LimitDouble(double input, double min, double max){
juliusbernth 0:64442857169c 99 double output;
juliusbernth 0:64442857169c 100 output = input;
juliusbernth 0:64442857169c 101 if (input > max){
juliusbernth 0:64442857169c 102 output = max;
juliusbernth 0:64442857169c 103 }
juliusbernth 0:64442857169c 104 if (input < min){
juliusbernth 0:64442857169c 105 output = min;
juliusbernth 0:64442857169c 106 }
juliusbernth 0:64442857169c 107 return output;
juliusbernth 0:64442857169c 108 }
juliusbernth 0:64442857169c 109 /*
juliusbernth 0:64442857169c 110 double GetSpeed(int pulses, int lastPulses, double currentSpeed){
juliusbernth 0:64442857169c 111 double filteredSpeedRPM;
juliusbernth 0:64442857169c 112
juliusbernth 0:64442857169c 113 //find change in pulses.
juliusbernth 0:64442857169c 114 double speedRPM = (double) (pulses - lastPulses); //get change in angle
juliusbernth 0:64442857169c 115 speedRPM /= encoderTimer.read_us(); //calculate speed in pulses/us
juliusbernth 0:64442857169c 116 encoderTimer.reset();
juliusbernth 0:64442857169c 117 speedRPM *= 60000000.0/PULSES_PER_REV/4.0;//convert to RPM;
juliusbernth 0:64442857169c 118
juliusbernth 0:64442857169c 119 //filter speed
juliusbernth 0:64442857169c 120 //filteredSpeedRPM = speedFilterConstant * speedRPM + currentSpeed - speedFilterConstant * currentSpeed;
juliusbernth 0:64442857169c 121 filteredSpeedRPM = speedRPM;
juliusbernth 0:64442857169c 122 return filteredSpeedRPM;
juliusbernth 0:64442857169c 123 }*/
juliusbernth 0:64442857169c 124
juliusbernth 0:64442857169c 125
juliusbernth 0:64442857169c 126 void PIDControl(){
juliusbernth 0:64442857169c 127
juliusbernth 0:64442857169c 128 }
juliusbernth 0:64442857169c 129
juliusbernth 0:64442857169c 130 void TestCompleteNotification(){
juliusbernth 0:64442857169c 131 //send message
juliusbernth 0:64442857169c 132 printf("\r\nTest complete\r\n");
juliusbernth 0:64442857169c 133 //sound buzzer and blink 3 times
juliusbernth 0:64442857169c 134 }
juliusbernth 0:64442857169c 135
juliusbernth 0:64442857169c 136 void MotorControlRelease(){
juliusbernth 0:64442857169c 137 semMotorControl.release();
juliusbernth 0:64442857169c 138 }
juliusbernth 0:64442857169c 139 void PrintRelease(){
juliusbernth 0:64442857169c 140 semPrint.release();
juliusbernth 0:64442857169c 141 }
juliusbernth 0:64442857169c 142
juliusbernth 5:e9bb800a3742 143 void PrintTimeRemaining(){
juliusbernth 0:64442857169c 144 while(1){
juliusbernth 0:64442857169c 145 semPrint.wait();
juliusbernth 5:e9bb800a3742 146 if(state == STATE_RUNNING){
juliusbernth 0:64442857169c 147 double timeElapsed = testTimer.read();
juliusbernth 0:64442857169c 148 double timeRemaining = SPIN_T[5] - timeElapsed;
juliusbernth 0:64442857169c 149 int displayTime = int(timeRemaining)+1;
juliusbernth 12:bc34f264e2f2 150 //printf("Time remaining %d s\r\n", displayTime);
juliusbernth 7:e36f61608c10 151 //mut1.lock();
juliusbernth 5:e9bb800a3742 152 double printDemandSpeed = demandSpeed_RPM;
juliusbernth 5:e9bb800a3742 153 double printCurrentSpeed = currentSpeedRPM;
juliusbernth 7:e36f61608c10 154 //mut1.unlock();
juliusbernth 9:b1f53e4eb453 155 //printf("%f\t%f\r\n", currentSpeedRPM,_MagFil);
juliusbernth 12:bc34f264e2f2 156 printf("%f\t%f\r\n", printDemandSpeed,printCurrentSpeed);
juliusbernth 12:bc34f264e2f2 157 //printf("%f\r\n",_MagFil);
juliusbernth 12:bc34f264e2f2 158 }
juliusbernth 12:bc34f264e2f2 159 if(state == STATE_ERROR){
juliusbernth 12:bc34f264e2f2 160 double timeElapsed = testTimer.read();
juliusbernth 12:bc34f264e2f2 161 double timeRemaining = SPIN_T[5] - timeElapsed;
juliusbernth 12:bc34f264e2f2 162 int displayTime = int(timeRemaining)+1;
juliusbernth 12:bc34f264e2f2 163 //printf("Time remaining %d s\r\n", displayTime);
juliusbernth 12:bc34f264e2f2 164 //mut1.lock();
juliusbernth 12:bc34f264e2f2 165 double printDemandSpeed = demandSpeed_RPM;
juliusbernth 12:bc34f264e2f2 166 double printCurrentSpeed = currentSpeedRPM;
juliusbernth 12:bc34f264e2f2 167 //mut1.unlock();
juliusbernth 12:bc34f264e2f2 168 //printf("%f\t%f\r\n", currentSpeedRPM,_MagFil);
juliusbernth 12:bc34f264e2f2 169 printf("%f\t%f\r\n", printDemandSpeed,printCurrentSpeed);
juliusbernth 9:b1f53e4eb453 170 //printf("%f\r\n",_MagFil);
juliusbernth 3:4f215646a42b 171 }
juliusbernth 3:4f215646a42b 172 }
juliusbernth 3:4f215646a42b 173 }
juliusbernth 3:4f215646a42b 174
juliusbernth 0:64442857169c 175 void MotorControl(){
juliusbernth 9:b1f53e4eb453 176 double Ax, Ay, Az, Mag;
juliusbernth 9:b1f53e4eb453 177 static double MagFil, lastAx, lastAy, lastAz;
juliusbernth 9:b1f53e4eb453 178 static double lastErrorDot;
juliusbernth 0:64442857169c 179 while(1){
juliusbernth 0:64442857169c 180 semMotorControl.wait();//wait for a signal
juliusbernth 12:bc34f264e2f2 181
juliusbernth 12:bc34f264e2f2 182 pinLedRed = 1;
juliusbernth 12:bc34f264e2f2 183 Tnow = testTimer.read();
juliusbernth 12:bc34f264e2f2 184 //check accel. If problem, change state to ERROR
juliusbernth 12:bc34f264e2f2 185 //check accel here
juliusbernth 12:bc34f264e2f2 186
juliusbernth 12:bc34f264e2f2 187 /*
juliusbernth 12:bc34f264e2f2 188 Ax = 0.2*pinAx.read() + 0.8*Ax - 0.5;
juliusbernth 12:bc34f264e2f2 189 Ay = 0.2*pinAy.read() + 0.8*Ay - 0.5;
juliusbernth 12:bc34f264e2f2 190 Az = 0.2*pinAz.read() + 0.8*Az - 0.5;
juliusbernth 12:bc34f264e2f2 191 */
juliusbernth 12:bc34f264e2f2 192
juliusbernth 12:bc34f264e2f2 193 Ax = pinAx.read() - 0.5;
juliusbernth 12:bc34f264e2f2 194 Ay = pinAy.read() - 0.5;
juliusbernth 12:bc34f264e2f2 195 Az = pinAz.read() - 0.5;
juliusbernth 12:bc34f264e2f2 196
juliusbernth 12:bc34f264e2f2 197
juliusbernth 12:bc34f264e2f2 198 //read accel
juliusbernth 12:bc34f264e2f2 199 Mag = Ax*Ax + Ay*Ay;
juliusbernth 12:bc34f264e2f2 200 Mag = sqrt(Mag);
juliusbernth 12:bc34f264e2f2 201 //Mag *=ACCEL_SCALE;
juliusbernth 12:bc34f264e2f2 202 MagFil = 0.1*Mag + 0.9*MagFil;
juliusbernth 12:bc34f264e2f2 203 _MagFil = MagFil;
juliusbernth 12:bc34f264e2f2 204 if (MagFil > VIBRATION_THRESHOLD){
juliusbernth 12:bc34f264e2f2 205 //mut1.lock();
juliusbernth 12:bc34f264e2f2 206 //state = STATE_ERROR;
juliusbernth 12:bc34f264e2f2 207 printf("Excess vibration detected\r\n");
juliusbernth 12:bc34f264e2f2 208 //mut1.unlock();
juliusbernth 12:bc34f264e2f2 209 }
juliusbernth 12:bc34f264e2f2 210 //int deltaT = encoderTimer.read();//read current time in seconds
juliusbernth 7:e36f61608c10 211 if(state == STATE_RUNNING){//need to check if this is the best condition to look for.
juliusbernth 0:64442857169c 212 //calculate current demand
juliusbernth 5:e9bb800a3742 213 if ( (SPIN_T[0] <= Tnow) && (Tnow < SPIN_T[1]) ) {//test is in warmup
juliusbernth 0:64442857169c 214 demandSpeed_RPM = 0.0;
juliusbernth 5:e9bb800a3742 215 //printf("warm up %f\r\n", demandSpeed_RPM);
juliusbernth 5:e9bb800a3742 216 //deactivate motor?
juliusbernth 0:64442857169c 217 }
juliusbernth 5:e9bb800a3742 218 if ((SPIN_T[1] <= Tnow)&&(Tnow < SPIN_T[2])){//test is in ramp up
juliusbernth 5:e9bb800a3742 219
juliusbernth 5:e9bb800a3742 220 double a = Tnow - SPIN_T[1];
juliusbernth 5:e9bb800a3742 221 demandSpeed_RPM = a * targetSpeed_RPM / T_RAMP;
juliusbernth 5:e9bb800a3742 222 //printf("ramp up %f\r\n", demandSpeed_RPM);
juliusbernth 5:e9bb800a3742 223 }
juliusbernth 5:e9bb800a3742 224 if ((SPIN_T[2] <= Tnow)&&(Tnow < SPIN_T[3])){//test is in coast
juliusbernth 5:e9bb800a3742 225 demandSpeed_RPM = targetSpeed_RPM;
juliusbernth 5:e9bb800a3742 226 //printf("coast %f\r\n", demandSpeed_RPM);
juliusbernth 4:d04afc466198 227 }
juliusbernth 5:e9bb800a3742 228 if ((SPIN_T[3] <= Tnow)&&(Tnow < SPIN_T[4])){//test is in ramp down
juliusbernth 5:e9bb800a3742 229 double a = Tnow - SPIN_T[3];
juliusbernth 5:e9bb800a3742 230 demandSpeed_RPM = targetSpeed_RPM - (a/T_RAMP*targetSpeed_RPM);
juliusbernth 5:e9bb800a3742 231 //printf("ramp down %f\r\n", demandSpeed_RPM);
juliusbernth 5:e9bb800a3742 232 }
juliusbernth 5:e9bb800a3742 233 if ((SPIN_T[4] <= Tnow)&&(Tnow < SPIN_T[5])){//test is in cooldown
juliusbernth 5:e9bb800a3742 234 demandSpeed_RPM = 0.0;
juliusbernth 5:e9bb800a3742 235 //printf("cool down %f\r\n", demandSpeed_RPM);
juliusbernth 5:e9bb800a3742 236 //deactivate motor?
juliusbernth 4:d04afc466198 237 }
juliusbernth 12:bc34f264e2f2 238 }
juliusbernth 7:e36f61608c10 239
juliusbernth 12:bc34f264e2f2 240 if(state == STATE_ERROR){
juliusbernth 11:62d2a592b1ae 241 demandSpeed_RPM -=66.7*SAMPLE_TIME_US/1000000;
juliusbernth 12:bc34f264e2f2 242 }
juliusbernth 12:bc34f264e2f2 243
juliusbernth 11:62d2a592b1ae 244
juliusbernth 7:e36f61608c10 245 demandSpeed_RPM = LimitDouble(demandSpeed_RPM,0.0,MAX_SPEED_RPM);//limit demand
juliusbernth 7:e36f61608c10 246 currentPulses = encoder.getPulses();//calculate current speed
juliusbernth 7:e36f61608c10 247 double deltaPulses = currentPulses - lastPulses;
juliusbernth 7:e36f61608c10 248 double speed_RPM = deltaPulses / SAMPLE_TIME_US * 1000000;//get in pulses per second
juliusbernth 7:e36f61608c10 249 speed_RPM *= 60/4/PULSES_PER_REV;//convert to RPM
juliusbernth 7:e36f61608c10 250
juliusbernth 9:b1f53e4eb453 251 currentSpeedRPM = 0.1*speed_RPM + 0.9*lastSpeedRPM;//filter speed
juliusbernth 5:e9bb800a3742 252
juliusbernth 7:e36f61608c10 253 double error = demandSpeed_RPM - currentSpeedRPM;//calculate error
juliusbernth 7:e36f61608c10 254 deltaError = error - lastError;
juliusbernth 7:e36f61608c10 255 double errorDot = deltaError/SAMPLE_TIME_US*1000000.0;
juliusbernth 9:b1f53e4eb453 256 errorDot = 0.1*errorDot + 0.9*lastErrorDot;
juliusbernth 7:e36f61608c10 257 integralTerm += error*Ki*SAMPLE_TIME_US/1000000.0;
juliusbernth 7:e36f61608c10 258 integralTerm = LimitDouble(integralTerm,-0.8, 0.8);
juliusbernth 7:e36f61608c10 259
juliusbernth 7:e36f61608c10 260 output = Kp * error; //calculate output
juliusbernth 7:e36f61608c10 261 output += integralTerm;
juliusbernth 7:e36f61608c10 262 output += Kd*errorDot;
juliusbernth 9:b1f53e4eb453 263 output += Ko*demandSpeed_RPM;
juliusbernth 7:e36f61608c10 264 output = LimitDouble(output,-1.0,1.0);
juliusbernth 7:e36f61608c10 265 //printf("wd:%f\t w:%f\t e:%f\t o:%f \r\n",demandSpeed_RPM, currentSpeedRPM, error, output);
juliusbernth 5:e9bb800a3742 266
juliusbernth 7:e36f61608c10 267 if(output >=0){//Set direction
juliusbernth 7:e36f61608c10 268 PHA.write(0);
juliusbernth 7:e36f61608c10 269 }else{
juliusbernth 7:e36f61608c10 270 PHA.write(1);
juliusbernth 7:e36f61608c10 271 output = -1*output;
juliusbernth 7:e36f61608c10 272 }
juliusbernth 11:62d2a592b1ae 273
juliusbernth 12:bc34f264e2f2 274 // if(state == STATE_ERROR){
juliusbernth 12:bc34f264e2f2 275 // output = 0;
juliusbernth 12:bc34f264e2f2 276 // }
juliusbernth 11:62d2a592b1ae 277
juliusbernth 7:e36f61608c10 278 PWMA.write(output);//write to motor
juliusbernth 7:e36f61608c10 279 lastPulses = currentPulses;//update
juliusbernth 7:e36f61608c10 280 lastError = error;
juliusbernth 7:e36f61608c10 281 lastSpeedRPM = currentSpeedRPM;
juliusbernth 9:b1f53e4eb453 282 lastErrorDot = errorDot;
juliusbernth 5:e9bb800a3742 283
juliusbernth 7:e36f61608c10 284 //exit when test has completed
juliusbernth 7:e36f61608c10 285 if (Tnow >= SPIN_T[5]){
juliusbernth 9:b1f53e4eb453 286 //printf("Terminating Test %f \t %f\r\n", Tnow, SPIN_T[5]);
juliusbernth 7:e36f61608c10 287 state = STATE_READY;//change state
juliusbernth 7:e36f61608c10 288 testTimer.stop(); //stop and reset timers
juliusbernth 7:e36f61608c10 289 testTimer.reset();
juliusbernth 7:e36f61608c10 290 Tnow = testTimer.read();
juliusbernth 7:e36f61608c10 291 encoderTimer.stop();
juliusbernth 7:e36f61608c10 292 encoderTimer.reset();
juliusbernth 9:b1f53e4eb453 293 PWMA.write(0.0);
juliusbernth 12:bc34f264e2f2 294
juliusbernth 12:bc34f264e2f2 295 //add check if motor has stopped
juliusbernth 9:b1f53e4eb453 296 ThisThread::sleep_for(500);
juliusbernth 7:e36f61608c10 297 EN_FAULTA.write(0);//disable motor
juliusbernth 9:b1f53e4eb453 298 EN_FAULTB.write(0);
juliusbernth 7:e36f61608c10 299
juliusbernth 7:e36f61608c10 300 tickerMotorControl.detach(); //detach the semaphore release for motor control
juliusbernth 7:e36f61608c10 301 tickerPrint.detach();
juliusbernth 7:e36f61608c10 302
juliusbernth 9:b1f53e4eb453 303 //printf("state = %d\r\n",state);
juliusbernth 8:41cd1fc8cbbe 304 pinLedRed = 0;
juliusbernth 7:e36f61608c10 305 TestCompleteNotification();//send notification
juliusbernth 9:b1f53e4eb453 306 lastErrorDot = 0.0;
juliusbernth 9:b1f53e4eb453 307 lastError = 0.0;
juliusbernth 9:b1f53e4eb453 308 integralTerm = 0.0;
juliusbernth 7:e36f61608c10 309 //deactivate motor
juliusbernth 7:e36f61608c10 310 //PrintThread.terminate();//terminate print thread
juliusbernth 7:e36f61608c10 311 //CentrifugeTestThread.terminate();//terminate threads
juliusbernth 7:e36f61608c10 312 }
juliusbernth 9:b1f53e4eb453 313
juliusbernth 12:bc34f264e2f2 314 //} //end running conditional
juliusbernth 12:bc34f264e2f2 315
juliusbernth 12:bc34f264e2f2 316 }//end while
juliusbernth 0:64442857169c 317 }
juliusbernth 0:64442857169c 318
juliusbernth 5:e9bb800a3742 319 void CentrifugeTest(){
juliusbernth 5:e9bb800a3742 320 while(1){
juliusbernth 5:e9bb800a3742 321 semStartTest.wait();
juliusbernth 0:64442857169c 322 printf("\r\n Test starting \r\n");
juliusbernth 5:e9bb800a3742 323 state = STATE_RUNNING;
juliusbernth 0:64442857169c 324 //set up test
juliusbernth 0:64442857169c 325 testTimer.reset();
juliusbernth 0:64442857169c 326 testTimer.start();//start timer
juliusbernth 0:64442857169c 327
juliusbernth 5:e9bb800a3742 328 char spinState;
juliusbernth 8:41cd1fc8cbbe 329 pinLedRed = 1;
juliusbernth 0:64442857169c 330 //set up ticker to allow motor control thread to run periodically
juliusbernth 5:e9bb800a3742 331
juliusbernth 0:64442857169c 332 encoder.reset();//reset encoder
juliusbernth 0:64442857169c 333 lastPulses = 0;//reset previous encoder reading
juliusbernth 5:e9bb800a3742 334 encoderTimer.start();
juliusbernth 5:e9bb800a3742 335 PrintThread.start(PrintTimeRemaining);
juliusbernth 11:62d2a592b1ae 336 printf("\r\n Test setup complete, State:%d \r\n", state);
juliusbernth 5:e9bb800a3742 337 EN_FAULTA.write(1);
juliusbernth 9:b1f53e4eb453 338 //EN_FAULTB.write(1);
juliusbernth 7:e36f61608c10 339 if(state == STATE_RUNNING){
juliusbernth 9:b1f53e4eb453 340 //printf("\r\n running %d\r\n",state);
juliusbernth 7:e36f61608c10 341 }
juliusbernth 0:64442857169c 342
juliusbernth 5:e9bb800a3742 343
juliusbernth 5:e9bb800a3742 344 }
juliusbernth 0:64442857169c 345 }
juliusbernth 0:64442857169c 346
juliusbernth 0:64442857169c 347 void ReleaseReadButton(){
juliusbernth 0:64442857169c 348 semButton.release();
juliusbernth 0:64442857169c 349 }
juliusbernth 0:64442857169c 350
juliusbernth 0:64442857169c 351 void ReadButton()
juliusbernth 0:64442857169c 352 {
juliusbernth 0:64442857169c 353 int countThreashold = int(BUTTON_HOLD_TIME_S/BUTTON_READ_SAMPLETIME_S);
juliusbernth 12:bc34f264e2f2 354 int errorBlinkCount;
juliusbernth 0:64442857169c 355 while (1)
juliusbernth 0:64442857169c 356 {
juliusbernth 0:64442857169c 357 semButton.wait();
juliusbernth 12:bc34f264e2f2 358
juliusbernth 12:bc34f264e2f2 359 if(state == STATE_ERROR){
juliusbernth 12:bc34f264e2f2 360
juliusbernth 12:bc34f264e2f2 361 }
juliusbernth 12:bc34f264e2f2 362
juliusbernth 0:64442857169c 363 int count = 0;
juliusbernth 9:b1f53e4eb453 364 int blinkCount = 0;
juliusbernth 9:b1f53e4eb453 365 pinLedRed = 0;
juliusbernth 8:41cd1fc8cbbe 366 while(pinButton.read())
juliusbernth 0:64442857169c 367 {
juliusbernth 0:64442857169c 368 count++;
juliusbernth 9:b1f53e4eb453 369 if(count < countThreashold){
juliusbernth 9:b1f53e4eb453 370 blinkCount++;
juliusbernth 9:b1f53e4eb453 371 if(blinkCount>=10){
juliusbernth 9:b1f53e4eb453 372 blinkCount = 0;
juliusbernth 9:b1f53e4eb453 373 pinLedRed = !pinLedRed;
juliusbernth 9:b1f53e4eb453 374 if(count == 1){
juliusbernth 9:b1f53e4eb453 375 pinLedRed = 0;
juliusbernth 9:b1f53e4eb453 376 }
juliusbernth 9:b1f53e4eb453 377 }
juliusbernth 9:b1f53e4eb453 378 }
juliusbernth 9:b1f53e4eb453 379 else{
juliusbernth 9:b1f53e4eb453 380 pinLedRed = 1;
juliusbernth 9:b1f53e4eb453 381 }
juliusbernth 0:64442857169c 382 if (count ==1){
juliusbernth 11:62d2a592b1ae 383 if(state == STATE_READY){
juliusbernth 11:62d2a592b1ae 384 printf("Button pressed. Hold for %f s\r\n",BUTTON_HOLD_TIME_S);
juliusbernth 11:62d2a592b1ae 385 }
juliusbernth 11:62d2a592b1ae 386 else if(state == STATE_RUNNING){
juliusbernth 12:bc34f264e2f2 387 printf("Test terminated by user. Slowing to stop. Please restart system when safe.\r\n");
juliusbernth 11:62d2a592b1ae 388 state = STATE_ERROR;
juliusbernth 11:62d2a592b1ae 389 }
juliusbernth 0:64442857169c 390 }
juliusbernth 0:64442857169c 391 ThisThread::sleep_for(10);
juliusbernth 0:64442857169c 392 }
juliusbernth 7:e36f61608c10 393 switch (state)
juliusbernth 0:64442857169c 394 {
juliusbernth 0:64442857169c 395 case STATE_READY:
juliusbernth 0:64442857169c 396 if(count > countThreashold)
juliusbernth 0:64442857169c 397 {
juliusbernth 9:b1f53e4eb453 398 pinLedRed = 1;
juliusbernth 9:b1f53e4eb453 399 //printf("button released count = %d\r\n",count);
juliusbernth 0:64442857169c 400 count = 0;
juliusbernth 0:64442857169c 401 //CentrifugeTestThread.start(CentrifugeTest);
juliusbernth 5:e9bb800a3742 402 semStartTest.release();
juliusbernth 0:64442857169c 403 tickerMotorControl.attach_us(&MotorControlRelease, SAMPLE_TIME_US);//set up signal for control frequency
juliusbernth 0:64442857169c 404 tickerPrint.attach(&PrintRelease,PRINT_TIME_S);
juliusbernth 9:b1f53e4eb453 405 }else{
juliusbernth 9:b1f53e4eb453 406 pinLedRed = 0;
juliusbernth 0:64442857169c 407 }
juliusbernth 0:64442857169c 408 break;
juliusbernth 0:64442857169c 409 case STATE_RUNNING:
juliusbernth 0:64442857169c 410 if(count >1){
juliusbernth 11:62d2a592b1ae 411 //EN_FAULTA.write(0);
juliusbernth 11:62d2a592b1ae 412 // EN_FAULTB.write(0);
juliusbernth 9:b1f53e4eb453 413 state = STATE_ERROR;
juliusbernth 9:b1f53e4eb453 414 //EN_FAULTB.write(0);
juliusbernth 0:64442857169c 415 }
juliusbernth 0:64442857169c 416 break;
juliusbernth 0:64442857169c 417
juliusbernth 0:64442857169c 418 case STATE_ERROR:
juliusbernth 9:b1f53e4eb453 419 //printf("Please restart the system. \r\n");
juliusbernth 12:bc34f264e2f2 420 errorBlinkCount++;
juliusbernth 12:bc34f264e2f2 421 if(errorBlinkCount >=50){
juliusbernth 12:bc34f264e2f2 422 errorBlinkCount = 0;
juliusbernth 12:bc34f264e2f2 423 pinLedRed = !pinLedRed;
juliusbernth 12:bc34f264e2f2 424 }
juliusbernth 0:64442857169c 425 break;
juliusbernth 0:64442857169c 426 default:
juliusbernth 0:64442857169c 427 break;
juliusbernth 0:64442857169c 428 }
juliusbernth 0:64442857169c 429 count = 0;
juliusbernth 5:e9bb800a3742 430 ThisThread::sleep_for(100);
juliusbernth 0:64442857169c 431 }
juliusbernth 0:64442857169c 432 }
juliusbernth 0:64442857169c 433
juliusbernth 0:64442857169c 434 int main(){
juliusbernth 0:64442857169c 435 printf("\r\nSystem Online\r\n");
juliusbernth 0:64442857169c 436 //set up system
juliusbernth 0:64442857169c 437
juliusbernth 0:64442857169c 438 //set up motor
juliusbernth 0:64442857169c 439 //EN_FAULTA.mode(PullDown);
juliusbernth 0:64442857169c 440 //STBY.mode(PullDown);
juliusbernth 0:64442857169c 441
juliusbernth 0:64442857169c 442 REF_PWM_A.period_us(100);
juliusbernth 9:b1f53e4eb453 443 PWMA.period_us(33);
juliusbernth 9:b1f53e4eb453 444 REF_PWM_A.write(0.1);//set current reference
juliusbernth 9:b1f53e4eb453 445
juliusbernth 9:b1f53e4eb453 446 REF_PWMB.period_us(100);
juliusbernth 9:b1f53e4eb453 447 PWMB.period_us(33);
juliusbernth 9:b1f53e4eb453 448 REF_PWMB.write(0.0);
juliusbernth 9:b1f53e4eb453 449 PHB.write(0);
juliusbernth 9:b1f53e4eb453 450 EN_FAULTB.write(0);
juliusbernth 0:64442857169c 451
juliusbernth 0:64442857169c 452 EN_FAULTA.write(0);
juliusbernth 0:64442857169c 453 STBY.write(1);
juliusbernth 0:64442857169c 454 //calculate filter constant
juliusbernth 0:64442857169c 455 speedFilterConstant = 2*3.141593*SAMPLE_TIME_US/1000000*FILTER_CUTOFF_FREQ;
juliusbernth 0:64442857169c 456 speedFilterConstant /= (1 + speedFilterConstant);
juliusbernth 0:64442857169c 457
juliusbernth 0:64442857169c 458 SPIN_T[0] = 0.0;
juliusbernth 0:64442857169c 459 SPIN_T[1] = T_WARMUP;
juliusbernth 0:64442857169c 460 SPIN_T[2] = T_WARMUP + T_RAMP;
juliusbernth 0:64442857169c 461 SPIN_T[3] = T_WARMUP + T_RAMP + T_TEST;
juliusbernth 0:64442857169c 462 SPIN_T[4] = T_WARMUP + T_RAMP + T_TEST + T_RAMP;
juliusbernth 0:64442857169c 463 SPIN_T[5] = T_WARMUP + T_RAMP + T_TEST + T_RAMP + T_WARMUP;
juliusbernth 0:64442857169c 464
juliusbernth 0:64442857169c 465 /* //set up button interrupts
juliusbernth 0:64442857169c 466 pinButton.rise(ISR_Button_Rise);
juliusbernth 0:64442857169c 467 pinButton.fall(ISR_Button_Fall);
juliusbernth 0:64442857169c 468 */
juliusbernth 8:41cd1fc8cbbe 469 pinButton.mode(PullDown);
juliusbernth 8:41cd1fc8cbbe 470 pinLedWhite = 1;
juliusbernth 8:41cd1fc8cbbe 471
juliusbernth 8:41cd1fc8cbbe 472
juliusbernth 5:e9bb800a3742 473
juliusbernth 5:e9bb800a3742 474 state = STATE_READY;//set state to READY
juliusbernth 0:64442857169c 475 //start all threads
juliusbernth 0:64442857169c 476 MotorControlThread.start(MotorControl);
juliusbernth 0:64442857169c 477
juliusbernth 5:e9bb800a3742 478 CentrifugeTestThread.start(CentrifugeTest);
juliusbernth 0:64442857169c 479 //start print thread.
juliusbernth 0:64442857169c 480
juliusbernth 0:64442857169c 481 ReadButtonThread.start(ReadButton);
juliusbernth 0:64442857169c 482 tickerReleaseButton.attach(ReleaseReadButton,BUTTON_READ_SAMPLETIME_S);
juliusbernth 0:64442857169c 483
juliusbernth 0:64442857169c 484
juliusbernth 0:64442857169c 485 printf("\r\nSetup Complete\r\n");
juliusbernth 0:64442857169c 486 while (true) {
juliusbernth 0:64442857169c 487 //check state of button
juliusbernth 0:64442857169c 488 ThisThread::sleep_for(osWaitForever);
juliusbernth 0:64442857169c 489 }
juliusbernth 0:64442857169c 490 }