Final version used at presentation. Working parts: idle, enccali, emgcali, brushingmode, demomode(potmeter).

Dependencies:   mbed QEI HIDScope biquadFilter MODSERIAL Encoder FastPWM

Revision:
3:8eb1b9e0d676
Parent:
2:6ca30ccec353
--- a/main.cpp	Mon Oct 28 16:31:37 2019 +0000
+++ b/main.cpp	Mon Nov 04 10:32:10 2019 +0000
@@ -1,163 +1,662 @@
+#include <math.h>
 #include "mbed.h"
-#include "math.h"
-#include "encoder.h"
+#include "MODSERIAL.h"
 #include "QEI.h"
-//#include "HIDScope.h"
-// ---- Alles met een 1(of geen getal) gaat over motor 1----
-// ---- Alles met een 2 gaat over motor 2---- 
-// ------ Hardware Interfaces -------
+#include "FastPWM.h"
+#include "HIDScope.h"
+#include <stdio.h>      /* printf */
+#include <stdlib.h>     /* abs */
+#include <complex>
+#include "BiQuad.h"
  
-const PinName motor1dir = D7; //direction1 (cw,ccw)
-const PinName motor1PWM = D6; //speed1
-const PinName motor2PWM = D5; //speed2
-const PinName motor2dir = D4; //direction2 (cw,ccw)
+ 
+const double PI = 3.1415926535897;
  
-DigitalOut motor1direction(motor1dir);
-PwmOut motor1control(motor1PWM);
-PwmOut motor2control(motor2PWM);
-DigitalOut motor2direction(motor2dir);
+InterruptIn but1(D1); 
+InterruptIn but2(D0); 
+DigitalIn butsw2(SW3); 
+DigitalIn butsw3(SW2); 
+AnalogIn potMeter1(A5);
+AnalogIn potMeter2(A4);
  
-const PinName button1name = D10; 
-const PinName pot1name = A0;
-const PinName button2name = D11;
-const PinName pot2name = A1;
-InterruptIn button1(button1name);    //had ook direct gekund maar he
-AnalogIn potMeterIn1(pot1name);
-InterruptIn button2(button2name);
-AnalogIn potMeterIn2(pot2name);
-
-QEI Encoder1(D13,D12,NC,64,QEI::X4_ENCODING);           //64 = ..., x4 encoding because ...
-QEI Encoder2(D9,D8,NC,64,QEI::X4_ENCODING); 
-// ------- Objects used -------
+DigitalOut motor1_direction(D4);                                                //richting van motor1
+FastPWM motor1_pwm(D5);                                                         //Motor 1 PWM controle van de snelheid
+DigitalOut motor2_direction(D7);                                                //richting van motor2
+FastPWM motor2_pwm(D6);                                                         //Motor 2 PWM controle van de snelheid
  
-// Ticker which controls the mother every 1/100 of a second.
-Ticker controlTicker;
- 
-Ticker debugTicker;
+Ticker loop_ticker;
+// SERIAL COMMUNICATION WITH PC.................................................
 Serial pc(USBTX, USBRX);
  
-//HIDScope scope(2); //fuck you hidscope we're not using you!
+enum States {s_idle, s_calibratie_encoder, s_demonstratie, s_EMGcalibratie, s_EMG};
+States state;
+ 
+// ENCODER .....................................................................
+QEI enc1 (D13, D12, NC, 4200); //encoder 1 gebruiken
+QEI enc2 (D9,  D8,  NC, 4200); //encoder 2 gebruiken
+ 
+const float dt = 0.001;
+double e_int = 0;
+double e_int2 = 0;
+double theta1;
+double theta2;
+int enc1_zero = 0;
+int enc2_zero = 0;
+int enc1_value;
+int enc2_value;
+const int maxwaarde = 400;
  
+volatile double Huidigepositie1=0;
+volatile double Huidigepositie2=0;
+volatile double motorValue1;
+volatile double motorValue2;
+volatile double refP;
+volatile double refP2;
+volatile double error1;
+volatile double error2;
+ 
+bool state_changed = false;
+volatile bool A=true;
+volatile bool B=true;
+volatile bool but1_pressed = false;
+volatile bool but2_pressed = false;
+volatile bool butsw2_pressed = false;
+volatile bool butsw3_pressed = false;
+volatile bool failure_occurred = false;
  
