Julius Bernth / Mbed OS Cuvette_Centrifuge_Test_v1-2_ParallelMode

Dependencies:   QEI LIS3DH_spi

Committer:
juliusbernth
Date:
Sun Aug 08 14:47:14 2021 +0000
Revision:
3:4f215646a42b
Parent:
2:da51e13f4ddf
Child:
4:d04afc466198
Updated to include all basic functions.

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