fancy lampje

Dependencies:   mbed QEI HIDScope biquadFilter MODSERIAL FXOS8700Q FastPWM

Committer:
MatthewMaat
Date:
Fri Oct 18 10:14:17 2019 +0000
Revision:
16:2d115aa2773e
Parent:
15:c4799ad02cdc
Child:
17:d1acb6888b82
FSM met EMG kalibratie

Who changed what in which revision?

UserRevisionLine numberNew contents of line
RobertoO 0:67c50348f842 1 #include "mbed.h"
MatthewMaat 13:ec4708dab45d 2 #include "HIDScope.h"
MatthewMaat 11:de4a85703169 3 //#include "QEI.h"
RobertoO 1:b862262a9d14 4 #include "MODSERIAL.h"
RobertoO 0:67c50348f842 5 //#include "BiQuad.h"
MatthewMaat 8:ec3c634390c7 6 #include "FastPWM.h"
MatthewMaat 2:626688c21b6f 7 #include <iostream>
MatthewMaat 5:cee5f898b350 8 MODSERIAL pc(USBTX, USBRX);
MatthewMaat 13:ec4708dab45d 9 AnalogIn ain2(A2);
MatthewMaat 13:ec4708dab45d 10 AnalogIn ain1(A3);
MatthewMaat 13:ec4708dab45d 11 DigitalOut dir2(D4);
MatthewMaat 13:ec4708dab45d 12 DigitalOut dir1(D7);
MatthewMaat 13:ec4708dab45d 13 //D4,D7 direction of motors 2,1 on board, D5,D6- PWM of motors 2,1 on board
MatthewMaat 13:ec4708dab45d 14 PwmOut motor2_pwm(D5);
MatthewMaat 13:ec4708dab45d 15 PwmOut motor1_pwm(D6);
MatthewMaat 13:ec4708dab45d 16 AnalogIn emg0( A0 );
MatthewMaat 13:ec4708dab45d 17 AnalogIn emg1( A1 );
MatthewMaat 13:ec4708dab45d 18
MatthewMaat 15:c4799ad02cdc 19 Ticker ticktick;
MatthewMaat 15:c4799ad02cdc 20 Timer state_time;
MatthewMaat 15:c4799ad02cdc 21 Timeout EMG_peak;
MatthewMaat 13:ec4708dab45d 22 Ticker sample_timer;
MatthewMaat 15:c4799ad02cdc 23 HIDScope scope( 3);
MatthewMaat 14:dc89250ebc52 24 DigitalOut ledred(LED_RED);
MatthewMaat 14:dc89250ebc52 25 DigitalOut ledblue(LED_BLUE);
MatthewMaat 14:dc89250ebc52 26 DigitalOut ledgreen(LED_GREEN);
MatthewMaat 15:c4799ad02cdc 27 InterruptIn err(SW2);
MatthewMaat 15:c4799ad02cdc 28 InterruptIn button(SW3);
MatthewMaat 15:c4799ad02cdc 29
MatthewMaat 15:c4799ad02cdc 30 volatile float P0;
MatthewMaat 15:c4799ad02cdc 31 volatile float P1;
MatthewMaat 15:c4799ad02cdc 32 volatile float EMG_min0=1;
MatthewMaat 15:c4799ad02cdc 33 volatile float EMG_max0=0;
MatthewMaat 15:c4799ad02cdc 34 volatile float EMG_min1=1;
MatthewMaat 15:c4799ad02cdc 35 volatile float EMG_max1=0;
MatthewMaat 15:c4799ad02cdc 36 volatile bool ignore_peaks=false;
MatthewMaat 16:2d115aa2773e 37 volatile bool ignore_turn=true;
MatthewMaat 14:dc89250ebc52 38 enum states{Waiting,Position_calibration,EMG_calibration,Homing,Operating,Demo,Failure};
MatthewMaat 15:c4799ad02cdc 39 states currentState=Waiting;
MatthewMaat 10:e1eb73e19540 40
MatthewMaat 14:dc89250ebc52 41
MatthewMaat 14:dc89250ebc52 42 void read_emg()
MatthewMaat 13:ec4708dab45d 43 {
MatthewMaat 15:c4799ad02cdc 44 //EMG signal 0
MatthewMaat 15:c4799ad02cdc 45 static int count0=0;
MatthewMaat 15:c4799ad02cdc 46 static float RMS_value0=0;
MatthewMaat 15:c4799ad02cdc 47 static float HighPass_value0=0;
MatthewMaat 15:c4799ad02cdc 48 count0+=1;
MatthewMaat 15:c4799ad02cdc 49 static float RMS0[150];
MatthewMaat 15:c4799ad02cdc 50 static float HighPass0[30];
MatthewMaat 15:c4799ad02cdc 51 float I0;
MatthewMaat 15:c4799ad02cdc 52 float If0;
MatthewMaat 15:c4799ad02cdc 53 //signal 1
MatthewMaat 15:c4799ad02cdc 54 static int count1=0;
MatthewMaat 15:c4799ad02cdc 55 static float RMS_value1=0;
MatthewMaat 15:c4799ad02cdc 56 static float HighPass_value1=0;
MatthewMaat 15:c4799ad02cdc 57 count1+=1;
MatthewMaat 15:c4799ad02cdc 58 static float RMS1[150];
MatthewMaat 15:c4799ad02cdc 59 static float HighPass1[30];
MatthewMaat 13:ec4708dab45d 60 float I1;
MatthewMaat 15:c4799ad02cdc 61 float If1;
MatthewMaat 15:c4799ad02cdc 62 I0=emg0.read(); //read signal
MatthewMaat 15:c4799ad02cdc 63 HighPass_value0+=(I0-HighPass0[count0%30])/30.0;
MatthewMaat 15:c4799ad02cdc 64 HighPass0[count0%30]=I0;
MatthewMaat 15:c4799ad02cdc 65 If0=pow(I0-HighPass_value0,2.0f); // Highpass-filtered value squared
MatthewMaat 15:c4799ad02cdc 66 RMS_value0+=(If0-RMS0[count0%150])/150.0;
MatthewMaat 15:c4799ad02cdc 67 RMS0[count0%150]=If0;
MatthewMaat 13:ec4708dab45d 68 /* Set the sampled emg values in channel 0 (the first channel) and 1 (the second channel) in the 'HIDScope' instance named 'scope' */
MatthewMaat 15:c4799ad02cdc 69 P0=sqrt(RMS_value0);
MatthewMaat 15:c4799ad02cdc 70 I1=emg1.read(); //read signal
MatthewMaat 15:c4799ad02cdc 71 HighPass_value1+=(I1-HighPass1[count1%30])/30.0;
MatthewMaat 15:c4799ad02cdc 72 HighPass1[count1%30]=I1;
MatthewMaat 15:c4799ad02cdc 73 If1=pow(I1-HighPass_value1,2.0f); // Highpass-filtered value squared
MatthewMaat 15:c4799ad02cdc 74 RMS_value1+=(If1-RMS1[count1%150])/150.0;
MatthewMaat 15:c4799ad02cdc 75 RMS1[count1%150]=If1;
MatthewMaat 15:c4799ad02cdc 76 /* Set the sampled emg values in channel 0 (the first channel) and 1 (the second channel) in the 'HIDScope' instance named 'scope' */
MatthewMaat 15:c4799ad02cdc 77 P1=sqrt(RMS_value1);
MatthewMaat 15:c4799ad02cdc 78 scope.set(0, P0 ); // send root mean squared
MatthewMaat 15:c4799ad02cdc 79 scope.set(1, EMG_min0);
MatthewMaat 15:c4799ad02cdc 80 scope.set(2,EMG_max0);
MatthewMaat 13:ec4708dab45d 81 /* Repeat the step above if required for more channels of required (channel 0 up to 5 = 6 channels)
MatthewMaat 13:ec4708dab45d 82 * Ensure that enough channels are available (HIDScope scope( 2 ))
MatthewMaat 13:ec4708dab45d 83 * Finally, send all channels to the PC at once */
MatthewMaat 13:ec4708dab45d 84 scope.send();
MatthewMaat 13:ec4708dab45d 85 /* To indicate that the function is working, the LED is toggled */
MatthewMaat 14:dc89250ebc52 86 ledred=1;
MatthewMaat 14:dc89250ebc52 87 ledgreen=0;
MatthewMaat 14:dc89250ebc52 88 ledblue=1;
MatthewMaat 13:ec4708dab45d 89 }
MatthewMaat 14:dc89250ebc52 90
MatthewMaat 15:c4799ad02cdc 91 void record_min_max(void)
MatthewMaat 15:c4799ad02cdc 92 {
MatthewMaat 15:c4799ad02cdc 93 float t=state_time.read();
MatthewMaat 15:c4799ad02cdc 94 if(t>0.4)
MatthewMaat 15:c4799ad02cdc 95 {
MatthewMaat 15:c4799ad02cdc 96 if(P0<EMG_min0)
MatthewMaat 15:c4799ad02cdc 97 {
MatthewMaat 15:c4799ad02cdc 98 EMG_min0=P0;
MatthewMaat 15:c4799ad02cdc 99 }
MatthewMaat 15:c4799ad02cdc 100 else if(P0>EMG_max0)
MatthewMaat 15:c4799ad02cdc 101 {
MatthewMaat 15:c4799ad02cdc 102 EMG_max0=P0;
MatthewMaat 15:c4799ad02cdc 103 }
MatthewMaat 15:c4799ad02cdc 104 if(P1<EMG_min1)
MatthewMaat 15:c4799ad02cdc 105 {
MatthewMaat 15:c4799ad02cdc 106 EMG_min1=P1;
MatthewMaat 15:c4799ad02cdc 107 }
MatthewMaat 15:c4799ad02cdc 108 else if(P1>EMG_max1)
MatthewMaat 15:c4799ad02cdc 109 {
MatthewMaat 15:c4799ad02cdc 110 EMG_max1=P1;
MatthewMaat 15:c4799ad02cdc 111 }
MatthewMaat 15:c4799ad02cdc 112 }
MatthewMaat 15:c4799ad02cdc 113 }
MatthewMaat 15:c4799ad02cdc 114
MatthewMaat 15:c4799ad02cdc 115 void unignore_peaks(void)
MatthewMaat 15:c4799ad02cdc 116 {
MatthewMaat 15:c4799ad02cdc 117 ignore_peaks=false;
MatthewMaat 15:c4799ad02cdc 118 }
MatthewMaat 16:2d115aa2773e 119 void start_ignore_turn(void)
MatthewMaat 16:2d115aa2773e 120 {
MatthewMaat 16:2d115aa2773e 121 ignore_turn=true;
MatthewMaat 16:2d115aa2773e 122 }
MatthewMaat 15:c4799ad02cdc 123
MatthewMaat 14:dc89250ebc52 124 void set_PWM(void)
MatthewMaat 11:de4a85703169 125 {
MatthewMaat 15:c4799ad02cdc 126 static bool motor_on=false;
MatthewMaat 15:c4799ad02cdc 127 float Q0;
MatthewMaat 15:c4799ad02cdc 128 Q0=2.0f*(P0-(EMG_min0+EMG_max0)/2.0f)/(EMG_max0-EMG_min0);
MatthewMaat 16:2d115aa2773e 129 if (Q0>0.3 && !ignore_peaks)
MatthewMaat 13:ec4708dab45d 130 {
MatthewMaat 15:c4799ad02cdc 131 if (!motor_on)
MatthewMaat 15:c4799ad02cdc 132 {
MatthewMaat 15:c4799ad02cdc 133 motor1_pwm.write(1.0f);
MatthewMaat 15:c4799ad02cdc 134 EMG_peak.attach(unignore_peaks,1);
MatthewMaat 15:c4799ad02cdc 135 ignore_peaks=true;
MatthewMaat 15:c4799ad02cdc 136 motor_on=true;
MatthewMaat 15:c4799ad02cdc 137 }
MatthewMaat 16:2d115aa2773e 138 else if(ignore_turn)
MatthewMaat 15:c4799ad02cdc 139 {
MatthewMaat 15:c4799ad02cdc 140 motor1_pwm.write(0.0f);
MatthewMaat 15:c4799ad02cdc 141 EMG_peak.attach(unignore_peaks,1);
MatthewMaat 16:2d115aa2773e 142 EMG_peak.attach(start_ignore_turn,1.5);
MatthewMaat 16:2d115aa2773e 143 ignore_turn=false;
MatthewMaat 15:c4799ad02cdc 144 ignore_peaks=true;
MatthewMaat 15:c4799ad02cdc 145 motor_on=false;
MatthewMaat 15:c4799ad02cdc 146 }
MatthewMaat 16:2d115aa2773e 147 else
MatthewMaat 16:2d115aa2773e 148 {
MatthewMaat 16:2d115aa2773e 149 motor1_pwm.write(1.0f);
MatthewMaat 16:2d115aa2773e 150 dir1=!dir1;
MatthewMaat 16:2d115aa2773e 151 EMG_peak.attach(unignore_peaks,1);
MatthewMaat 16:2d115aa2773e 152 ignore_peaks=true;
MatthewMaat 16:2d115aa2773e 153 motor_on=true;
MatthewMaat 16:2d115aa2773e 154 }
MatthewMaat 13:ec4708dab45d 155 }
MatthewMaat 13:ec4708dab45d 156 motor2_pwm.write(ain1.read());
MatthewMaat 11:de4a85703169 157 }
MatthewMaat 11:de4a85703169 158
MatthewMaat 14:dc89250ebc52 159 void sample()
MatthewMaat 14:dc89250ebc52 160 {
MatthewMaat 14:dc89250ebc52 161 switch(currentState)
MatthewMaat 14:dc89250ebc52 162 {
MatthewMaat 15:c4799ad02cdc 163 case Waiting:
MatthewMaat 15:c4799ad02cdc 164 ledred=0;
MatthewMaat 15:c4799ad02cdc 165 ledgreen=0;
MatthewMaat 15:c4799ad02cdc 166 ledblue=1;
MatthewMaat 15:c4799ad02cdc 167 break;
MatthewMaat 15:c4799ad02cdc 168 case Position_calibration:
MatthewMaat 15:c4799ad02cdc 169 ledred=1;
MatthewMaat 15:c4799ad02cdc 170 ledgreen=1;
MatthewMaat 15:c4799ad02cdc 171 ledblue=0;
MatthewMaat 15:c4799ad02cdc 172 break;
MatthewMaat 15:c4799ad02cdc 173 case EMG_calibration:
MatthewMaat 15:c4799ad02cdc 174 ledred=1;
MatthewMaat 15:c4799ad02cdc 175 ledgreen=0;
MatthewMaat 15:c4799ad02cdc 176 ledblue=0;
MatthewMaat 15:c4799ad02cdc 177 read_emg();
MatthewMaat 15:c4799ad02cdc 178 record_min_max();
MatthewMaat 15:c4799ad02cdc 179 break;
MatthewMaat 15:c4799ad02cdc 180 case Homing:
MatthewMaat 15:c4799ad02cdc 181 ledred=0;
MatthewMaat 15:c4799ad02cdc 182 ledgreen=1;
MatthewMaat 15:c4799ad02cdc 183 ledblue=0;
MatthewMaat 15:c4799ad02cdc 184 break;
MatthewMaat 14:dc89250ebc52 185 case Operating:
MatthewMaat 14:dc89250ebc52 186 read_emg();
MatthewMaat 14:dc89250ebc52 187 set_PWM();
MatthewMaat 15:c4799ad02cdc 188 ledred=1;
MatthewMaat 15:c4799ad02cdc 189 ledgreen=0;
MatthewMaat 15:c4799ad02cdc 190 ledblue=1;
MatthewMaat 15:c4799ad02cdc 191 break;
MatthewMaat 15:c4799ad02cdc 192 case Demo:
MatthewMaat 15:c4799ad02cdc 193 ledred=0;
MatthewMaat 15:c4799ad02cdc 194 ledgreen=0;
MatthewMaat 15:c4799ad02cdc 195 ledblue=0;
MatthewMaat 14:dc89250ebc52 196 break;
MatthewMaat 14:dc89250ebc52 197 case Failure:
MatthewMaat 14:dc89250ebc52 198 ledred=0;
MatthewMaat 14:dc89250ebc52 199 ledgreen=1;
MatthewMaat 14:dc89250ebc52 200 ledblue=1;
MatthewMaat 15:c4799ad02cdc 201 motor1_pwm.write(0.0);
MatthewMaat 15:c4799ad02cdc 202 motor2_pwm.write(0.0);
MatthewMaat 14:dc89250ebc52 203 break;
MatthewMaat 14:dc89250ebc52 204 }
MatthewMaat 14:dc89250ebc52 205 }
MatthewMaat 14:dc89250ebc52 206
MatthewMaat 14:dc89250ebc52 207 void error_occur()
MatthewMaat 14:dc89250ebc52 208 {
MatthewMaat 14:dc89250ebc52 209 currentState=Failure;
MatthewMaat 14:dc89250ebc52 210 }
MatthewMaat 14:dc89250ebc52 211
MatthewMaat 15:c4799ad02cdc 212 void button_press()
MatthewMaat 15:c4799ad02cdc 213 //Press button to change state
MatthewMaat 15:c4799ad02cdc 214 {
MatthewMaat 15:c4799ad02cdc 215 state_time.start();
MatthewMaat 15:c4799ad02cdc 216 switch(currentState)
MatthewMaat 15:c4799ad02cdc 217 {
MatthewMaat 15:c4799ad02cdc 218 case Waiting:
MatthewMaat 15:c4799ad02cdc 219 currentState=Position_calibration;
MatthewMaat 15:c4799ad02cdc 220 wait(1);
MatthewMaat 15:c4799ad02cdc 221 break;
MatthewMaat 15:c4799ad02cdc 222 case Position_calibration:
MatthewMaat 15:c4799ad02cdc 223 currentState=EMG_calibration;
MatthewMaat 15:c4799ad02cdc 224 wait(1);
MatthewMaat 15:c4799ad02cdc 225 break;
MatthewMaat 15:c4799ad02cdc 226 case EMG_calibration:
MatthewMaat 15:c4799ad02cdc 227 currentState=Homing;
MatthewMaat 15:c4799ad02cdc 228 wait(1);
MatthewMaat 15:c4799ad02cdc 229 break;
MatthewMaat 15:c4799ad02cdc 230 case Homing:
MatthewMaat 15:c4799ad02cdc 231 currentState=Operating;
MatthewMaat 15:c4799ad02cdc 232 wait(1);
MatthewMaat 15:c4799ad02cdc 233 break;
MatthewMaat 15:c4799ad02cdc 234 case Operating:
MatthewMaat 15:c4799ad02cdc 235 currentState=Demo;
MatthewMaat 15:c4799ad02cdc 236 wait(1);
MatthewMaat 15:c4799ad02cdc 237 break;
MatthewMaat 15:c4799ad02cdc 238 case Demo:
MatthewMaat 15:c4799ad02cdc 239 currentState=Operating;
MatthewMaat 15:c4799ad02cdc 240 wait(1);
MatthewMaat 15:c4799ad02cdc 241 break;
MatthewMaat 15:c4799ad02cdc 242 }
MatthewMaat 15:c4799ad02cdc 243 }
MatthewMaat 15:c4799ad02cdc 244
MatthewMaat 8:ec3c634390c7 245 int main()
MatthewMaat 4:f988679bf9a1 246 {
MatthewMaat 14:dc89250ebc52 247 pc.baud(115200);
MatthewMaat 14:dc89250ebc52 248 pc.printf("Starting...");
MatthewMaat 14:dc89250ebc52 249 ledred=0;
MatthewMaat 13:ec4708dab45d 250 sample_timer.attach(&sample, 0.002);
MatthewMaat 14:dc89250ebc52 251 err.fall(error_occur);
MatthewMaat 15:c4799ad02cdc 252 button.fall(button_press);
MatthewMaat 12:7f280a661e71 253 int frequency_pwm=10000;
MatthewMaat 12:7f280a661e71 254 motor1_pwm.period(1.0/frequency_pwm);
MatthewMaat 13:ec4708dab45d 255 motor2_pwm.period(1.0/frequency_pwm);
MatthewMaat 11:de4a85703169 256
MatthewMaat 8:ec3c634390c7 257 while (true) {
MatthewMaat 12:7f280a661e71 258 wait(10);
MatthewMaat 4:f988679bf9a1 259 }
MatthewMaat 4:f988679bf9a1 260 }