-// ------- Constants
-const float motorGain = 8f;         //just to be sure, niet te veel input geven tegen windup (old motor, suboptimal perfomance)
-const float maxVelocity = 8f; //radians per second
-const bool clockwise = true;
-const float rad_count = 0.0007479;   // 2pi/8400;
-const float pi = 3.1415926;
+const bool clockwise1 = true;
+const bool clockwise2 = true;
+volatile bool direction1 = clockwise1;
+volatile bool direction2 = clockwise2;
+ 
+// RKI VARIABELEN...............................................................
+// Lengtes zijn in meters
+// Vaste variabelen:
+const double L0 = 0.25;                                                         // lengte arm 1 --> moet nog goed worden opgemeten!
+const double L2 = 0.375;                                                         // Lengte arm 2 --> moet ook nog goed opgemeten worden!
+const double r_trans = 0.035;                                                   // gebruiken voor translation naar shaft rotation
+//const double gear1=1.0;
+const double gear2=1.25;
+
+
+// Variërende variabelen:
+double q1 = 0;                                                                  // Motorhoek van joint 1 op beginpositie
+double q2 = PI/2;                                                               // Motorhoek van joint 2 op beginpositie
+double v_x;                                                                     // Snelheid van end effector in x richting --> Door EMG signals
+double v_y;                                                                     // Snelheid van end effector in y richting --> Door EMG signals
  
-// ------ variables
+double Lq1;                                                                     // Translatieafstand als gevolg van motor rotation joint 1
+double Cq2;                                                                     // Joint angle van het systeem (gecorrigeerd voor gear ratio 1:1.1)
+ 
+double q1_dot;                                                                  // Benodigde hoeksnelheid van motor 1
+double q2_dot;                                                                  // Benodigde hoeksnelheid van motor 2
+ 
+double q1_ii;                                                                   // Referentie signaal voor motorhoek q1
+double q2_ii;                                                                   // Referentie signaal voor motorhoek q2
+ 
+//PI VARIABELEN................................................................
+const double kp=0.01;                                                          // Soort van geschaald --> meer onderzoek nodig
+const double ki=0.0001;
+const double kp2=0.01;
+const double ki2=0.0001;
+
+
+double maxPWM1 = 0.2;
+double maxPWM2 = 0.2;
+ 
+//FILTERS EMG...................................................................
  
-volatile bool direction1 = clockwise;
-volatile bool direction2 = clockwise;
- 
-// ------ functions
+//Filters EMG
+//Filters Linker Biceps
+//In de volgorde High pass, notch, low pass
+//BiQuad LBHP1(1, 2.000000023182220, 0.999999981993818, 1.893415601022358, 0.896255659548714);
+//BiQuad LBHP2(1, 1.999999976817780, 0.999999976817780, 1.778313488139574, 0.790599715524785);
+BiQuad LBHP1(0.995566972017647,  -1.991133944035294,   0.995566972017647, 1.000000000000000,  -1.991114292201654,   0.991153595868935);
+//BiQuad LBHP2([3.913020539916823e-05,7.826041079833645e-05,3.913020539916823e-05, -1.982228929792529,0.982385450614126]);
+BiQuad LBN1( 0.5, 0, 0.5, 0, 0);
+BiQuad LBLP1(0000.087655548754006,   0000.175311097508013,   0000.087655548754006,    1.000000000000000,  -1.973344249781299,   0.973694871976315);
+//BiQuad LBLP2( 0.000155148423475721, 0.000310296846951441, 0.000155148423475721,-1.96446058020523, 0.965081173899135);
+BiQuadChain LeftBicepHP;
+BiQuadChain LeftBicepN;
+BiQuadChain LeftBicepLP;
+
+//Filters Rechter Biceps
+//In de volgorde High pass, notch, low pass
+//BiQuad RBHP1(1, 2.000000023182220, 0.999999981993818, 1.893415601022358, 0.896255659548714);
+//BiQuad RBHP2(1, 1.999999976817780, 0.999999976817780, 1.778313488139574, 0.790599715524785);
+BiQuad RBHP1(0.995566972017647,  -1.991133944035294,   0.995566972017647, 1.000000000000000,  -1.991114292201654,   0.991153595868935);
+//BiQuad RBHP2([3.913020539916823e-05,7.826041079833645e-05,3.913020539916823e-05, -1.982228929792529,0.982385450614126]);
+BiQuad RBN1( 0.5, 0, 0.5, 0, 0);
+BiQuad RBLP1(0000.087655548754006,   0000.175311097508013,   0000.087655548754006,  1.000000000000000,  -1.973344249781299,   0.973694871976315);
+//BiQuad RBLP2( 0.000155148423475721, 0.000310296846951441, 0.000155148423475721,-1.96446058020523, 0.965081173899135);
+BiQuadChain RightBicepHP;
+BiQuadChain RightBicepN;
+BiQuadChain RightBicepLP;
+
+
+//Filters Rechter Quadriceps
+//In de volgorde High pass, notch, low pass
+//BiQuad RTHP1(1, 2.000000023182220, 0.999999981993818, 1.893415601022358, 0.896255659548714);
+//BiQuad RTHP2(1, 1.999999976817780, 0.999999976817780, 1.778313488139574, 0.790599715524785);
+BiQuad RTHP1(0.995566972017647,  -1.991133944035294 ,  0.995566972017647 ,1.000000000000000,  -1.991114292201654 ,  0.991153595868935);
+//BiQuad RTHP2(1, 1.999999966458334, 0.999999966458334, -1.988418014198592, 0.988451549797368);
+BiQuad RTN1( 0.5, 0, 0.5, 0, 0);
+BiQuad RTLP1(0000.087655548754006  , 0.175311097508013 ,  0.087655548754006,  1.000000000000000 , -1.973344249781299  , 0.973694871976315);
+//BiQuad RTLP2( 0.000155148423475721, 0.000310296846951441, 0.000155148423475721,-1.96446058020523, 0.965081173899135);
+BiQuadChain RightLegHP;
+BiQuadChain RightLegN;
+BiQuadChain RightLegLP;
  
