4 directional EMG control of the XY table. Made during my bachelor end assignment.

Dependencies:   C12832_lcd HIDScope mbed-dsp mbed

Files at this revision

API Documentation at this revision

Comitter:
jessekaiser
Date:
Tue Jun 16 15:42:59 2015 +0000
Parent:
59:ba22a8c26dee
Child:
61:99f3ae6e053b
Commit message:
Eindconcept 9. Nieuwe control + homing

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Tue Jun 16 09:33:08 2015 +0000
+++ b/main.cpp	Tue Jun 16 15:42:59 2015 +0000
@@ -12,18 +12,18 @@
 #include "arm_math.h"
 //#include "HIDScope.h"
 
-#define K_Gain      10    //Gain of the filtered EMG signal
+#define K_Gain      50    //Gain of the filtered EMG signal
 #define Damp        5       //Deceleration of the motor
 #define Mass        1       // Mass value
-#define dt          0.10   //Sample frequency
-#define MAX_bi      0.09 //Can be used for normalisation of the EMG signal of the biceps
-#define MAX_tri     0.10
-#define MAX_pect    0.10
-#define MAX_delt    0.05
-#define EMG_tresh1   0.03
-#define EMG_tresh2   0.03
-#define EMG_tresh3   0.02
-#define EMG_tresh4   0.03
+#define dt          0.01   //Sample frequency
+#define MAX_bi      0.40 //Can be used for normalisation of the EMG signal of the biceps
+#define MAX_tri     0.60
+#define MAX_pect    0.48
+#define MAX_delt    1.07
+#define EMG_tresh1   0.02
+#define EMG_tresh2   0.02
+#define EMG_tresh3   0.01
+#define EMG_tresh4   0.01
 
 //Motor control
 DigitalOut Dirx(p21);
@@ -58,7 +58,7 @@
 C12832_LCD lcd;
 
 //Variables for motor control
-float setpoint = 1000; //Frequentie setpoint
+float setpoint = 2000; //Frequentie setpoint
 float step_freq1 = 1;
 float step_freq2 = 1;
 float step_freq3 = 1;
@@ -95,6 +95,7 @@
 float force1, force2, force3, force4;
 float speed1, speed2, speed3, speed4;
 float damping1, damping2, damping3, damping4;
+float emg_x, emg_y;
 
 void looper_emg()
 {
@@ -106,22 +107,22 @@
 
     //process emg biceps
     arm_biquad_cascade_df1_f32(&highnotch_biceps, &emg_value1_f32, &filtered_biceps, 1 );   //High pass and notch filter
-    filtered_biceps = fabs(filtered_biceps)*K_Gain;                                                //Rectifier, The Gain is already implemented.
+    filtered_biceps = fabs(filtered_biceps);                                                //Rectifier, The Gain is already implemented.
     arm_biquad_cascade_df1_f32(&lowpass_biceps, &filtered_biceps, &filtered_biceps, 1 );    //low pass filter
 
     //process emg triceps
     arm_biquad_cascade_df1_f32(&highnotch_triceps, &emg_value2_f32, &filtered_triceps, 1 );
-    filtered_triceps = fabs(filtered_triceps)*K_Gain;
+    filtered_triceps = fabs(filtered_triceps);
     arm_biquad_cascade_df1_f32(&lowpass_triceps, &filtered_triceps, &filtered_triceps, 1 );
 
     //process emg pectoralis major
     arm_biquad_cascade_df1_f32(&highnotch_pect, &emg_value3_f32, &filtered_pect, 1 );
-    filtered_pect = fabs(filtered_pect)*K_Gain;
+    filtered_pect = fabs(filtered_pect);
     arm_biquad_cascade_df1_f32(&lowpass_pect, &filtered_pect, &filtered_pect, 1 );
 
     //process emg deltoid
     arm_biquad_cascade_df1_f32(&highnotch_deltoid, &emg_value4_f32, &filtered_deltoid, 1 );
-    filtered_deltoid = fabs(filtered_deltoid)*K_Gain;
+    filtered_deltoid = fabs(filtered_deltoid);
     arm_biquad_cascade_df1_f32(&lowpass_deltoid, &filtered_deltoid, &filtered_deltoid, 1 );
 
     /*send value to PC.
@@ -131,12 +132,107 @@
     scope.set(3,filtered_deltoid);*/
 }
 
