test
Dependencies: HIDScope MODSERIAL mbed-dsp mbed
Fork of emg_filter2 by
EMGfilter.cpp@22:dc630dbb1dcd, 2014-10-10 (annotated)
- Committer:
- s1340735
- Date:
- Fri Oct 10 09:54:49 2014 +0000
- Revision:
- 22:dc630dbb1dcd
- Child:
- 23:1c51af8386c9
poging 1 bicep tricep filter
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
s1340735 | 22:dc630dbb1dcd | 1 | #include "mbed.h" |
s1340735 | 22:dc630dbb1dcd | 2 | #include "HIDScope.h" |
s1340735 | 22:dc630dbb1dcd | 3 | |
s1340735 | 22:dc630dbb1dcd | 4 | #include "arm_math.h" |
s1340735 | 22:dc630dbb1dcd | 5 | |
s1340735 | 22:dc630dbb1dcd | 6 | //Define objects |
s1340735 | 22:dc630dbb1dcd | 7 | AnalogIn emgB(PTB0); //Analog input bicep |
s1340735 | 22:dc630dbb1dcd | 8 | AnalogIn emgT(PTB1); //Analog input tricep |
s1340735 | 22:dc630dbb1dcd | 9 | |
s1340735 | 22:dc630dbb1dcd | 10 | HIDScope scope(2);//WHAT IS THIS |
s1340735 | 22:dc630dbb1dcd | 11 | |
s1340735 | 22:dc630dbb1dcd | 12 | arm_biquad_casd_df1_inst_f32 lowpass; |
s1340735 | 22:dc630dbb1dcd | 13 | //constants for 50Hz lowpass |
s1340735 | 22:dc630dbb1dcd | 14 | float lowpass_const[] = {-0.2924 , 0.1085 , 0 , 0.5587 , 0.2573};//{a1 a2 b0 b1 b2} normalized coefficients (a0=1) |
s1340735 | 22:dc630dbb1dcd | 15 | //state values |
s1340735 | 22:dc630dbb1dcd | 16 | float lowpass_states[4];//WHAT IS THIS |
s1340735 | 22:dc630dbb1dcd | 17 | |
s1340735 | 22:dc630dbb1dcd | 18 | arm_biquad_casd_df1_inst_f32 highpass; |
s1340735 | 22:dc630dbb1dcd | 19 | //constants for 10Hz highpass |
s1340735 | 22:dc630dbb1dcd | 20 | float highpass_const[] = {-1.562, 0.6413, 1, -1.958 , 0.9576};//{a1 a2 b0 b1 b2} normalized coefficients (a0=1) |
s1340735 | 22:dc630dbb1dcd | 21 | //state values |
s1340735 | 22:dc630dbb1dcd | 22 | float highpass_states[4];//WHAT IS THIS |
s1340735 | 22:dc630dbb1dcd | 23 | |
s1340735 | 22:dc630dbb1dcd | 24 | |
s1340735 | 22:dc630dbb1dcd | 25 | /** Looper function |
s1340735 | 22:dc630dbb1dcd | 26 | * functions used for Ticker and Timeout should be of type void <name>(void) |
s1340735 | 22:dc630dbb1dcd | 27 | * i.e. no input arguments, no output arguments. |
s1340735 | 22:dc630dbb1dcd | 28 | * if you want to change a variable that you use in other places (for example in main) |
s1340735 | 22:dc630dbb1dcd | 29 | * you will have to make that variable global in order to be able to reach it both from |
s1340735 | 22:dc630dbb1dcd | 30 | * the function called at interrupt time, and in the main function. |
s1340735 | 22:dc630dbb1dcd | 31 | * To make a variable global, define it under the includes. |
s1340735 | 22:dc630dbb1dcd | 32 | * variables that are changed in the interrupt routine (written to) should be made |
s1340735 | 22:dc630dbb1dcd | 33 | * 'volatile' to let the compiler know that those values may change outside the current context. |
s1340735 | 22:dc630dbb1dcd | 34 | * i.e.: "volatile uint16_t emg_value;" instead of "uint16_t emg_value" |
s1340735 | 22:dc630dbb1dcd | 35 | * in the example below, the variable is not re-used in the main function, and is thus declared |
s1340735 | 22:dc630dbb1dcd | 36 | * local in the looper function only. |
s1340735 | 22:dc630dbb1dcd | 37 | **/ |
s1340735 | 22:dc630dbb1dcd | 38 | |
s1340735 | 22:dc630dbb1dcd | 39 | //BICEP EMG LEZEN |
s1340735 | 22:dc630dbb1dcd | 40 | void looperB() |
s1340735 | 22:dc630dbb1dcd | 41 | { |
s1340735 | 22:dc630dbb1dcd | 42 | /*variable to store value in*/ |
s1340735 | 22:dc630dbb1dcd | 43 | uint16_t emg_valueB; |
s1340735 | 22:dc630dbb1dcd | 44 | float filtered_emgB; |
s1340735 | 22:dc630dbb1dcd | 45 | float emg_value_f32B; |
s1340735 | 22:dc630dbb1dcd | 46 | /*put raw emg value both in red and in emg_value*/ |
s1340735 | 22:dc630dbb1dcd | 47 | emg_valueB = emgB.read_u16(); // read direct ADC result, converted to 16 bit integer (0..2^16 = 0..65536 = 0..3.3V) |
s1340735 | 22:dc630dbb1dcd | 48 | emg_value_f32B = emgB.read(); |
s1340735 | 22:dc630dbb1dcd | 49 | |
s1340735 | 22:dc630dbb1dcd | 50 | //process emg |
s1340735 | 22:dc630dbb1dcd | 51 | arm_biquad_cascade_df1_f32(&highpass, &emg_value_f32B, &filtered_emgB, 1 ); |
s1340735 | 22:dc630dbb1dcd | 52 | filtered_emgB = fabs(filtered_emgB); |
s1340735 | 22:dc630dbb1dcd | 53 | arm_biquad_cascade_df1_f32(&lowpass, &filtered_emgB, &filtered_emgB, 1 ); |
s1340735 | 22:dc630dbb1dcd | 54 | |
s1340735 | 22:dc630dbb1dcd | 55 | /*send value to PC. */ |
s1340735 | 22:dc630dbb1dcd | 56 | scope.set(0,emg_valueB); //uint value |
s1340735 | 22:dc630dbb1dcd | 57 | scope.set(1,filtered_emgB); //processed float |
s1340735 | 22:dc630dbb1dcd | 58 | scope.send(); |
s1340735 | 22:dc630dbb1dcd | 59 | |
s1340735 | 22:dc630dbb1dcd | 60 | } |
s1340735 | 22:dc630dbb1dcd | 61 | |
s1340735 | 22:dc630dbb1dcd | 62 | void looperT() |
s1340735 | 22:dc630dbb1dcd | 63 | { |
s1340735 | 22:dc630dbb1dcd | 64 | /*variable to store value in*/ |
s1340735 | 22:dc630dbb1dcd | 65 | uint16_t emg_valueT; |
s1340735 | 22:dc630dbb1dcd | 66 | float filtered_emgT; |
s1340735 | 22:dc630dbb1dcd | 67 | float emg_value_f32T; |
s1340735 | 22:dc630dbb1dcd | 68 | /*put raw emg value both in red and in emg_value*/ |
s1340735 | 22:dc630dbb1dcd | 69 | emg_valueT = emgT.read_u16(); // read direct ADC result, converted to 16 bit integer (0..2^16 = 0..65536 = 0..3.3V) |
s1340735 | 22:dc630dbb1dcd | 70 | emg_value_f32T = emgT.read(); |
s1340735 | 22:dc630dbb1dcd | 71 | |
s1340735 | 22:dc630dbb1dcd | 72 | //process emg |
s1340735 | 22:dc630dbb1dcd | 73 | arm_biquad_cascade_df1_f32(&highpass, &emg_value_f32T, &filtered_emgT, 1 ); |
s1340735 | 22:dc630dbb1dcd | 74 | filtered_emgT = fabs(filtered_emgT); |
s1340735 | 22:dc630dbb1dcd | 75 | arm_biquad_cascade_df1_f32(&lowpass, &filtered_emgT, &filtered_emgT, 1 ); |
s1340735 | 22:dc630dbb1dcd | 76 | |
s1340735 | 22:dc630dbb1dcd | 77 | /*send value to PC. */ |
s1340735 | 22:dc630dbb1dcd | 78 | scope.set(0,emg_valueT); //uint value |
s1340735 | 22:dc630dbb1dcd | 79 | scope.set(1,filtered_emgT); //processed float |
s1340735 | 22:dc630dbb1dcd | 80 | scope.send(); |
s1340735 | 22:dc630dbb1dcd | 81 | |
s1340735 | 22:dc630dbb1dcd | 82 | } |
s1340735 | 22:dc630dbb1dcd | 83 | |
s1340735 | 22:dc630dbb1dcd | 84 | int main() |
s1340735 | 22:dc630dbb1dcd | 85 | { |
s1340735 | 22:dc630dbb1dcd | 86 | Ticker log_timer; |
s1340735 | 22:dc630dbb1dcd | 87 | //set up filters. Use external array for constants |
s1340735 | 22:dc630dbb1dcd | 88 | arm_biquad_cascade_df1_init_f32(&lowpass,1 , lowpass_const, lowpass_states); |
s1340735 | 22:dc630dbb1dcd | 89 | arm_biquad_cascade_df1_init_f32(&highpass,1 ,highpass_const, highpass_states); |
s1340735 | 22:dc630dbb1dcd | 90 | |
s1340735 | 22:dc630dbb1dcd | 91 | /**Here you attach the 'void looper(void)' function to the Ticker object |
s1340735 | 22:dc630dbb1dcd | 92 | * The looper() function will be called every 0.01 seconds. |
s1340735 | 22:dc630dbb1dcd | 93 | * Please mind that the parentheses after looper are omitted when using attach. |
s1340735 | 22:dc630dbb1dcd | 94 | */ |
s1340735 | 22:dc630dbb1dcd | 95 | log_timer.attach(looperB, 0.005);//?? |
s1340735 | 22:dc630dbb1dcd | 96 | log_timer.attach(looperT, 0.005);//?? |
s1340735 | 22:dc630dbb1dcd | 97 | while(1) //Loop |
s1340735 | 22:dc630dbb1dcd | 98 | { |
s1340735 | 22:dc630dbb1dcd | 99 | /*Empty!*/ |
s1340735 | 22:dc630dbb1dcd | 100 | |
s1340735 | 22:dc630dbb1dcd | 101 | |
s1340735 | 22:dc630dbb1dcd | 102 | //filtered_emgB |
s1340735 | 22:dc630dbb1dcd | 103 | //filtered_emgT |
s1340735 | 22:dc630dbb1dcd | 104 | |
s1340735 | 22:dc630dbb1dcd | 105 | /*Everything is handled by the interrupt routine now!*/ |
s1340735 | 22:dc630dbb1dcd | 106 | } |
s1340735 | 22:dc630dbb1dcd | 107 | } |