Skelton of EMG input method program using timer interrupt and thread.

Dependencies:   QEI mbed-rtos mbed

Fork of DCmotor by manabu kosaka

main.cpp

Committer:
kosaka
Date:
2012-11-30
Revision:
11:61883be906e2
Parent:
10:6be424b58abe

File content as of revision 11:61883be906e2:

//  Skelton of EMG input method program using timer interrupt and thread.
//      ver. 121130a by Kosaka lab.
#include "mbed.h"
#include "rtos.h"
#define PI 3.14159265358979 // def. of PI
/*********** User setting for control parameters (begin) ***************/
AnalogIn emg(p20);      // *3.3 [V], Volt of emg from detection cirquit
#define N_COUNT 5000    // keep N_COUNT data to identify japanese chracter.
#define TS      0.0001  // [s], TS, sampling time[s] to detect emg from AD.
#define TMAX    5       // [s], experiment starts from 0[s] to TMAX[s]
/*********** User setting for control parameters (end) ***************/
 
Serial pc(USBTX, USBRX);        // Display on tera term in PC 
LocalFileSystem local("local"); // save data to mbed USB disk drive in PC
//Semaphore semaphore1(1);      // wait and release to protect memories and so on
//Mutex stdio_mutex;            // wait and release to protect memories and so on
Ticker timer_interrupt;         // Timer interrupt using TIMER3, TS<0.001 is OK. Priority is higher than rtosTimer.
 
//extern "C" void mbed_reset();   // if called, mbed is resset.
 
float _emg_data[N_COUNT];// emg raw data
unsigned long _count=0;  // sampling number for emg detection.
unsigned long _count2=0; // = _count/N_COUNT
 
DigitalOut led1(LED1); // for debug
DigitalOut led2(LED2); // for debug
DigitalOut led3(LED3); // for debug
 
float   _char=0;        //-------- make japanese character from emg
FILE *fp;               // save data to PC
unsigned char   _f_req_slow=0;      // flag requesting slow()
unsigned char   _f_req_slowest=0;   // flag requesting slowest()
 
 
void disp2PC(){     //-------- display japanese character to tera term on PC
    pc.printf(" d %f\r\n",_char);
}
 
void discriminateEMG(){  //-------- discriminate EMG to make japanese character
    int     i;
    float   x;
 
    x = 0;
    for( i=0;i<N_COUNT;i++){
        x = x + _emg_data[i];
    }
    _char = x;  // _char = emg_data[0] + emg_data[1] + emg_data[2] + ...
    pc.printf(" s\r\n");
}
 
 
//---------------- from here, timer interrupt and threads ---------------
 
void slowest(void const *argument) {    // thread priority: Low
    while(true){
        if( _f_req_slowest == 1 ){    // if slowest() is requested.
            led3 = 1;   // check calculate time
//          function();
            _f_req_slowest = 0;     // release to request slowest()
            Thread::wait(100);
            led3 = 0;   // check calculate time
        }
    }
}
 
void slow(void const *argument) {    // thread priority: below normal
    while(true){
        if( _f_req_slow == 1 ){    // if slow() is requested.
            led2 = 1;   // check calculate time
            discriminateEMG();  //-------- discriminate EMG to make japanese character
            disp2PC();          //-------- display japanese character to tera term on PC
            _f_req_slow = 0;    // release to request slow()
            _f_req_slowest = 1; // request slowest()
            led2 = 0;   // check calculate time
        }
        Thread::wait(1);    // wait 1ms to give time with slowest()
    }
}
 
void fastest() {                    // ticker using TIMER3 interrupt
    led1 = 1;   // check calculate time
//    if( led1==0 ){  led1=1;}else{           led1=0;}// for debug
    _emg_data[_count] = emg;
    _count = _count + 1;
    if( _count==N_COUNT ){
        _count = 0;
        _count2 += 1;
        _f_req_slow = 1;    // request slow()
    }
    led1 = 0;   // check calculate time
}
 
int main() {
    Thread threadSlow(slow,NULL,osPriorityBelowNormal); // call thread slow()
    Thread threadSlowest(slowest,NULL,osPriorityLow);   // call thread slowest()
 
    pc.printf("Start!!\r\n");
//    if ( NULL == (fp = fopen( "/local/data.csv", "w" )) ){   error( "" );} // open mbed USB drive
    timer_interrupt.attach(&fastest, TS );  // start timer interrupt: call fastest() on each TS[s].
    while( _count2 < TMAX/TS/N_COUNT ){
        Thread::wait(1000);  // [ms], wait
    }
    timer_interrupt.detach();   // stop timer interrupt fastest
//    fclose( fp );               // release mbed USB drive
    pc.printf("Completed!!\r\n\r\n");
}
//    osStatus set_priority(osPriority osPriorityBelowNormal );
// Priority of Thread (RtosTimer has no priority?)
//  osPriorityIdle          = -3,          ///< priority: idle (lowest)--> then, mbed ERROR!!
//  osPriorityLow           = -2,          ///< priority: low
//  osPriorityBelowNormal   = -1,          ///< priority: below normal
//  osPriorityNormal        =  0,          ///< priority: normal (default)
//  osPriorityAboveNormal   = +1,          ///< priority: above normal
//  osPriorityHigh          = +2,          ///< priority: high 
//  osPriorityRealtime      = +3,          ///< priority: realtime (highest)
//  osPriorityError         =  0x84        ///< system cannot determine priority or thread has illegal priority