![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Mbed bordje 1 -af
Dependencies: Encoder HIDScope MODSERIAL Matrix MatrixMath biquad-master mbed
Fork of dsjklafjaslkjdfalkjfdaslkasdjklajadsflkjdasflkjdasflkadsflkasd by
Diff: main.cpp
- Revision:
- 5:3562c205d001
- Parent:
- 4:afa85283eb18
- Child:
- 6:643c44fb044a
diff -r afa85283eb18 -r 3562c205d001 main.cpp --- a/main.cpp Wed Nov 01 11:50:05 2017 +0000 +++ b/main.cpp Fri Nov 03 06:40:08 2017 +0000 @@ -1,229 +1,528 @@ - /** - * Demo program for BiQuad and BiQuadChain classes - * author: T.J.W. Lankhorst <t.j.w.lankhorst@student.utwente.nl> and Matthijs and Roy and Dion - */ +//initialisation #include "mbed.h" +#include "encoder.h" #include "HIDScope.h" +#include "MODSERIAL.h" +#include "math.h" +#include "BiQuad.h" +#include "Matrix.h" +#include "MatrixMath.h" #include <stdlib.h> #include <iostream> #include <iomanip> #include <complex> #include <vector> -#include "BiQuad.h" -#include "Matrix.h" -#include "MatrixMath.h" -#include "MODSERIAL.h" -#include "encoder.h" + +Ticker MainTicker; -AnalogIn emg0( A0 ); -AnalogIn emg1( A1 ); -DigitalIn button1(D11); -Encoder encoder1(D13,D12); -Encoder encoder2(D13,D12); //moet nog even aangepast worden - - -DigitalOut motorDirection(D4); -PwmOut motorSpeed(D5); -DigitalOut motorDirection1(D4); //nog goede channel toevoegen -PwmOut motorSpeed1(D5); //nog goede channel toevoegen - -MODSERIAL pc(USBTX, USBRX); +//Define objects EMG +AnalogIn emg0( A0 ); +AnalogIn emg1( A1 ); +DigitalIn buttonCal(D11); +DigitalIn changeX(D2); +DigitalIn changeY(D3); +InterruptIn turning(D10); -Ticker sample_timer; -Ticker cal_timer; -HIDScope scope( 4 ); -DigitalOut led(LED1); -DigitalOut led2(LED_GREEN); +Ticker sample_timer; +Ticker calX_timer; +Ticker calY_timer; +//HIDScope scope( 4 ); +DigitalOut led(LED1); +DigitalOut led2(LED_GREEN); + +//Define variables EMG const int size = 100; -vector<double> S(size,0); -vector<double> S1(size,0); +vector<double> SX(size,0); +vector<double> SY(size,0); double meanSum = 0; - double maxsignal = 0; -double emgX = 0; -double emgY = 0; -double L0 = 0.123; -double L1 = 0.37; -double L2 = 0.41; -double q1 = encoder1.getPosition()/131.25; //Calibreren nog toevoegen -double q2 = encoder2.getPosition()/131.25; //Calibreren mist nog -double Periode = 1/500; //1000 is het aantal Hz - -//Filter toevoegen, bestaande uit notch, high- en lowpass filter +//Filters BiQuadChain Notch; BiQuadChain Notch50; BiQuadChain bqcLP; BiQuadChain bqc; -//50 Hz Notch filter, for radiation from surroundings //Notch filter chain for 100 Hz BiQuad bqNotch1( 9.75180e-01, -1.85510e+00, 9.75218e-01, -1.87865e+00, 9.75178e-01 ); BiQuad bqNotch2( 1.00000e+00, -1.90228e+00, 1.00004e+00, -1.88308e+00, 9.87097e-01 ); BiQuad bqNotch3( 1.00000e+00, -1.90219e+00, 9.99925e-01, -1.89724e+00, 9.87929e-01 ); -//BiQuad Notch(0.9179504645111498,-1.4852750515677946, 0.9179504645111498, -1.4852750515677946, 0.8359009290222995); - //Notch filter chain for 50 Hz BiQuad bq1( 9.50972e-01, -1.53921e+00, 9.51003e-01, -1.57886e+00, 9.50957e-01 ); BiQuad bq2( 1.00000e+00, -1.61851e+00, 9.99979e-01, -1.57185e+00, 9.74451e-01 ); BiQuad bq3( 1.00000e+00, -1.61855e+00, 9.99988e-01, -1.62358e+00, 9.75921e-01 ); -//15 Hz Highpass filter, as recommended by multiple studies regarding EMG signals -//BiQuad Highpass15(9.35527e-01, -1.87105e+00, 9.35527e-01, -1.86689e+00, 8.75215e-01); - -//2Hz Highpass +//2 Hz High Pass filter BiQuad Highpass1(9.82385e-01, -1.96477e+00, 9.82385e-01, -1.96446e+00, 9.65081e-01); - -//20 Hz Lowpass -//BiQuad Lowpass100( 3.62168e-03, 7.24336e-03, 3.62168e-03, -1.82269e+00, 8.37182e-01 ); - -//250 Hz Lowpass -//BiQuad Lowpass100 (2.92893e-01, 5.85786e-01, 2.92893e-01, -3.60822e-16, 1.71573e-01 ); - -//80 Hz Lowpass +//80 Hz Low Pass filter BiQuad bqLP1( 5.78904e-02, 5.78898e-02, 0.00000e+00, -2.90527e-01, 0.00000e+00 ); BiQuad bqLP2( 1.00000e+00, 2.00001e+00, 1.00001e+00, -7.53537e-01, 4.06308e-01 ); +//Define objects MotorControl +DigitalOut gpo(D0); +DigitalOut UpperMotorDir(D4); +PwmOut UpperMotorVel(D5); +DigitalOut LowerMotorDir(D6); +PwmOut LowerMotorVel(D7); +AnalogIn potMeterIn(A1); +InterruptIn ButMotorDir(D3); +Encoder encoder1(D13,D12); +Encoder encoder2(D9,D8); +Ticker m1_Ticker; +Ticker setpoint_Ticker; -//450 Hz Lowpass filter, to remove any noise (sample frequency is only 500 Hz, but still...) -//BiQuad Lowpass450(8.00592e-01, 1.60118e+00, 8.00592e-01, 1.56102e+00, 6.41352e-01); +//Define variables MotorControl +float M_PI = 3.14159265359; + +float M1_KP = 1.0f; +float M1_KI = 0.1f; +const float M1_TS = 0.002; +const float q_RAD_PER_PULSE_m2 = 0.36f*M_PI/1300.0f; //2*M_PI/4320 voor als het nu geen rechte lijn meer is8 +const float q_RAD_PER_PULSE_m1 = 0.5f*M_PI/3300.0f; + +float m1_err_int = 0; +float m2_err_int = 0; +int motorD1 = 0; +float motor1 = 0; +int motorD2 = 0; +float motor2 = 0; +float position1 = 0; +float position2 = 0; + +float emgX = 0; +float emgY = 0; -//Making matrices globaly -Matrix JAPPAPP(2,2); -Matrix qdot(2,1); -Matrix Vdes(2,1); -Matrix qsetpoint(2,1); - - +float L0 = 0.123; +float L1 = 0.37; +float L2 = 0.41; +float q1 = 0.0f*M_PI; +float q2 = 0.0f*M_PI; +float Periode = 0.001; //1000 is het aantal Hz + +float ref_pos1; +float ref_pos2; + +float Qset1 = 0; +float Qset2 = 0; + +int UpperMotorPos; +int UpperMotorPos_prev; +int LowerMotorPos; +int LowerMotorPos_prev; + +int NPC = 0; +float NoTurnies = 1; + +//Define matrices MotorControl +Matrix JAPPAPP(2,2); +Matrix qdot(2,1); +Matrix Vdes(2,1); + +//Define object Servo Motors +DigitalOut Ledr(LED_RED); +DigitalOut Ledg(LED_GREEN); +DigitalOut Ledb(LED_BLUE); +PwmOut LeftServoVel(D11); +PwmOut RightServoVel(D10); +DigitalIn ServoButton(D2); +Ticker ServoTick; - -double findRMS(vector<double> array) -{ +//Other variables +float Cal_Strength = 0.6f; + + +//Connection with TeraTerm +MODSERIAL pc(USBTX, USBRX); + +//Creating of the states +enum states{calib1, calib2, calibEMG, UpDown, LeftRight, Vertical, MotionEndEffector, GrabbingPlacing, Off, Idle, No_State}; + +//Root Mean Square value calculator for useful envelope, using vectors +double findRMS(vector<double> array) { int i; - double sumsquared = 0.000; + double sumsquared = 0.000; //define variable that resets to 0 for every call of the function double RMS; - //sumsquared = 0; - for (i = 0; i < size; i++) + + for (i = 0; i < size; i++) //for loop to calculate the total sum of the squared values { sumsquared = sumsquared + array.at(i)*array.at(i); } - RMS = sqrt((double(1)/size)*(sumsquared)); + RMS = sqrt((double(1)/size)*(sumsquared)); //root mean square calculation return RMS; } - - - -void sample() -{ + + +//Function to show the EMG signals in HIDScope +void sample() { /* Set the sampled emg values in channel 0 (the first channel) and 1 (the second channel) in the 'HIDScope' instance named 'scope' */ - //scope.set(0, emg0.read() ); - //scope.set(1, fabs(Notch.step(emg0.read())) ); - scope.set(0, emg0.read()-0.4542); - //scope.set(1, bqcLP.step(Highpass1.step(emg0.read()-0.4542))); - //scope.set(2, fabs(Notch50.step(bqcLP.step(Highpass1.step(emg0.read()-0.4542))))); - //scope.set(3, fabs(bqc.step(emg0.read()-0.4542))); - //scope.set(3, Notch.step(Notch50.step(bqcLP.step(Highpass1.step(fabs(emg0.read()-0.4542)))))); + //Standard emg value without filters, offset removed with the - value + //scope.set(0, emg0.read()-0.4542f); + + //Use S vector to save values coming from EMG signal + SX.erase(SX.begin()); //remove first value + double emgXvalue = bqc.step(emg0.read()-0.4542f); + SX.push_back(emgXvalue); //add extra value to begin of vector + + SY.erase(SY.begin()); //remove first value + double emgYvalue = bqc.step(emg0.read()-0.4542f); + SY.push_back(emgYvalue); //add extra value to begin of vector - //scope.set(0, fabs(Highpass1.step(Lowpass100.step(Notch.step(emg0.read())))) ); - /* - for (int i = size-1; i > 1; i--) { - S[i] = S[i-1]; - } - */ - S.erase(S.begin()); - S1.erase(S1.begin()); - double b = bqc.step(emg0.read()-0.4542); - double c = bqc.step(emg1.read()-0.4542); - S.push_back(b); - S1.push_back(c); - //S[0] = bqc.step(emg0.read()-0.4542))); - //Notch50.step(bqcLP.step(Highpass1.step(emg0.read()-0.4542))); - emgX = findRMS(S); - emgY = findRMS(S1); - scope.set(1, emgX); - //scope.set(2, S[0]); - //meanSum = 0; */ - /* Repeat the step above if required for more channels of required (channel 0 up to 5 = 6 channels) - * Ensure that enough channels are available (HIDScope scope( 2 )) - * Finally, send all channels to the PC at once */ - scope.send(); + //Calculate Root Mean Square value using findRMS function as defined above + double emgX = findRMS(SX); + double emgY = findRMS(SY); + + //Display results + //scope.set(1, emgX); + //scope.set(2, emgY); + + //Send all scopes to HIDScope + //scope.send(); + /* To indicate that the function is working, the LED is toggled */ led = !led; - - motorSpeed.write(0.38080*(emgX/maxsignal)); - motorDirection.write(1); } -void calibration() -{ +//Calibration function for the EMG signals +void calibrationX() { //function to determine maximal EMG input in order to allow motorcontrol to be activated - if (button1.read() == false){ + if (buttonCal.read() == false){ //activated when button is pressed led2 = !led2; for (int n = 1; n < 5000; n++){ //calibrate for 5000 samples or 10 seconds - - S.erase(S.begin()); - double b = bqc.step(emg0.read()-0.4542); - S.push_back(b); - //S[0] = bqc.step(emg0.read()-0.4542))); - //Notch50.step(bqcLP.step(Highpass1.step(emg0.read()-0.4542))); - double signalfinal = findRMS(S); - if (signalfinal >= maxsignal){ - maxsignal = signalfinal; //keep changing the maximal signal - pc.printf("%d \n",maxsignal); + SX.erase(SX.begin()); + double emgXCalvalue = bqc.step(emg0.read()-0.4542f); + SX.push_back(emgXCalvalue); + double signalfinal = findRMS(SX); //calculate RMS values from EMG signals + if (signalfinal >= maxsignal){ //Check if current signal is higher than current maximal signal + maxsignal = signalfinal; //keep changing the maximal signal } } - led2 = 1; + led2 = 1; //Turn LED off when calibration is finished + } +} + +void calibrationY() { + //function to determine maximal EMG input in order to allow motorcontrol to be activated + + if (buttonCal.read() == false){ //activated when button is pressed + led2 = !led2; + for (int n = 1; n < 5000; n++){ //calibrate for 5000 samples or 10 seconds + SY.erase(SY.begin()); + double emgYCalvalue = bqc.step(emg1.read()-0.4542f); + SY.push_back(emgYCalvalue); + double signalfinal = findRMS(SY); //calculate RMS values from EMG signals + if (signalfinal >= maxsignal){ //Check if current signal is higher than current maximal signal + maxsignal = signalfinal; //keep changing the maximal signal + } + } + led2 = 1; //Turn LED off when calibration is finished + } +} + + +void NegPosChanger(){ + if(NPC == 0){ + NoTurnies = 0; + NPC++; + } else { + NoTurnies = 1; + NPC= 0; } } -void qSetpointSet(){ - // Fill Matrix with data. - JAPPAPP(1,1) = -(L0 - L0*sin(q1) + L1*sin(q1) - L2*sin(q2))/(L1*L1*cos(q1)*sin(q1) + L0*L1*cos(q1) + L0*L2*cos(q2) - L0*L1*cos(q1)*sin(q1) - L0*L2*cos(q2)*sin(q1) - L1*L2*cos(q1)*sin(q2)); - JAPPAPP(1,2) = -(L2*cos(q2))/(L1*L1*cos(q1)*sin(q1) + L0*L1*cos(q1) + L0*L2*cos(q2) - L0*L1*cos(q1)*sin(q1) - L0*L2*cos(q2)*sin(q1) - L1*L2*cos(q1)*sin(q2)); - JAPPAPP(2,1) = (L1*sin(q1) - L2*sin(q2))/(L1*L1*cos(q1)*sin(q1) + L0*L1*cos(q1) + L0*L2*cos(q2) - L0*L1*cos(q1)*sin(q1) - L0*L2*cos(q2)*sin(q1) - L1*L2*cos(q1)*sin(q2)); - JAPPAPP(2,2) = (L1*cos(q1) + L2*cos(q2))/(L1*L1*cos(q1)*sin(q1) + L0*L1*cos(q1) + L0*L2*cos(q2) - L0*L1*cos(q1)*sin(q1) - L0*L2*cos(q2)*sin(q1) - L1*L2*cos(q1)*sin(q2)); - +void qSetpointSet() { // Fill Matrix with data. - Vdes(1,1) = emgX; //Goede code nog toevoegen, Vx - Vdes(2,1) = emgY; //goede code nog toevoegen, Vy + q1 = encoder1.getPosition()*q_RAD_PER_PULSE_m1; //Calibreren nog toevoegen + q2 = 0.5f*M_PI - q1 + encoder2.getPosition()*q_RAD_PER_PULSE_m2; //Calibreren mist nog + + JAPPAPP(1,1) = (cos(q1)*cos(q2) - sin(q1)*sin(q2))/(L1*sin(q2)*cos(q1)*cos(q1) + L1*sin(q2)*sin(q1)*sin(q1)); + JAPPAPP(1,2) = (cos(q1)*sin(q2) + cos(q2)*sin(q1))/(L1*sin(q2)*cos(q1)*cos(q1) + L1*sin(q2)*sin(q1)*sin(q1)); + JAPPAPP(2,1) = -(L1*cos(q1) + L2*cos(q1)*cos(q2) - L2*sin(q1)*sin(q2))/(L1*L2*sin(q2)*cos(q1)*cos(q1) + L1*L2*sin(q2)*sin(q1)*sin(q1)); + JAPPAPP(2,2) = -(L1*sin(q1) + L2*cos(q1)*sin(q2) + L2*cos(q2)*sin(q1))/(L1*L2*sin(q2)*cos(q1)*cos(q1) + L1*L2*sin(q2)*sin(q1)*sin(q1)); + + // Fill Matrix with data. + int Xchanger = (changeX == 1) ? -1 : 1; + int Ychanger = (changeY == 1) ? -1 : 1; + Vdes(1,1) = emgX*Xchanger*NoTurnies; + Vdes(2,1) = emgY*Ychanger*NoTurnies; + int turnChanger = (turning == 1) ? -1 : 1; qdot = JAPPAPP*Vdes; - - qsetpoint(1,1) = q1 + qdot(1,1)*Periode; - qsetpoint(2,1) = q2 + qdot(2,1)*Periode; + + Qset1 = Qset1 + qdot(1,1)*Periode; //Vdes(1,1) + Qset2 = Qset2 + qdot(2,1)*Periode; //Vdes(2,1) + + if (Qset1 <= 0.43f*M_PI && Qset1 >= 0.01f){ + Qset1 = Qset1; + } + else if (Qset1 < 0.01f){ + Qset1 = 0.01f; + } + else if (Qset1 > 0.43f*M_PI){ + Qset1 = 0.43f*M_PI; + } + if (Qset1 + Qset2 < 0.5f*M_PI){ + Qset2 = 0.5f*M_PI - Qset1; + } + if (Qset2 <= 0.5f*M_PI && Qset2 >= 0.1f){ + Qset2 = Qset2; + } + else if (Qset2 < .1f){ + Qset2 = 0.1f; + } + else if (Qset1+Qset2 > M_PI){ + Qset2 = M_PI - Qset1; + } + +} + +float PI( float e, const float Kp, const float Ki, float Ts, float &e_int ){ // Reusable PI controller + return fabs(Kp * e); +} + +void PositionControl() { + //position1 = RAD_PER_PULSE * encoder1.getPosition(); + //position2 = RAD_PER_PULSE * encoder2.getPosition(); + ref_pos1 = Qset1 - q1; + //if (ref_pos1 < 0.1) { ref_pos1 = 0; } + ref_pos2 = Qset2 - q2; // Don’t use magic numbers! + //if (ref_pos2 < 0.1) { ref_pos2 = 0; } + motor1 = PI(ref_pos1, M1_KP, M1_KI, M1_TS, m1_err_int ); + motor2 = PI(ref_pos2, M1_KP, M1_KI, M1_TS, m2_err_int ); + if (ref_pos1 <= 0) { + motorD1=1; + } + else{ + motorD1 = 0; + } + if (ref_pos2 <= 0) { + motorD2=0; + } + else{ + motorD2=1; + } + UpperMotorDir.write(motorD1); + UpperMotorVel.write(motor1); + LowerMotorDir.write(motorD2); + LowerMotorVel.write(motor2); +} + +/** Servo motor control function **/ + +//Servo initialisation +enum servostates{Close, Open}; + +//Set default state to open, as mentioned in paragraph ... of the report +servostates CurrentState = Open; + +int i = 0; +int j = 0; + +//Simply switch the current state when button is pressed +void Change() { + if(CurrentState == Close){ + CurrentState = Open; + } + else{ + CurrentState = Close; + } } -int main() -{ -pc.baud(115200); +//State machine for the servo motors, to determine the state +void ProcessStateMachine(void) { +/** +State machine for the servo motors, motor response dependent on the current state and the amount of milliseconds of activation. +The entire function must be sampled at 2000 Hz, since it counts half milliseconds. This is required since the servos respond to half millisecond actuation. +For further information on the functioning of the servo motors; see paragraph ... in report 'Design of a Jenga playing robot' by group 2. +**/ + switch (CurrentState) + { + case Close: + if(j <= 35){ + RightServoVel.write(0); + LeftServoVel.write(0); + j++; + } + else if (j == 36){ + RightServoVel.write(1); + LeftServoVel.write(0); + j++; + } + else if (j == 37){ + RightServoVel.write(1); + LeftServoVel.write(0); + j++; + } + else if (j == 38){ + RightServoVel.write(1); + LeftServoVel.write(0); + j++; + } + else if (j == 39){ + RightServoVel.write(1); + LeftServoVel.write(1); + j = 0; + } + break; + + case Open: + if(j <= 35){ + RightServoVel.write(0); + LeftServoVel.write(0); + j++; + } + else if (j == 36){ + RightServoVel.write(0); + LeftServoVel.write(0); + j++; + } + else if (j == 37){ + RightServoVel.write(0); + LeftServoVel.write(1); + j++; + } + else if (j == 38){ + RightServoVel.write(1); + LeftServoVel.write(1); + j++; + } + else if (j == 39){ + RightServoVel.write(1); + LeftServoVel.write(1); + j = 0; + } + break; + } +} + +//StateMachine for the moving of the end effector + +void ProcessStateMachineMain(void) { + states CurrentState1 = calibEMG; + switch (CurrentState1) + { + case MotionEndEffector: + m1_Ticker.attach( &PositionControl, M1_TS ); + setpoint_Ticker.attach(&qSetpointSet, Periode); + break; + + case calibEMG: + //Function to calibrate the filtered EMG signals to the user, in order to control the motors + double maxsignal = 0; //empty variable to check the maximal EMG output + for (int n = 1; n < 5000; n++){ //calibrate for 5000 samples or 5 seconds + double signalfinal = fabs(bqc.step(emg0.read())); //get values from the filtered EMG signal + if (signalfinal >= maxsignal){ //check whether the received signal is higher or lower than the current highest signal value + maxsignal = signalfinal; //keep changing the maximal signal + } + } + break; + + case calib1: + UpperMotorVel = Cal_Strength; UpperMotorDir = true; //depends on definitions + LowerMotorVel = 0.0f; + UpperMotorPos = encoder1.getPosition(); + if (abs(UpperMotorPos - UpperMotorPos_prev) < 0.01f){ + if (Cal_Strength < 1.0f) { + Cal_Strength += 0.05f; + } + else{ + encoder1.setPosition(0); //Afhankelijk van RKI uitzoeken of deze echt naar nul moet of naar 0.5pi + CurrentState1 = calib2; + Cal_Strength = 0.6f; + } + int UpperMotorPos_prev = UpperMotorPos; + } + break; + + case calib2: + LowerMotorVel = Cal_Strength; LowerMotorDir = true; // Check definitions + UpperMotorVel = 1.0f; + LowerMotorPos = encoder2.getPosition(); + if (abs(LowerMotorPos - UpperMotorPos_prev) < 0.01f){ + if (Cal_Strength < 1.0f) { + Cal_Strength += 0.05f; + } + else{ + encoder2.setPosition(0); + CurrentState1 = Idle; + //M1_controller = true; //turn on the position controller here + UpperMotorVel = 0.0f; LowerMotorVel = 0.0f; + } + int UpperMotorPos_prev = UpperMotorPos; + } + break; + + case Idle: + emgX = 0; + emgY = 0; + m1_Ticker.attach( &PositionControl, M1_TS ); + setpoint_Ticker.attach(&qSetpointSet, Periode); + break; + + case Off: + //Robot is off, also return to default state so you have a reference position when it starts up again + break; + + default: + //Robot is in idle mode, not doing anything (motors still powered to hold current position) (Posible when waiting for your turn) + + } +} + +//Main function for the servo motors, to change open or closed state +int main() { + //allow for the 2000 Hz sampling of the Servo state machine function + MainTicker.attach(ProcessStateMachineMain, 0.0005); + + ServoTick.attach(ProcessStateMachine, 0.0005); + + + + + + /** EMG signals **/ //Constructing the notch filter chain - Notch.add( &bqNotch1 ).add( &bqNotch2 ).add( &bqNotch3 ); - Notch50.add( &bq1 ).add( &bq2 ).add( &bq3 ); - bqcLP.add( &bqLP1 ).add( &bqLP2 ); bqc.add( &bqNotch1 ).add( &bqNotch2 ).add( &bqNotch3 ).add( &bq1 ).add( &bq2 ).add( &bq3 ).add( &bqLP1 ).add( &bqLP2 ); - /**Attach the 'sample' function to the timer 'sample_timer'. - * this ensures that 'sample' is executed every... 0.001 seconds = 1000 Hz - */ - sample_timer.attach(&sample, Periode); - cal_timer.attach(&calibration, 0.002);//ticker to check if motor is being calibrated - led2 = 1; - /*empty loop, sample() is executed periodically*/ + //Sample every 0.002 seconds, or 500 Hz + sample_timer.attach(&sample, 0.002); + //Ticker to check if motor is being calibrated, also at 500 Hz + calX_timer.attach(&calibrationX, 0.002); + calY_timer.attach(&calibrationY, 0.002); + //Turn LED off, turned on when calibrating + led2 = 1; + turning.rise(&NegPosChanger); + + //MODSERIAL connection + pc.baud(115200); + + + while (true) + { - DigitalOut myled(LED1); - -//--- - - while(true) { - qdot.print(); //Alleen visualisatie - wait(0.5); + if (buttonCal.read() == false){ //when calibrate button is pressed + states CurrentState1 = calibEMG; + } + + if (!ServoButton) { + Change(); + wait(0.3); + } + + + /*Control end-effector + wait(0.1); + float v_ref = GetReferenceVelocity(); + setMotor(v_ref); + pc.printf("%f \r\n", FeedForwardControl(v_ref)); + UpperMotorDir.write(motorDirection); + UpperMotorVel.write(RightServoVel); //PWM Speed Control + */ } - -} \ No newline at end of file +} \ No newline at end of file