Hybrid sEMG + IMU activated controller for Galileo Bionic Hand Prosthesis
Dependencies: FXAS21000 FXOS8700Q kalman mbed-dsp mbed-rtos mbed
main.cpp
- Committer:
- julioefajardo
- Date:
- 2015-10-16
- Revision:
- 0:2245e978868c
- Child:
- 1:84347af5a1f2
File content as of revision 0:2245e978868c:
#include "mbed.h" #include "FXOS8700Q.h" #include "FXAS21000.h" #include "rtos.h" #include "kalman.c" #include "arm_math.h" #define TRUE 1 #define FALSE 0 #define RAW 0 #define RECTIFIED 1 #define SMOOTH 2 #define THRESHOLDF 0.25f #define THRESHOLDE 0.25f #define FLEXION2 0.0f #define Rad2Dree 57.295779513082320876798154814105f Serial pc(USBTX, USBRX); AnalogIn Ref(A0); AnalogIn E1(A1); AnalogIn E2(A2); AnalogIn E3(A3); FXOS8700Q_acc combo_acc(D14, D15, FXOS8700CQ_SLAVE_ADDR1); FXOS8700Q_mag combo_mag(D14, D15, FXOS8700CQ_SLAVE_ADDR1); FXAS21000 gyro(D14, D15); DigitalOut led1(LED1); InterruptIn sw2(SW2); Timer GlobalTime; Timer ProgramTimer; //Threadas uint32_t button_pressed; Thread *thread2; Thread *thread3; Thread *thread4; //EMG samples and DSP variables float32_t EMG1, EMG2, EMG3; float32_t samples[25]; float32_t samples2[25]; float32_t samples3[25]; float32_t abs_output[25]; float32_t abs_output2[25]; float32_t abs_output3[25]; float32_t mean = 0.0f; float32_t mean2 = 0.0f; float32_t mean3 = 0.0f; //IMU float gyro_data[3]; MotionSensorDataUnits adata; MotionSensorDataUnits mdata; float R; float angle[3]; float roll; float pitch; kalman filter_pitch; kalman filter_roll; //OS osMutexId el_mutex; osMutexDef(el_mutex); //time unsigned long timer; long loopStartTime; void sw2_press(void); void button_thread(void const *argument); void imu_thread(void const *argument); void sampler_thread(void const *argument); void logger_thread(void const *argument); void Serial_Oscilloscope(uint8_t activation, uint8_t type); int main(void) { pc.baud(115200); //Serial com at 115200 bauds Thread thread(imu_thread); thread2 = new Thread(button_thread); thread3 = new Thread(sampler_thread); thread4 = new Thread(logger_thread); el_mutex = osMutexCreate(osMutex(el_mutex)); GlobalTime.start(); combo_acc.enable(); combo_mag.enable(); pc.printf("FXOS8700 Combo = %X\r\n", combo_acc.whoAmI()); pc.printf("FXAS21000 Gyro = %X\r\n", gyro.getWhoAmI()); kalman_init(&filter_pitch, R_matrix, Q_Gyro_matrix, Q_Accel_matrix); kalman_init(&filter_roll, R_matrix, Q_Gyro_matrix, Q_Accel_matrix); button_pressed = 0; sw2.fall(&sw2_press); ProgramTimer.start(); loopStartTime = ProgramTimer.read_us(); timer = loopStartTime; while (true) { Thread::wait(5000); led1 = !led1; pc.printf("SW2 was pressed (last 5 seconds): %d \n\r", button_pressed); pc.printf("Roll Angle X: %.6f Pitch Angle Y: %.6f \r\n", Rad2Dree * angle[1], Rad2Dree * angle[0]); fflush(stdout); button_pressed = 0; } } void sw2_press(void){ thread2->signal_set(0x1); } void button_thread(void const *argument){ while (true) { Thread::signal_wait(0x1); button_pressed++; } } void imu_thread(void const *argument){ while (true) { combo_acc.getAxis(adata); //pc.printf("FXOS8700 Acc: X:%6.3f Y:%6.3f Z:%6.3f\r\n", adata.x, adata.y, adata.z); combo_mag.getAxis(mdata); //pc.printf("FXOS8700 Mag: X:%6.2f Y:%6.2f Z:%6.2f\r\n", mdata.x, mdata.y, mdata.z); gyro.ReadXYZ(gyro_data); //pc.printf("FXAS21000 Gyro: X:%6.2f Y:%6.2f Z:%6.2f\r\n", gyro_data[0], gyro_data[1], gyro_data[2]); R = sqrt(std::pow(adata.x, 2) + std::pow(adata.y, 2) + std::pow(adata.z, 2)); kalman_predict(&filter_pitch, gyro_data[0], (ProgramTimer.read_us() - timer)); kalman_update(&filter_pitch, acos(adata.x/R)); kalman_predict(&filter_roll, gyro_data[1], (ProgramTimer.read_us() - timer)); kalman_update(&filter_roll, acos(adata.y/R)); angle[0] = kalman_get_angle(&filter_pitch); angle[1] = kalman_get_angle(&filter_roll); Thread::wait(10); } } void sampler_thread(void const *argument){ while (true) { EMG1 = (E1.read()-Ref.read())*3.3f; EMG2 = (E2.read()-Ref.read())*3.3f; EMG3 = (E3.read()-Ref.read())*3.3f; //osMutexWait(el_mutex, osWaitForever); for(int j=24;j>0;j--) { samples[j]=samples[j-1]; //Fill Array samples2[j]=samples2[j-1]; //Fill Array samples3[j]=samples3[j-1]; //Fill Array } samples[0]=EMG1; samples2[0]=EMG2; samples3[0]=EMG3; //osMutexRelease(el_mutex); Thread::wait(1); } } void logger_thread(void const *argument){ while (true) { Thread::wait(50); } } void Serial_Oscilloscope(uint8_t activation, uint8_t type){ if (activation){ switch(type){ case RAW: pc.printf("%.10f,%.10f,%.10f\n\r",EMG1,EMG2,EMG3); break; case RECTIFIED: pc.printf("%.10f,%.10f,%.10f\n\r",abs_output[0],abs_output2[0],abs_output3[0]);break; case SMOOTH: pc.printf("%.10f,%.10f,%.10f\n\r",mean,mean2,mean3); break; default: pc.printf("%.10f,%.10f,%.10f\n\r",EMG1,EMG2,EMG3); } } }