Skelton of EMG input method program using timer interrupt and thread.
Dependencies: QEI mbed-rtos mbed
Fork of DCmotor by
main.cpp@11:61883be906e2, 2012-11-30 (annotated)
- Committer:
- kosaka
- Date:
- Fri Nov 30 11:06:48 2012 +0000
- Revision:
- 11:61883be906e2
- Parent:
- 10:6be424b58abe
debug
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kosaka | 8:0540582a220e | 1 | // Skelton of EMG input method program using timer interrupt and thread. |
kosaka | 11:61883be906e2 | 2 | // ver. 121130a by Kosaka lab. |
kosaka | 0:fe068497f773 | 3 | #include "mbed.h" |
kosaka | 0:fe068497f773 | 4 | #include "rtos.h" |
kosaka | 0:fe068497f773 | 5 | #define PI 3.14159265358979 // def. of PI |
kosaka | 0:fe068497f773 | 6 | /*********** User setting for control parameters (begin) ***************/ |
kosaka | 8:0540582a220e | 7 | AnalogIn emg(p20); // *3.3 [V], Volt of emg from detection cirquit |
kosaka | 8:0540582a220e | 8 | #define N_COUNT 5000 // keep N_COUNT data to identify japanese chracter. |
kosaka | 8:0540582a220e | 9 | #define TS 0.0001 // [s], TS, sampling time[s] to detect emg from AD. |
kosaka | 8:0540582a220e | 10 | #define TMAX 5 // [s], experiment starts from 0[s] to TMAX[s] |
kosaka | 0:fe068497f773 | 11 | /*********** User setting for control parameters (end) ***************/ |
kosaka | 11:61883be906e2 | 12 | |
kosaka | 0:fe068497f773 | 13 | Serial pc(USBTX, USBRX); // Display on tera term in PC |
kosaka | 0:fe068497f773 | 14 | LocalFileSystem local("local"); // save data to mbed USB disk drive in PC |
kosaka | 0:fe068497f773 | 15 | //Semaphore semaphore1(1); // wait and release to protect memories and so on |
kosaka | 0:fe068497f773 | 16 | //Mutex stdio_mutex; // wait and release to protect memories and so on |
kosaka | 8:0540582a220e | 17 | Ticker timer_interrupt; // Timer interrupt using TIMER3, TS<0.001 is OK. Priority is higher than rtosTimer. |
kosaka | 11:61883be906e2 | 18 | |
kosaka | 8:0540582a220e | 19 | //extern "C" void mbed_reset(); // if called, mbed is resset. |
kosaka | 11:61883be906e2 | 20 | |
kosaka | 8:0540582a220e | 21 | float _emg_data[N_COUNT];// emg raw data |
kosaka | 8:0540582a220e | 22 | unsigned long _count=0; // sampling number for emg detection. |
kosaka | 8:0540582a220e | 23 | unsigned long _count2=0; // = _count/N_COUNT |
kosaka | 11:61883be906e2 | 24 | |
kosaka | 8:0540582a220e | 25 | DigitalOut led1(LED1); // for debug |
kosaka | 8:0540582a220e | 26 | DigitalOut led2(LED2); // for debug |
kosaka | 11:61883be906e2 | 27 | DigitalOut led3(LED3); // for debug |
kosaka | 11:61883be906e2 | 28 | |
kosaka | 8:0540582a220e | 29 | float _char=0; //-------- make japanese character from emg |
kosaka | 8:0540582a220e | 30 | FILE *fp; // save data to PC |
kosaka | 8:0540582a220e | 31 | unsigned char _f_req_slow=0; // flag requesting slow() |
kosaka | 8:0540582a220e | 32 | unsigned char _f_req_slowest=0; // flag requesting slowest() |
kosaka | 11:61883be906e2 | 33 | |
kosaka | 11:61883be906e2 | 34 | |
kosaka | 8:0540582a220e | 35 | void disp2PC(){ //-------- display japanese character to tera term on PC |
kosaka | 8:0540582a220e | 36 | pc.printf(" d %f\r\n",_char); |
kosaka | 0:fe068497f773 | 37 | } |
kosaka | 11:61883be906e2 | 38 | |
kosaka | 8:0540582a220e | 39 | void discriminateEMG(){ //-------- discriminate EMG to make japanese character |
kosaka | 8:0540582a220e | 40 | int i; |
kosaka | 8:0540582a220e | 41 | float x; |
kosaka | 11:61883be906e2 | 42 | |
kosaka | 8:0540582a220e | 43 | x = 0; |
kosaka | 8:0540582a220e | 44 | for( i=0;i<N_COUNT;i++){ |
kosaka | 8:0540582a220e | 45 | x = x + _emg_data[i]; |
kosaka | 0:fe068497f773 | 46 | } |
kosaka | 8:0540582a220e | 47 | _char = x; // _char = emg_data[0] + emg_data[1] + emg_data[2] + ... |
kosaka | 8:0540582a220e | 48 | pc.printf(" s\r\n"); |
kosaka | 0:fe068497f773 | 49 | } |
kosaka | 11:61883be906e2 | 50 | |
kosaka | 11:61883be906e2 | 51 | |
kosaka | 8:0540582a220e | 52 | //---------------- from here, timer interrupt and threads --------------- |
kosaka | 11:61883be906e2 | 53 | |
kosaka | 8:0540582a220e | 54 | void slowest(void const *argument) { // thread priority: Low |
kosaka | 8:0540582a220e | 55 | while(true){ |
kosaka | 8:0540582a220e | 56 | if( _f_req_slowest == 1 ){ // if slowest() is requested. |
kosaka | 11:61883be906e2 | 57 | led3 = 1; // check calculate time |
kosaka | 8:0540582a220e | 58 | // function(); |
kosaka | 8:0540582a220e | 59 | _f_req_slowest = 0; // release to request slowest() |
kosaka | 11:61883be906e2 | 60 | Thread::wait(100); |
kosaka | 11:61883be906e2 | 61 | led3 = 0; // check calculate time |
kosaka | 8:0540582a220e | 62 | } |
kosaka | 0:fe068497f773 | 63 | } |
kosaka | 0:fe068497f773 | 64 | } |
kosaka | 11:61883be906e2 | 65 | |
kosaka | 8:0540582a220e | 66 | void slow(void const *argument) { // thread priority: below normal |
kosaka | 0:fe068497f773 | 67 | while(true){ |
kosaka | 8:0540582a220e | 68 | if( _f_req_slow == 1 ){ // if slow() is requested. |
kosaka | 8:0540582a220e | 69 | led2 = 1; // check calculate time |
kosaka | 8:0540582a220e | 70 | discriminateEMG(); //-------- discriminate EMG to make japanese character |
kosaka | 8:0540582a220e | 71 | disp2PC(); //-------- display japanese character to tera term on PC |
kosaka | 8:0540582a220e | 72 | _f_req_slow = 0; // release to request slow() |
kosaka | 8:0540582a220e | 73 | _f_req_slowest = 1; // request slowest() |
kosaka | 8:0540582a220e | 74 | led2 = 0; // check calculate time |
kosaka | 7:613febb8f028 | 75 | } |
kosaka | 11:61883be906e2 | 76 | Thread::wait(1); // wait 1ms to give time with slowest() |
kosaka | 8:0540582a220e | 77 | } |
kosaka | 8:0540582a220e | 78 | } |
kosaka | 11:61883be906e2 | 79 | |
kosaka | 8:0540582a220e | 80 | void fastest() { // ticker using TIMER3 interrupt |
kosaka | 8:0540582a220e | 81 | led1 = 1; // check calculate time |
kosaka | 8:0540582a220e | 82 | // if( led1==0 ){ led1=1;}else{ led1=0;}// for debug |
kosaka | 8:0540582a220e | 83 | _emg_data[_count] = emg; |
kosaka | 8:0540582a220e | 84 | _count = _count + 1; |
kosaka | 8:0540582a220e | 85 | if( _count==N_COUNT ){ |
kosaka | 8:0540582a220e | 86 | _count = 0; |
kosaka | 8:0540582a220e | 87 | _count2 += 1; |
kosaka | 8:0540582a220e | 88 | _f_req_slow = 1; // request slow() |
kosaka | 8:0540582a220e | 89 | } |
kosaka | 8:0540582a220e | 90 | led1 = 0; // check calculate time |
kosaka | 0:fe068497f773 | 91 | } |
kosaka | 11:61883be906e2 | 92 | |
kosaka | 0:fe068497f773 | 93 | int main() { |
kosaka | 8:0540582a220e | 94 | Thread threadSlow(slow,NULL,osPriorityBelowNormal); // call thread slow() |
kosaka | 8:0540582a220e | 95 | Thread threadSlowest(slowest,NULL,osPriorityLow); // call thread slowest() |
kosaka | 11:61883be906e2 | 96 | |
kosaka | 8:0540582a220e | 97 | pc.printf("Start!!\r\n"); |
kosaka | 8:0540582a220e | 98 | // if ( NULL == (fp = fopen( "/local/data.csv", "w" )) ){ error( "" );} // open mbed USB drive |
kosaka | 8:0540582a220e | 99 | timer_interrupt.attach(&fastest, TS ); // start timer interrupt: call fastest() on each TS[s]. |
kosaka | 8:0540582a220e | 100 | while( _count2 < TMAX/TS/N_COUNT ){ |
kosaka | 8:0540582a220e | 101 | Thread::wait(1000); // [ms], wait |
kosaka | 8:0540582a220e | 102 | } |
kosaka | 8:0540582a220e | 103 | timer_interrupt.detach(); // stop timer interrupt fastest |
kosaka | 8:0540582a220e | 104 | // fclose( fp ); // release mbed USB drive |
kosaka | 8:0540582a220e | 105 | pc.printf("Completed!!\r\n\r\n"); |
kosaka | 8:0540582a220e | 106 | } |
kosaka | 0:fe068497f773 | 107 | // osStatus set_priority(osPriority osPriorityBelowNormal ); |
kosaka | 0:fe068497f773 | 108 | // Priority of Thread (RtosTimer has no priority?) |
kosaka | 0:fe068497f773 | 109 | // osPriorityIdle = -3, ///< priority: idle (lowest)--> then, mbed ERROR!! |
kosaka | 0:fe068497f773 | 110 | // osPriorityLow = -2, ///< priority: low |
kosaka | 0:fe068497f773 | 111 | // osPriorityBelowNormal = -1, ///< priority: below normal |
kosaka | 0:fe068497f773 | 112 | // osPriorityNormal = 0, ///< priority: normal (default) |
kosaka | 0:fe068497f773 | 113 | // osPriorityAboveNormal = +1, ///< priority: above normal |
kosaka | 0:fe068497f773 | 114 | // osPriorityHigh = +2, ///< priority: high |
kosaka | 0:fe068497f773 | 115 | // osPriorityRealtime = +3, ///< priority: realtime (highest) |
kosaka | 0:fe068497f773 | 116 | // osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority |
kosaka | 11:61883be906e2 | 117 | |
kosaka | 11:61883be906e2 | 118 |