+void looper_motory()
+{
+    emg_y = fabs(filtered_biceps - filtered_triceps);
+    force1 = emg_y*K_Gain;
+    force1 = force1 - damping1;
+    acc1 = force1/Mass;
+    speed1 = speed_old1 + (acc1 * dt);
+    damping1 = speed1 * Damp;
+    step_freq1 = setpoint * speed1;
+    Stepy.period(1.0/step_freq1);
+    speed_old1 = speed1;
+
+
+    if (emg_y > 0 || Posy < 0.20) {
+        Diry = 1;
+    }
+
+    if (emg_y < 0 || Posy > 0.70) {
+        Diry = 0;
+    }
+    //Speed limit
+    if (speed1 > 1) {
+        speed1 = 1;
+        step_freq1 = setpoint;
+    }
+    //EMG treshold
+    if (filtered_biceps < EMG_tresh1 && filtered_triceps < EMG_tresh2) {
+        Enabley = 1; //Enable = 1 turns the motor off.
+    } else {
+        Enabley = 0;
+    }
+
+}
+
+void looper_motorx()
+{
+    emg_x = fabs(filtered_pect - filtered_deltoid);
+    force2 = emg_x*K_Gain;
+    force2 = force2 - damping2;
+    acc2 = force2/Mass;
+    speed2 = speed_old2 + (acc2 * dt);
+    damping2 = speed2 * Damp;
+    step_freq2 = setpoint * speed2;
+    Stepx.period(1.0/step_freq2);
+    speed_old2 = speed2;
+
+    if (emg_x > 0 || Posx < 0.30) {
+        Dirx = 0;
+    }
+    if (emg_x < 0 || Posx > 0.86) {
+        Dirx = 1;
+    }
+    //Speed limit
+    if (speed2 > 1) {
+        speed2 = 1;
+        step_freq2 = setpoint;
+    }
+    //EMG treshold
+    if (filtered_pect < EMG_tresh3 && filtered_deltoid < EMG_tresh4) {
+        Enablex = 1; //Enable = 1 turns the motor off.
+    } else {
+        Enablex = 0;
+    }
+
+}
 
 int main()
 {
+    float errorx = 0.2;
+    float errory = 0.2;
+    float Ps_x = Posx.read();
+    float Ps_y = Posy.read(); 
+    float cx = 0;
+    float cy = 0;
+    #define H_Gain  1
+    #define Pt_x    0.83
+    #define Pt_y    0.25
+    
     // Attach the HIDScope::send method from the scope object to the timer at 500Hz. Hier wordt de sample freq aangegeven.
     // scopeTimer.attach_us(&scope, &HIDScope::send, 2e3);
-
+    while(errorx > 0.05 || errory > 0.05) {
+        lcd.printf("%.2f %.2f \n", Stepx.read(), Stepy.read());
+        if (Posx.read() < 0.83) {
+            Dirx = 0;
+            errorx = Pt_x - Ps_x;
+            cx = errorx * H_Gain;
+            //Stepx.period(1.0/(2000*cx));
+        }
+        if (Posy.read() > 0.25) {
+            Diry = 0;
+            errory = Ps_y - Pt_y;
+            cy = errory * H_Gain;
+            //Stepy.period(1.0/(2000*cy));
+        }
+        
+            Stepx.period(1.0/(2000*cx));
+ Stepy.period(1.0/(2000*cy));      
+        wait(0.01);
+        
+    }
+   
     Ticker emgtimer;    //biceps
     arm_biquad_cascade_df1_init_f32(&lowpass_biceps, 1 , lowpass_const, lowpass_biceps_states);
     arm_biquad_cascade_df1_init_f32(&highnotch_biceps, 2 , highnotch_const, highnotch_biceps_states);
@@ -151,11 +247,11 @@
     arm_biquad_cascade_df1_init_f32(&highnotch_deltoid, 2 , highnotch_const, highnotch_deltoid_states);
     emgtimer.attach(looper_emg, 0.01);
 
-    /*Ticker looptimer1;
+    Ticker looptimer1;
     looptimer1.attach(looper_motorx, 0.01); //X-Spindle motor, why this freq?
 
     Ticker looptimer2;
-    looptimer2.attach(looper_motory, 0.01); //Y-Spindle motor*/
+    looptimer2.attach(looper_motory, 0.01); //Y-Spindle motor
 
     //Microstepping control, now configured as half stepping (MS1=1,MS2=0,MS3=0)
     MS1 = 1;
@@ -164,123 +260,17 @@
     Stepx.write(0.5); // Duty cycle of 50%
     Stepy.write(0.5);
 
-    //if (Posx < 0.50) {
-    //  Stepx.period(1.0/3000); //if the speed and distance is known. The motor can be brought to a home position.
-    //Need to know rpm to m/s.
-
 
     while (1) {
 
-    //Forward
-    force1 = (filtered_biceps/MAX_bi); //MAX_bi is used to normalize the signal
-    force1 = force1 - damping1;
-    acc1 = force1/Mass;
-    speed1 = speed_old1 + (acc1 * dt);
-    damping1 = speed1 * Damp;
-    step_freq1 = (setpoint*speed1);
-    speed_old1 = speed1;
-
-    //Achteruit triceps
-    force2 = (filtered_triceps/MAX_tri);
-    force2 = force2 - damping2;
-    acc2 = force2/Mass;
-    speed2 = speed_old2 + (acc2 * dt);
-    damping2 = speed2 * Damp;
-    step_freq2 = (setpoint*speed2);
-    speed_old2 = speed2;
-
-    if (filtered_biceps > filtered_triceps || Posy < 0.20) {
-        Diry = 1;
-        speed2 = 0.01;
-        speed_old2 = 0.01;
-        Stepy.period(1.0/step_freq1);
-    }
-    if (filtered_triceps > filtered_biceps || Posy > 0.70) {
-        Diry = 0;
-        speed1 = 0.01;
-        speed_old1 = 0.01;
-        Stepy.period(1.0/step_freq2);
-    }
-    //Speed limit
-    if (speed1 > 1) {
-        speed1 = 1;
-        Stepy.period(1.0/setpoint);
-        //step_freq1 = setpoint;
-    }
-    if (speed2 > 1) {
-        speed2 = 1;
-        Stepy.period(1.0/setpoint);
-        //step_freq2 = setpoint;
-    }
-    //EMG treshold
-    if (filtered_biceps < EMG_tresh1 && filtered_triceps < EMG_tresh2) {
-        Enabley = 1; //Enable = 1 turns the motor off.
-        speed1 = 0.01;
-        speed_old1 = 0.01;
-        speed2 = 0.01;
-        speed_old2 = 0.01;
-    } else {
-        Enabley = 0;
-    }
-
-    //To the left
-    force3 = (filtered_pect/MAX_pect);
-    force3 = force3 - damping3;
-    acc3 = force3/Mass;
-    speed3 = speed_old3 + (acc3 * dt);
-    damping3 = speed3 * Damp;
-    step_freq3 = (setpoint*speed3);
-    speed_old3 = speed3;
-
-    //To the right
-    force4 = (filtered_deltoid/MAX_delt);
-    force4 = force4 - damping4;
-    acc4 = force4/Mass;
-    speed4 = speed_old4 + (acc4 * dt);
-    damping4 = speed4 * Damp;
-    step_freq4 = (setpoint*speed4);
-    speed_old4 = speed4;
-
-    if (filtered_pect > filtered_deltoid || Posx < 0.30) {
-        Dirx = 0;
-        speed4 = 0.01;
-        speed_old4 = 0.01;
-        Stepx.period(1.0/step_freq3);
-    }
-    if (filtered_deltoid > filtered_pect || Posx > 0.86) {
-        Dirx = 1;
-        speed3 = 0.01;
-        speed_old3 = 0.01;
-        Stepx.period(1.0/step_freq4);
-    }
-    //Speed limit
-    if (speed3 > 1) {
-        speed3 = 1;
-        Stepx.period(1.0/setpoint);
-        //step_freq3 = setpoint;
-    }
-    if (speed4 > 1) {
-        speed4 = 1;
-        Stepx.period(1.0/setpoint); 
-        //step_freq4 = setpoint;
-    }
-    //EMG treshold
-    if (filtered_pect < EMG_tresh3 && filtered_deltoid < EMG_tresh4) {
-        Enablex = 1; //Enable = 1 turns the motor off.
-        speed3 = 0.01;
-        speed_old3 = 0.01;
-        speed4 = 0.01;
-        speed_old4 = 0.01;
-    } else {
-        Enablex = 0;
-    }
-
 
         //lcd.printf("x %.2f, y %.2f \n", Posx.read(), Posy.read());
-        lcd.printf("%.2f, %.2f %.2f %.2f \n", filtered_biceps, filtered_triceps, filtered_pect, filtered_deltoid); //Filtered EMG values
-        //lcd.printf("1 %.0f, 2 %.0f, 3 %.0f, 4 %.0f \n", step_freq1, step_freq2, step_freq3, step_freq4); //step_freq value of every EMG sensor
+        //lcd.printf("%.2f, %.2f %.2f %.2f \n", filtered_biceps, filtered_triceps, filtered_pect, filtered_deltoid); //Filtered EMG values
+        //lcd.printf("1 %.0f, 2 %.0f \n", step_freq1, step_freq2); //step_freq value of every EMG sensor
+        lcd.printf("%.2f %.2f \n", force1, force2);
         //lcd.printf("%.2f, %.2f %.2f %.2f \n", gain_biceps, gain_triceps, gain_pect, gain_deltoid);
         //lcd.printf("%.2f, %.2f %.2f %.2f \n", norm_biceps, norm_triceps, norm_pect, norm_deltoid);
         wait(0.01);
+
     }
 }