Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: HIDScope MODSERIAL QEI TextLCD mbed
Fork of TotalControlEmg2 by
Diff: main.cpp
- Revision:
- 34:60391fb72629
- Parent:
- 33:b4757132437e
- Child:
- 35:012b2e045579
--- a/main.cpp Mon Oct 19 20:14:13 2015 +0000 +++ b/main.cpp Tue Oct 20 08:26:10 2015 +0000 @@ -17,7 +17,7 @@ AnalogIn potL(A2), potR(A3); // Potential meter left and right AnalogIn KS(A4); // Killswitch HIDScope scope(6); // Hidscope, amount of scopes -Ticker EMGticker, tickerControl, tickerBreak; // Ticker for EMG, regulator and break +Ticker EMGticker, tickerControl, tickerBreak, tickerLcd; // Ticker for EMG, regulator and break // QEI Encoder(port 1, port 2, ,counts/rev QEI enc1 (D13, D12, NC, 64), enc2 (D11, D10, NC, 64); // Motor1 met PWM power control and direction @@ -26,16 +26,16 @@ // Motor2 met PWM power control and direction PwmOut pwmM2(D5); DigitalOut dirM2(D4); -enum spelfase {KALIBRATE_EMG, KALIBRATE_AIM, KALIBRATE_PEND, AIM, BREAK, FIRE}; // Proframstates, ACKNOWLEDGEMENT switch: BMT groep 4 2014 -uint8_t state = KALIBRATE_EMG; // first state program +enum spelfase {CALIBRATE_EMG, CALIBRATE_AIM, CALIBRATE_PEND, AIM, BREAK, FIRE}; // Proframstates, ACKNOWLEDGEMENT switch: BMT groep 4 2014 +uint8_t state = CALIBRATE_EMG; // first state program enum aimFase {OFF, CW, CCW}; // Aim motor possible states uint8_t aimState = OFF; // first state aim motor //-------------------------------Variables--------------------------------------------------------------------- const int on = 0, off = 1; // on off -int maxCounts = 42000; // max richt motor counts Aim motor +int maxCounts = 13000; // max richt motor counts Aim motor int breakPerc = 0; const double servoL = 0.001, servoR = 0.0011; // Range servo,between servoL en servoR (= pulsewidth pwm servo) -const double tControl = 0.005, tBreak = 0.1; // ticker for motor checking +const double tControl = 0.005, tBreak = 0.1, tLcd = 1; // tickers const double Fs = 50; //Sample frequency Hz double t = 1/ Fs; // time EMGticker double thresholdlowL= 0, thresholdmidL = 0, thresholdhighL= 0; @@ -43,7 +43,7 @@ double yL = 0, yR = 0; // y values EMG left and right volatile bool L = false, R = false; // Booleans for checking if mode. has been 1? volatile bool btn = false; // Button is pressed? -volatile bool controlFlag = false, btnFlag = false, breakFlag = false, emgFlag = false; // Go flags +volatile bool controlFlag = false, btnFlag = false, breakFlag = false, emgFlag = false, lcdFlag = false; // Go flags //----------------------------Functions----------------------------------------------------------------------- void flipLed(DigitalOut& led){ //function to flip one LED led.write(on); @@ -54,12 +54,13 @@ lcd.cls(); // clear LCD scherm lcd.printf(text); // print text op lcd } -void EMGkalibratieL(){ // Determine thresholds left - LedB = 1; - Init(); - double ymin = KalibratieMin(emgL, true); +void EMGkalibratieL(){ // Determine thresholds left + PRINT("EMG LEFT relax muscle"); + double ymin = KalibratieMin(emgL, true); // Minimum value left EMG, boolean indicates left wait(1); - double ymax = KalibratieMax(emgL, true); + PRINT("EMG LEFT flex muscle"); // LCD + double ymax = KalibratieMax(emgL, true); // Maxium value left EMG, boolean indicates left + PRINT("EMG LEFT well done!"); // LCD if((ymax-ymin) < 0.05){ // No EMG connected ymin = 10; @@ -72,11 +73,12 @@ pc.printf("ymaxL = %f en yminL = %f \r\n",ymax, ymin); } void EMGkalibratieR(){ // Determine thresholds right EMG, same as left - LedB = 1; - Init(); + PRINT("EMG RIGHT relax muscle"); double ymin = KalibratieMin(emgR, false); wait(1); + PRINT("EMG RIGHT flex muscle"); double ymax = KalibratieMax(emgR, false); + PRINT("EMG LEFT well done!"); if((ymax-ymin) < 0.05){ ymin = 10; @@ -128,7 +130,10 @@ } void setEmgFlag(){ // Goflag EMG emgFlag = true; - } + } +void setLcdFlag(){ // Goflag EMG + lcdFlag = true; + } void btnSetAction(){ // Set knop K64F btn = true; // GoFlag setknop } @@ -140,7 +145,7 @@ } void checkAim(){ // check if Killswitch is on or max counts is reached double volt = KS.read(); - if(volt> 0.5 || abs(enc2.getPulses()) > maxCounts*/){ + if(volt> 0.5 || abs(enc2.getPulses()) > (maxCounts -50) || enc2.getPulses() < 0){ pwmM2.write(0); // Aim motor freeze pc.printf("BOEM! CRASH! KASTUK! \r\n"); // Terminal PRINT("BOEM! CRASH!"); // LCD @@ -175,7 +180,7 @@ if(aimState!=OFF){ // only if aim motor is rotating pwmM2.write(0); // Aim motor freeze aimState = OFF; // motor state is off - PRINT("Motor freeze\r\n"); // LCD + pc.printf("Motor freeze\r\n"); // LCD L = false; // Modes must be first 1 for another action R = false; // "" } @@ -183,14 +188,14 @@ else if((modeL == 2) && (aimState != CCW && (modeR == 1))) { // modeL ==2 AND rotation is not CCW AND modeR has been 1 if(L){ aimState = CCW; // Rotate CCW - pc.printf("Rotate -, CCW"); + pc.printf("Rotate -, CCW\r\n"); motorAim(0); } } else if((modeR == 2) && (aimState != CW && (modeL == 1))) { // modeR == 2 AND rotation is not CW AND modeL has been 1 if(R){ aimState = CW; // Rotate CW - PRINT("Rotate +, CW"); + pc.printf("Rotate +, CW\r\n"); motorAim(1); } } @@ -203,98 +208,107 @@ tickerControl.attach(&setControlFlag,tControl); // ticker control motor tickerBreak.attach(&setBreakFlag,tBreak); // ticker break EMGticker.attach(&setEmgFlag, t); // ticker EMG, 500H + tickerLcd.attach(&setLcdFlag,tLcd); // ticker lcd pc.printf("\n\n\n\n\n"); // Terminal - pc.prinft("---NEW GAME---\r\n) + pc.printf("---NEW GAME---\r\n"); PRINT("--- NEW GAME ---"); // LCD while(1){ // Run program switch(state){ - case KALIBRATE_EMG: { - pc.printf("Kalibrate EMG left in 5 seconds\r\n"); // Terminal - PRINT("EMG LEFT MAX MIN"); // LCD - EMGkalibratieL(); // Kalibrate left EMG, determine thresholds - - pc.printf("Kalibrate EMG right in 5 seconds\r\n"); // Terminal - PRINT("EMG RIGHT MAX MIN"); // LCD - EMGkalibratieR(); // Kalibrate right EMG, determine thresholds - - state = KALIBRATE_AIM; // Next state + case CALIBRATE_EMG: { + EMGkalibratieL(); // calibrate left EMG, determine thresholds + EMGkalibratieR(); // calibrate right EMG, determine thresholds + state = CALIBRATE_AIM; // Next state break; } - case KALIBRATE_AIM: { + case CALIBRATE_AIM: { pwmM2.period(1/100000); // period motor 2 printf("Position is kalibrating\r\n"); // terminal PRINT("Wait a moment, please"); // LCD dirM2.write(0); // direction aim motor pwmM2.write(0.25); // percentage motor power - bool kalibrated = false; - while(state==KALIBRATE_AIM){ + bool calibrated = false; // + while(state==CALIBRATE_AIM){ pc.printf("Killswitch: %f\r\n", KS.read()); // terminal - if(KS.read() > 0.5){ // Killswitch? + if(KS.read() > 0.5 && !calibrated){ // Killswitch? pwmM2.write(0); // Aim motor freeze enc2.reset(); // Reset encoder - PRINT("Aim kalibrated"); - //state = KALIBRATE_PEND; // next state - kalibrated = true; + PRINT("Aim calibrated"); // LCD + calibrated = true; // dirM2.write(0); // direction aim motor pwmM2.write(0.25); // percentage motor power, turn it on - } - - if(controlFlag && kalibrated){ // motor regelen op GoFlag + } + if(controlFlag && calibrated){ // motor regelen op GoFlag controlFlag = false; - if(enc.getPulses() > maxCounts/2){ // rotate aim motor to midi position + if(enc1.getPulses() > maxCounts/2){ // rotate aim motor to midi position pwmM2.write(0); // Aim motor freeze - state = KALIBRATE_PEND; // next state + state = CALIBRATE_PEND; // next state } } } break; } - case KALIBRATE_PEND: { - pc.printf("Kalibrate pendulum motor with setknop\r\n"); - pwmM1.period(1/100000); // periode pendulum motor + case CALIBRATE_PEND: { + pc.printf("Calibrate beam motor with setknop\r\n"); // Terminal + pwmM1.period(1/100000); // period beam motor servo.period(0.02); // 20ms period servo - pwmM1.write(0.25); // Turn motor on, low power - btn = false; - R = false; - L = false; - while(state==KALIBRATE_PEND){ + //pwmM1.write(0.25); // Turn motor on, low power + btn = false; // Button is unpressed + R = false; // modeR must become 1 + L = false; // modeL must become 1 + PRINT("Calibrate beam"); + wait(1); + PRINT("Flex right half to swing beam"); + while(state==CALIBRATE_PEND){ if(emgFlag){ pc.printf(""); // lege regel printen, anders doet setknop het niet emgFlag = false; - int modeL = defMode(emgL, potL, true); - int modeR = defMode(emgR, potR, false); + int modeL = defMode(emgL, potL, true); // determine modeL + int modeR = defMode(emgR, potR, false); // determine modeR if(modeR < 2) { // modeR == 1 R = true; } if(modeL < 2) { // modeL == 1 L = true; - } - + } if (btn || (modeL == 3 && L) || (modeR == 3 && R)){ // If setbutton is on or one mode is 3, and has been 1 pwmM1.write(0); // Motor 1 freeze enc1.reset(); // encoder 1 reset - PRINT("Pendulum kalibrated\r\n"); + PRINT("Beam calibrated"); btn = false; // button op false state = AIM; // next state } else if(modeL == 2){ - pwmM1.write(0); // Pendulum freeze - PRINT("Pendulum off\r\n"); + pwmM1.write(0); // beam freeze + PRINT("Flex both full to continue"); // LCD } - else if(modeL == 3){ - pwmM1.write(0.025); // Pendulum rotate - PRINT("Pendulum on\r\n"); + else if(modeR == 2){ + pwmM1.write(0.025); // beam rotate + PRINT("Flex left half to stop beam"); // LCD } } } break; } case AIM: { - pc.printf("Aim with EMG\r\n"); - while(state == AIM){ + pc.printf("Aim with EMG\r\n"); // terminal + int i = 0; // counter for lcd + while(state == AIM){ + if(lcdFlag){ + if(i%3 == 0){ + PRINT("Flex left or right half to aim"); + } + else if(i%3 == 1){ + PRINT("Flex both half to freeze"); + } + else { + PRINT("Flex both full to continue"); + } + i++; + } + if(controlFlag){ // motor control on GoFlag controlFlag = false; checkAim(); // Check position @@ -303,7 +317,7 @@ emgFlag = false; if(controlAim()){ pc.printf("Position choosen, adjust shoot velocity\r\n"); - state = REM; // Next state (BREAK) + state = BREAK; // Next state (BREAK) } } } @@ -350,7 +364,8 @@ } if(modeL > 1 || modeR > 1){ // Print BREAK scale if one of both modes > 1 pc.printf("Current breaking scale: %i\r\n", breakPerc); - PRINT("Break scale is: %i", breakPerc); + lcd.cls(); + lcd.printf("Break scale is: %i", breakPerc); } } } @@ -362,10 +377,10 @@ case FIRE: { pc.printf("Shooting\r\n"); servo.pulsewidth(servoL); // BREAK release - pwmM1.write(0.25); // Pendulum motor on + pwmM1.write(0.25); // beam motor on bool servoPos = true; while(state == FIRE){ // while in FIRE state - if(breakFlag && (abs(enc1.getPulses())-100)%4200 < (2100*abs(breakPerc)/10)){ // BREAK goFlag half rotation pendulum = breaking + if(breakFlag && (abs(enc1.getPulses())-100)%4200 < (2100*abs(breakPerc)/10)){ // BREAK goFlag half rotation beam = breaking breakFlag = false; if(servoPos){ servoPos = false; @@ -378,9 +393,9 @@ } if(controlFlag){ controlFlag = false; - if((abs(enc1.getPulses())+50)%4200 < 150){ // rotate pendulum one revolution - pwmM1.write(0); // motor pendulum off - pc.printf("Pendulum on startposition\r\n"); + if((abs(enc1.getPulses())+50)%4200 < 150){ // rotate beam one revolution + pwmM1.write(0); // motor beam off + pc.printf("beam on startposition\r\n"); state = AIM; // Next stage } }