-float getReferenceVelocity() {
-    // Returns reference velocity in rad/s. 
-    return maxVelocity * potMeterIn1 ;
+double emgLBHP;
+double emgLBN;
+double emgLBA;
+//double emgLBLP;
+//double emgAbsLBNotch;
+
+double emgRBHP;
+double emgRBN;
+double emgRBA;
+double emgRBLP;
+double emgAbsRBNotch;
+
+double emgRTN;
+double emgRTHP;
+double emgRTA;
+//double emgRTLP;
+//double emgAbsRTNotch;
+
+double emgLBfiltered;
+double emgRBfiltered;
+double emgRTfiltered;
+double emgLBraw;
+double emgRBraw;
+double emgRTraw;
+
+
+double threshold_emgLB;
+double threshold_emgRB;
+double threshold_emgRT;
+double threshold = 0.5;
+double emgLB_max = 0.000;
+double emgRB_max = 0.000;
+double emgRT_max = 0.000;
+double emgLB_maxrust = 0.000;
+double emgRB_maxrust = 0.000;
+double emgRT_maxrust = 0.000;
+volatile int tijd = 0;
+double timecalibration;
+
+double emgsumLB;
+double emgsumRB;
+double emgsumRT;
+double restmeanLB = 0.000;
+double restmeanRB = 0.000;
+double restmeanRT = 0.000;
+//double emgmeansubLB;
+//double emgmeansubRB;
+//double emgmeansubRT;
+double LBvalue;
+double RBvalue;
+double RTvalue;
+double emgLBrust;
+double emgRBrust;
+double emgRTrust;
+double RestmeanLB;
+double RestmeanRB;
+double RestmeanRT;
+
+ 
+DigitalOut ledr(LED_RED);
+DigitalOut ledg(LED_GREEN);
+DigitalOut ledb(LED_BLUE);
+
+
+AnalogIn emgLB(A0);     //read EMG left bicep
+AnalogIn emgRB(A1);     //read EMG right bicep
+AnalogIn emgRT(A2);     //read EMG right quadriceps
+
+//HIDScope scope(6);      //aantal kanalen HIDScope (voor test 5, voor echt 6)
+ 
+void rest()
+// Rust. Hier wordt niets uitgevoerd. Wanneer button1
+{
+    // wordt ingedrukt gaan we naar de volgende state waar
+    if (but1_pressed) {                                                         // de encoders worden gekalibreerd.
+        state_changed = true;
+        state = s_calibratie_encoder;
+        but1_pressed = false;
     }
-float getReferenceVelocity2() {
-    // Returns reference velocity in rad/s. 
-    return maxVelocity * potMeterIn2;    
 }
  
-void setMotor1(float motorValue1) {
-    // Given motorValue1<=1, writes the velocity to the pwm control.
-    // MotorValues outside range are truncated to within range.
-    motor1control.write(fabs(motorValue1) > 1 ? 1 : fabs(motorValue1));
-}
+void calibratie_encoder()                                                       // calibratie encoder. Hier worden de encoders gekalibreerd en op
+{
+    // 0 gezet. Wanneer op button 1 wordt gedrukt gaan we naar de
+    if (state_changed) {                                                        // demo modus, wanneer op button 2 wordt gedruk gaan we naar
+        pc.printf("Started encoder calibration\r\n");                           // de EMG calibratie
+        state_changed = false;
+    }
+    else if (but1_pressed) {
+        pc.printf("Encoder has been calibrated \r\n");
+        enc1_value = enc1.getPulses();
+        enc2_value = enc2.getPulses();
+        //enc1_value -= enc1_zero;
+        //enc2_value -= enc2_zero;
+        theta1 = (float)(enc1_value)/(float)(4200)*2*PI;                        // First arm rotated fully ccw
+        theta2 = (float)(enc2_value)/(float)(4200)*2*PI;                        // second arm fully clockwise --> looks like a Z
+        enc1_zero = enc1_value;
+        enc2_zero = enc2_value;
+        
+
+        pc.printf("enc01: %i\r\n", enc1_zero);
+        pc.printf("enc1value: %i\r\n", enc1_value);
+        pc.printf("enc02: %i\r\n",enc2_zero);
+        pc.printf("enc2value: %i\r\n", enc2_value);
+        pc.printf("hoek 1: %f\r\n",theta1);
+        pc.printf("hoek 2: %f\r\n",theta2);
+        but1_pressed = false;
+        state_changed = true;
+        state = s_demonstratie;
+    }
  
-void setMotor2(float motorValue2) {
-    // Given motorValue2<=1, writes the velocity to the pwm control.
-    // MotorValues outside range are truncated to within range.
-    motor2control.write(fabs(motorValue2) > 1 ? 1 : fabs(motorValue2));
+    else if (but2_pressed) {
+        pc.printf("Encoder has been calibrated \r\n");
+        enc1_value = enc1.getPulses();
+        enc2_value = enc2.getPulses();
+        //enc1_value -= enc1_zero;
+        //enc2_value -= enc2_zero;
+        theta1 = (float)(enc1_value)/(float)(4200)*2*PI;
+        theta2 = (float)(enc2_value)/(float)(4200)*2*PI;
+        enc1_zero = enc1_value;
+        enc2_zero = enc2_value;
+        
+
+        pc.printf("enc01: %i\r\n", enc1_zero);
+        pc.printf("enc1value: %i\r\n", enc1_value);
+        pc.printf("enc02: %i\r\n",enc2_zero);
+        pc.printf("enc2value: %i\r\n", enc2_value);
+        pc.printf("hoek 1: %f\r\n",theta1);
+        pc.printf("hoek 2: %f\r\n",theta2);
+        
+        but2_pressed = false;
+        state_changed = true;
+        state = s_EMGcalibratie;
+        
+    }
 }
  
-float feedForwardControl(float referenceVelocity) {
-    // very simple linear feed-forward control
-    // returns motorValue
-    return referenceVelocity / motorGain;
-}
+void filteren()
+{
+     //linkerbicep
+    emgLBraw= emgLB.read(); //dit wordt: emgLBoffset
+    emgLBHP=LeftBicepHP.step(emgLBraw);
+    emgLBN=LeftBicepN.step(emgLBHP);
+    //emgmeansubLB = emgLBN - RestmeanLB;
+    emgLBA= fabs(emgLBN);
+    emgLBfiltered=LeftBicepLP.step(emgLBA);
+    //LBvalue = emgLBfiltered/emgLB_max;
+
+   /* //to show if filter is working
+    scope.set(0, emgLBraw);
+    scope.set(1, emgLBfiltered);
+    scope.set(2, emgRBraw);
+    scope.set(3, emgRBfiltered);
+    scope.set(4, emgRTraw);
+    scope.set(5, emgRTfiltered); 
+    scope.send();
+*/
+    //rechterbicep
+    emgRBraw= emgRB.read();
+    emgRBHP= RightBicepHP.step(emgRBraw);
+    emgRBN=RightBicepN.step(emgRBHP);
+    //emgmeansubRB = emgRBN - RestmeanRB;
+    emgRBA= fabs(emgRBN);
+    emgRBfiltered=RightBicepLP.step(emgRBA);
+    //RBvalue = emgRBfiltered/emgRB_max;
+
+    //Right Quadriceps
+    emgRTraw= emgRT.read();
+    emgRTHP= RightLegHP.step(emgRTraw);
+    emgRTN= RightLegN.step(emgRTHP);
+   // emgmeansubRT = emgRTHP - RestmeanRT;
+    emgRTA= fabs(emgRTN);
+    emgRTfiltered=RightLegLP.step(emgRTA);
+    //RTvalue = emgRTfiltered/emgRT_max;
+   
  
-float feedForwardControl2(float referenceVelocity2) {
-    // very simple linear feed-forward control
-    // returns motorValue
-    return referenceVelocity2 / motorGain;
 }
  
-void measureAndControl(void) {
-    // This function measures the potmeter position, extracts a
-    // reference velocity from it, and controls the motor with 
-    // a simple FeedForward controller. Call this from a Ticker.
-    float referenceVelocity = getReferenceVelocity();
-    float motorValue1 = feedForwardControl(referenceVelocity);
-    setMotor1(motorValue1);
+void EMGcalibration()
+    {
+        
+            emgLBraw= emgLB.read(); //dit wordt: emgLBoffset
+            emgLBHP=LeftBicepHP.step(emgLBraw);
+            emgLBN=LeftBicepN.step(emgLBHP);
+            emgLBA= fabs(emgLBN);
+            emgLBfiltered=LeftBicepLP.step(emgLBA);
+    
+            emgRBraw= emgRB.read();
+            emgRBHP= RightBicepHP.step(emgRBraw);
+            emgRBN=RightBicepN.step(emgRBHP);
+            emgRBA= fabs(emgRBN);
+            emgRBfiltered=RightBicepLP.step(emgRBA);
+        
+    
+            emgRTraw= emgRT.read();
+            emgRTHP= RightLegHP.step(emgRTraw);
+            emgRTN= RightLegN.step(emgRTHP);
+            emgRTA= fabs(emgRTN);
+            emgRTfiltered=RightLegLP.step(emgRTA);
+    
+        if (tijd > 1000 && tijd < 6000) {
+            emgLBraw= emgLB.read();
+            emgLBHP=LeftBicepHP.step(emgLBraw);
+            emgLBN=LeftBicepN.step(emgLBHP);
+            //emgmeansubLB = emgLBN - restmeanLB;
+            emgLBA= fabs(emgLBN);
+            emgLBfiltered=LeftBicepLP.step(emgLBA);
+            if (emgLBfiltered > emgLB_max) {
+                emgLB_max = emgLBfiltered;
+            }
+            //pc.baud(115200);
+            //pc.printf("emgLB_max = %f \r\n", emgLB_max);// geen tekst printen in ticker want dat gaat mis xjes
+            ledr=0; //led gaat aan zodra je linkerbicep moet aanspannen
+        }
+    
+        else if (tijd > 7000 && tijd < 12000) {
+            emgRBraw= emgRB.read();
+            emgRBHP= RightBicepHP.step(emgRBraw);
+            emgRBN=RightBicepN.step(emgRBHP);
+            //emgmeansubRB = emgRBN - RestmeanRB;
+            emgRBA= fabs(emgRBN);
+            emgRBfiltered=RightBicepLP.step(emgRBA);
+            if (emgRBfiltered > emgRB_max) {
+                emgRB_max = emgRBfiltered;
+            }
+            //pc.printf("emgRB_max = %f \r\n", emgRB_max);
+            ledr=0; //led gaat uit zodra je rechterbicep moet aanspannen
+        }
+    
+    
+        else if (tijd > 13000 && tijd < 18000) {
+            emgRTraw= emgRT.read();
+            emgRTHP= RightLegHP.step(emgRTraw);
+            emgRTN= RightLegN.step(emgRTHP);
+            //emgmeansubRT = emgRTHP - RestmeanRT;
+            emgRTA= fabs(emgRTN);
+            emgRTfiltered=RightLegLP.step(emgRTA);
+            if (emgRTfiltered > emgRT_max) {
+                emgRT_max = emgRTfiltered;
+            }
+            //pc.printf("emgRT_max = %f \r\n", emgRT_max);
+            ledr=0; //led gaat aan zodra je rechterbeenspier moet aanspannen
+        } else if (tijd > 18000) {
+            ledr=1; //led gaat uit zodra kalibratie voltooid
+            state=s_EMG;
+            state_changed=true;
+            
+            //pc.printf("Calibration finished!");
+        } else {
+            ledr=1;
+            }
+     
+        pc.printf("%i", tijd);
+        tijd++;
+        threshold_emgLB = threshold*emgLB_max;   //bepaal threshold, nu op 0.15*maximale waarde. 
+        threshold_emgRB = threshold*emgRB_max; 
+        threshold_emgRT = threshold*emgRT_max;
+    
+    
+    // if threshold_emgx is reached, brushingmodes activated
+}
  
-    float referenceVelocity2 = getReferenceVelocity2();
-    float motorValue2 = feedForwardControl2(referenceVelocity2);
-    setMotor2(motorValue2);
-} 
+ 
  
-void onButtonPress() {
-    // reverses the direction
-    motor1direction.write(direction1 = !direction1);
-    pc.printf("direction: %s\r\n\n", direction1 ? "clockwise" : "counter clockwise");
+void SetMotor1(float motorValue1)
+{
+    // gegeven motorValue1 <=1, schrijft snelheid naar pwm.
+    // MotorValues buiten range worden afgekapt dat ze binnen de range vallen.
+    motor1_pwm.write(fabs(motorValue1) > 1 ? 1 : fabs(motorValue1));
+}
+ 
+void SetMotor2(float motorValue2)
+{
+    motor2_pwm.write(fabs(motorValue2) > 1 ? 1 : fabs(motorValue2));
 }
  
-void onButtonPress2() {
-    // reverses the direction
-    motor2direction.write(direction2 = !direction2);
-    pc.printf("direction: %s\r\n\n", direction2 ? "clockwise" : "counter clockwise");
-} 
-
-float Encoding()
+void brushingmode()
+{
+    
+        //boven draait arm 1 aan, dus motor 1 
+        //onder draait arm 2 aan, dus motor 2 
+        if (emgLBfiltered > threshold_emgLB){      //tandenborstel naar links (cw/ccw) //direction1/2 = cw/ccw
+        
+        motor2_direction.write(direction1);   //motor 2 gaat cw
+        //motor2_direction.write(direction1 = !direction1); //is counterclockwise
+        motor2_pwm.write(maxPWM2);
+        ledr=0;
+        
+        
+        }else if (emgRBfiltered > threshold_emgRB){
+            motor2_pwm.write(maxPWM2);
+            motor2_direction.write(direction1 = !direction1); //is counterclockwise
+        //tandenborstel naar rechts
+        ledg=0;
+        
+        
+        }else if (emgRTfiltered > threshold_emgRT){
+        motor1_direction.write(direction1 = !direction1);
+        motor1_pwm.write(maxPWM1);
+        //tandenborstel naar achter
+        ledb=0;
+        
+        }else if (emgRBfiltered > threshold_emgRB && emgLBfiltered > threshold_emgLB){
+        motor1_direction.write(direction1); //motor 1 gaat cw
+        motor1_pwm.write(maxPWM1);
+        //tandenborstel naar voren
+        ledg=0;
+        ledr=0;
+}
+}
+ 
+void demonstratie()
+{
+    if (state_changed) {                                                        //
+        pc.printf("Demonstratie gestart\r\n")   ;                                //
+        state_changed = false;
+    }
+}
+ 
+ 
+void RKI()
 {
-    // Encoding is necessary for the computations of the joint angles and 
-    // velocities of the arm given certain linear velocities. 
+    Lq1 = q1*r_trans;
+    Cq2 = q2/gear2;                               //1.25 is gear ratio voor q2
+ 
+    q1_dot = (v_x + (v_y*(L2*sin(q2/gear2)))/(L0 + q1*r_trans + L2*cos(q2/gear2)))/r_trans;
+    q2_dot = (gear2*v_y)/(L0 + q1*r_trans + L2*cos(q2/gear2));
+ 
+    q1_ii = q1 + q1_dot*dt;
+    q2_ii = q2 + q2_dot*dt;
+ 
+    q1 = q1_ii;
+    q2 = q2_ii;
+ 
+}
+ 
+double GetReferencePosition()
+{
+    double Potmeterwaarde = potMeter2.read();
+ 
+    double refP = Potmeterwaarde*maxwaarde;
+    return refP;
+}
  
-    double counts1 = Encoder1.getPulses();
-    double rad_m1 = (rad_count * (double)counts1) + (1.0f*pi/3.0f);
-    return rad_m1;
-} 
-
-float Encoding2()
+double GetReferencePosition2()
+{
+    double potmeterwaarde2 = potMeter1.read();
+    double refP2 = potmeterwaarde2*maxwaarde;
+    return refP2;
+}
+ 
+double FeedBackControl(double error, double &e_int)
 {
-    // Encoding is necessary for the computations of the joint angles and 
-    // velocities of the arm given certain linear velocities. 
+    //double Proportional= kp*error1;
+    double motorValue1= kp*error1;
+    //e_int = e_int+dt*error1;
+    //double Integrator = ki*e_int;
+ 
+   // motorValue1 = Proportional + Integrator ;
+    return motorValue1;
+}
+ 
+double FeedBackControl2(double error2, double &e_int2)
+{
+    //double Proportional2= kp2*error2;
+    double motorValue2= kp2*error2;
+    //e_int2 = e_int2+dt*error2;
+    //double Integrator2 = ki2*e_int2;
+ 
+    //double motorValue2 = Proportional2 + Integrator2 ;
+    return motorValue2;
+}
  
-    double counts2 = Encoder2.getPulses();
-    double rad_m2 = (rad_count * (double)counts2) + (7.0f*pi/4.0f);
-    return rad_m2;
-} 
-
-   void onDebugTick() {
-    
-    pc.printf("pot input1: %f\r\n", potMeterIn1.read());
-    pc.printf("motorValue1: %f\r\n", feedForwardControl(getReferenceVelocity()));
-    pc.printf("radialen motor 1: %f\r\n",Encoding());
+void MeasureAndControl()
+{
+    // RKI aanroepen
+    //RKI();
+    // hier the control of the 1st control system
+    refP = GetReferencePosition();                    //moet eigenlijk nog met RKI
+    Huidigepositie1 = enc1.getPulses()*4200;
+    //error1 = (refP - Huidigepositie1);// make an error
+    error1 = refP ;// ffwd
+    motorValue1 = FeedBackControl(error1, e_int);
+    SetMotor1(motorValue1);
+    // hier the control of the 2nd control system
+    refP2 = GetReferencePosition2();
+    Huidigepositie2 = enc2.getPulses();
+    //error2 = (refP2 - Huidigepositie2);// make an error
+    error2 = refP2;// ffwd
+    motorValue2 = FeedBackControl2(error2, e_int2);
+    SetMotor2(motorValue2);
+    //pc.printf("refP = %d, huidigepos = %d, motorvalue = %d, refP2 = %d, huidigepos2 = %d, motorvalue2 = %d \r\n", refP, Huidigepositie1, motorValue1, refP2, Huidigepositie2, Huidigepositie2);
+ 
+}
+ 
+void direction()
+{
+    if (butsw2==0) {
+        if (A==true) { // zodat het knopje 1 x wordt afgelezen
+            // richting veranderen
+            motor1_direction.write(direction1 = !direction1);
+            pc.printf("direction: %s\r\n\n", direction1 ? "clockwise" : "counter clockwise");
+            A=false;
+        }
+    } else {
+        A=true;
+    }
+ 
+    if (butsw3==0) {
+        if (B==true) {
+            motor2_direction.write(direction2 = !direction2);
+            pc.printf("direction: %s\r\n\n", direction2 ? "clockwise" : "counter clockwise");
+            B=false;
+        }
+    } else {
+        B=true;
+    }
+ 
+}
+ 
+void but1_interrupt()
+{
+    /*if(but2.read()) {//both buttons are pressed
+     failure_occurred = true;
+    }*/
+    but1_pressed = true;
+    pc.printf("Button 1 interrupt active \n\r");
+}
+ 
+void but2_interrupt()
+{
+    /*if(but1.read()) {//both buttons are pressed
+      failure_occurred = true;
+    }*/
+    but2_pressed = true;
+    pc.printf("Button 2 interrupt active \n\r");
+}
 
-    pc.printf("\n\n\n");
-    
-    /*
-    scope.set(0, potMeterIn.read());
-    scope.set(1, feedForwardControl(getReferenceVelocity()));
-    scope.send();
-    */
-    pc.printf("pot input2: %f\r\n", potMeterIn2.read());
-    pc.printf("motorValue2: %f\r\n", feedForwardControl2(getReferenceVelocity2()));
-        pc.printf("radialen motor 2: %f\r\n",Encoding2());
-    pc.printf("\n\n\n");
-    }
-    
+ void state_machine()
+{
+    //run current state
+    switch (state) {
+        case s_idle:                                                            // in deze state gebeurd niets. Als op knop 1 wordt gedrukt
+            rest();                                                             // gaan we over naar s_calibratie_encoder
+            break;
+        case s_calibratie_encoder:                                              // in deze state worden de encoders gekalibreerd. knop 1 -> s_demonstratie
+            calibratie_encoder();                                               // knop 2 -> s_EMGcalibratie
+            break;
+        case s_demonstratie:                                                    // in deze state kunnen de motors worden bestuurd met de potmeters
+            demonstratie();
+            MeasureAndControl();                                                // en switch 2 en 3( pot1,sw2->motor1 / pot2,sw3->motor2
+            direction();                                                        // als op knop 2 wordt gedrukt komen we in de s_idle state
+            if (but2_pressed) {
+                pc.printf("fail. \r\n");
+                but2_pressed = false;
+                state_changed = true;
+                state = s_idle;
+            }
+            break;
+            
+        case s_EMGcalibratie:
+            EMGcalibration();
+            break;
+            
+        case s_EMG:
+            ledg=1;
+            ledr=1;
+            ledb=1;
+            state_changed=false;
+            filteren();
+            brushingmode();
+               if (but2_pressed) {
+                pc.printf("fail. \r\n");
+                but2_pressed = false;
+                state_changed = true;
+                state = s_idle;
+                }
+            break;
+ 
+        }
+}
+
 int main()
 {
     pc.baud(115200);
-    
-    button2.fall(&onButtonPress2);
-    controlTicker.attach(&measureAndControl, 1.0f/100.0f);
-    debugTicker.attach(&onDebugTick, 1);
-    
-    button1.fall(&onButtonPress);
-    
-}
\ No newline at end of file
+    pc.printf("Executing main()... \r\n");
+    state = s_idle;
+    ledg=1;
+    ledr=1;
+    ledb=1;
+ 
+    LeftBicepHP.add( &LBHP1 );  //BiQuadChain bqc;   //bqc.add( &bq1 ).add( &bq2 );
+    LeftBicepN.add( &LBN1 );
+    LeftBicepLP.add( &LBLP1 );
+
+
+    RightBicepHP.add( &RBHP1 );
+    RightBicepN.add( &RBN1 );
+    RightBicepLP.add( &RBLP1 );
+
+    RightLegHP.add( &RTHP1 );
+    RightLegN.add( &RTN1 );
+    RightLegLP.add( &RTLP1 );
+ 
+    but1.fall(&but1_interrupt);
+    but2.fall(&but2_interrupt);
+    loop_ticker.attach(&state_machine, dt); 
+    pc.printf("state_machine active!\n\r");
+ 
+}
+ 
+ 
+ 
\ No newline at end of file