Skelton of EMG input method program using timer interrupt and thread.
Dependencies: QEI mbed-rtos mbed
Fork of DCmotor by
main.cpp@10:6be424b58abe, 2012-11-24 (annotated)
- Committer:
- kosaka
- Date:
- Sat Nov 24 01:23:03 2012 +0000
- Revision:
- 10:6be424b58abe
- Parent:
- 8:0540582a220e
- Child:
- 11:61883be906e2
.
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 | 10:6be424b58abe | 2 | // ver. 121123a 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 | 0:fe068497f773 | 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 | 0:fe068497f773 | 18 | |
kosaka | 8:0540582a220e | 19 | //extern "C" void mbed_reset(); // if called, mbed is resset. |
kosaka | 4:6ccbf4d3cb6d | 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 | 0:fe068497f773 | 24 | |
kosaka | 8:0540582a220e | 25 | DigitalOut led1(LED1); // for debug |
kosaka | 8:0540582a220e | 26 | DigitalOut led2(LED2); // for debug |
kosaka | 3:b6b9b8c7dce6 | 27 | |
kosaka | 8:0540582a220e | 28 | float _char=0; //-------- make japanese character from emg |
kosaka | 8:0540582a220e | 29 | FILE *fp; // save data to PC |
kosaka | 8:0540582a220e | 30 | unsigned char _f_req_slow=0; // flag requesting slow() |
kosaka | 8:0540582a220e | 31 | unsigned char _f_req_slowest=0; // flag requesting slowest() |
kosaka | 8:0540582a220e | 32 | |
kosaka | 8:0540582a220e | 33 | |
kosaka | 8:0540582a220e | 34 | void disp2PC(){ //-------- display japanese character to tera term on PC |
kosaka | 8:0540582a220e | 35 | pc.printf(" d %f\r\n",_char); |
kosaka | 0:fe068497f773 | 36 | } |
kosaka | 0:fe068497f773 | 37 | |
kosaka | 8:0540582a220e | 38 | void discriminateEMG(){ //-------- discriminate EMG to make japanese character |
kosaka | 8:0540582a220e | 39 | int i; |
kosaka | 8:0540582a220e | 40 | float x; |
kosaka | 0:fe068497f773 | 41 | |
kosaka | 8:0540582a220e | 42 | x = 0; |
kosaka | 8:0540582a220e | 43 | for( i=0;i<N_COUNT;i++){ |
kosaka | 8:0540582a220e | 44 | x = x + _emg_data[i]; |
kosaka | 0:fe068497f773 | 45 | } |
kosaka | 8:0540582a220e | 46 | _char = x; // _char = emg_data[0] + emg_data[1] + emg_data[2] + ... |
kosaka | 8:0540582a220e | 47 | pc.printf(" s\r\n"); |
kosaka | 0:fe068497f773 | 48 | } |
kosaka | 0:fe068497f773 | 49 | |
kosaka | 0:fe068497f773 | 50 | |
kosaka | 8:0540582a220e | 51 | //---------------- from here, timer interrupt and threads --------------- |
kosaka | 0:fe068497f773 | 52 | |
kosaka | 8:0540582a220e | 53 | void slowest(void const *argument) { // thread priority: Low |
kosaka | 8:0540582a220e | 54 | while(true){ |
kosaka | 8:0540582a220e | 55 | if( _f_req_slowest == 1 ){ // if slowest() is requested. |
kosaka | 8:0540582a220e | 56 | // function(); |
kosaka | 8:0540582a220e | 57 | _f_req_slowest = 0; // release to request slowest() |
kosaka | 8:0540582a220e | 58 | } |
kosaka | 0:fe068497f773 | 59 | } |
kosaka | 0:fe068497f773 | 60 | } |
kosaka | 0:fe068497f773 | 61 | |
kosaka | 8:0540582a220e | 62 | void slow(void const *argument) { // thread priority: below normal |
kosaka | 0:fe068497f773 | 63 | while(true){ |
kosaka | 8:0540582a220e | 64 | if( _f_req_slow == 1 ){ // if slow() is requested. |
kosaka | 8:0540582a220e | 65 | led2 = 1; // check calculate time |
kosaka | 8:0540582a220e | 66 | discriminateEMG(); //-------- discriminate EMG to make japanese character |
kosaka | 8:0540582a220e | 67 | disp2PC(); //-------- display japanese character to tera term on PC |
kosaka | 8:0540582a220e | 68 | _f_req_slow = 0; // release to request slow() |
kosaka | 8:0540582a220e | 69 | _f_req_slowest = 1; // request slowest() |
kosaka | 8:0540582a220e | 70 | led2 = 0; // check calculate time |
kosaka | 7:613febb8f028 | 71 | } |
kosaka | 8:0540582a220e | 72 | } |
kosaka | 8:0540582a220e | 73 | } |
kosaka | 0:fe068497f773 | 74 | |
kosaka | 8:0540582a220e | 75 | void fastest() { // ticker using TIMER3 interrupt |
kosaka | 8:0540582a220e | 76 | led1 = 1; // check calculate time |
kosaka | 8:0540582a220e | 77 | // if( led1==0 ){ led1=1;}else{ led1=0;}// for debug |
kosaka | 8:0540582a220e | 78 | _emg_data[_count] = emg; |
kosaka | 8:0540582a220e | 79 | _count = _count + 1; |
kosaka | 8:0540582a220e | 80 | if( _count==N_COUNT ){ |
kosaka | 8:0540582a220e | 81 | _count = 0; |
kosaka | 8:0540582a220e | 82 | _count2 += 1; |
kosaka | 8:0540582a220e | 83 | _f_req_slow = 1; // request slow() |
kosaka | 8:0540582a220e | 84 | } |
kosaka | 8:0540582a220e | 85 | led1 = 0; // check calculate time |
kosaka | 0:fe068497f773 | 86 | } |
kosaka | 8:0540582a220e | 87 | |
kosaka | 0:fe068497f773 | 88 | int main() { |
kosaka | 8:0540582a220e | 89 | Thread threadSlow(slow,NULL,osPriorityBelowNormal); // call thread slow() |
kosaka | 8:0540582a220e | 90 | Thread threadSlowest(slowest,NULL,osPriorityLow); // call thread slowest() |
kosaka | 0:fe068497f773 | 91 | |
kosaka | 8:0540582a220e | 92 | pc.printf("Start!!\r\n"); |
kosaka | 8:0540582a220e | 93 | // if ( NULL == (fp = fopen( "/local/data.csv", "w" )) ){ error( "" );} // open mbed USB drive |
kosaka | 8:0540582a220e | 94 | timer_interrupt.attach(&fastest, TS ); // start timer interrupt: call fastest() on each TS[s]. |
kosaka | 8:0540582a220e | 95 | while( _count2 < TMAX/TS/N_COUNT ){ |
kosaka | 8:0540582a220e | 96 | Thread::wait(1000); // [ms], wait |
kosaka | 8:0540582a220e | 97 | } |
kosaka | 8:0540582a220e | 98 | timer_interrupt.detach(); // stop timer interrupt fastest |
kosaka | 8:0540582a220e | 99 | // fclose( fp ); // release mbed USB drive |
kosaka | 8:0540582a220e | 100 | pc.printf("Completed!!\r\n\r\n"); |
kosaka | 8:0540582a220e | 101 | } |
kosaka | 0:fe068497f773 | 102 | // osStatus set_priority(osPriority osPriorityBelowNormal ); |
kosaka | 0:fe068497f773 | 103 | // Priority of Thread (RtosTimer has no priority?) |
kosaka | 0:fe068497f773 | 104 | // osPriorityIdle = -3, ///< priority: idle (lowest)--> then, mbed ERROR!! |
kosaka | 0:fe068497f773 | 105 | // osPriorityLow = -2, ///< priority: low |
kosaka | 0:fe068497f773 | 106 | // osPriorityBelowNormal = -1, ///< priority: below normal |
kosaka | 0:fe068497f773 | 107 | // osPriorityNormal = 0, ///< priority: normal (default) |
kosaka | 0:fe068497f773 | 108 | // osPriorityAboveNormal = +1, ///< priority: above normal |
kosaka | 0:fe068497f773 | 109 | // osPriorityHigh = +2, ///< priority: high |
kosaka | 0:fe068497f773 | 110 | // osPriorityRealtime = +3, ///< priority: realtime (highest) |
kosaka | 0:fe068497f773 | 111 | // osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority |