Demo Code version of the Project Test Drive.

Dependencies:   mbed mbed-rtos PinDetect

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "rtos.h"
00003 #include "PinDetect.h"
00004 
00005 
00006 RawSerial pc(USBTX, USBRX);
00007 DigitalOut myled(p21);
00008 DigitalOut myled2(p22);
00009 PinDetect pb(p26, PullDown);
00010 PinDetect pb2(p27, PullDown);
00011 PwmOut speaker(p25);
00012 Timer t1;
00013 Timer t2;
00014 const int TEN_SEC_DEL = 5000;  // Change back to 10 seconds (changed for testing purposes)
00015 const int WINDOW_SIZE = 5;
00016 const float INCORRECT_PENALTY = 3.00;
00017 const float WEIGHT = 1.25; 
00018 
00019 volatile float rxn_time = 0;
00020 volatile int pb1_asserted = 0;
00021 volatile int pb2_asserted = 0;
00022 volatile int pb1_chosen = 0;
00023 volatile int pb2_chosen = 0;
00024 volatile int total_count = 0;
00025 volatile int incorrect_count = 0;
00026 volatile int interval = 0;
00027 volatile bool timeout = false;
00028 volatile float baseline_avg = 0;
00029 volatile float current_avg = 0;
00030 volatile float readings[WINDOW_SIZE]; // Change back to 10 later
00031 volatile int step = 0;
00032 volatile bool calc_baseline = false;
00033 
00034 
00035 void clear_timers() {
00036     t1.stop();
00037     t1.reset();
00038     t2.stop();
00039     t2.reset();
00040 }
00041 
00042 void flash(void const *args) {
00043     float timeout_time = 0;
00044     while(1){
00045         
00046         if(t1.read()>0 || t2.read()>0){
00047             clear_timers();
00048             incorrect_count++;  
00049             timeout = true; 
00050             
00051             // Add in the timeout reading into the current average 
00052             if (baseline_avg != 0) {
00053                 // Convert to seconds 
00054                 readings[step] = timeout_time / 1000.0;
00055                 step++;
00056                 if (step == WINDOW_SIZE) { 
00057                     step = 0;
00058                 }
00059             }
00060         }
00061         
00062         int choose = rand()%2;
00063         if (choose == 0) {
00064             pb1_chosen = 1;
00065             myled = 1;
00066             t1.start();
00067             Thread::wait(1000);
00068             myled = 0;
00069         } else {
00070             pb2_chosen = 1;
00071             myled2 = 1;
00072             t2.start();
00073             Thread::wait(1000);
00074             myled2 = 0;
00075         }
00076         
00077         float weight = rand() / (float) RAND_MAX;
00078         timeout_time = (int) (TEN_SEC_DEL * weight);
00079         Thread::wait(timeout_time);
00080         
00081         total_count++;
00082         interval++;
00083     }
00084 }
00085 
00086 void button_ready(void) {
00087     pb1_asserted = 1;
00088     rxn_time = t1.read();
00089     readings[step] = rxn_time;
00090     step++;
00091     if (step == WINDOW_SIZE) {
00092         calc_baseline = true;
00093         step = 0;
00094     }
00095     t1.stop();
00096     t1.reset();
00097 }
00098 
00099 void button_ready2(void) {
00100     pb2_asserted = 1;
00101     rxn_time = t2.read();
00102     readings[step] = rxn_time;
00103     step++;
00104     if (step == WINDOW_SIZE) {
00105         calc_baseline = true;
00106         step = 0;
00107     }
00108     t2.stop();
00109     t2.reset();
00110 }
00111 
00112 void sound(void const* args) {
00113     bool playOnce = true;
00114     while(1) {
00115         if (baseline_avg != 0 && playOnce) {
00116             speaker.period(1.0/1000.0);
00117             speaker = 0.5;
00118             Thread::wait(500);
00119             speaker = 0;
00120             playOnce = false;    
00121         }   
00122         
00123         if (baseline_avg != 0 && current_avg >= WEIGHT * baseline_avg) {
00124             speaker.period(1.0/100.0);
00125             speaker = 0.5;
00126             Thread::wait(250);
00127             speaker = 0;
00128             Thread::wait(250);
00129             speaker.period(1.0/200.0);
00130             speaker = 0.5;
00131             Thread::wait(250);
00132             speaker = 0;
00133             Thread::wait(250);
00134         }
00135         
00136         Thread::wait(100);
00137     }
00138 }
00139     
00140 int main() {
00141 
00142     pc.printf("System starting in ...");
00143     for(int i = 1; i <= 5; i++) {  
00144         pc.printf("%d...", i);
00145         wait(1);
00146     }
00147     pc.printf("Go!\n\r");
00148     pb.attach_deasserted(&button_ready);
00149     pb.setSampleFrequency();
00150     pb2.attach_deasserted(&button_ready2);
00151     pb2.setSampleFrequency();
00152 
00153     Thread thread1(flash);
00154     Thread thread2(sound);
00155 
00156     float accuracy;
00157     pc.printf("Starting Training Phase\n\r");
00158 
00159     while(1) {
00160         // Change back to 10 later
00161         if (calc_baseline && baseline_avg == 0) {
00162             float sum = 0;
00163             for (int j = 0; j < WINDOW_SIZE; j++)
00164                 sum += readings[j];
00165                 
00166             baseline_avg = sum / WINDOW_SIZE;
00167             pc.printf("Training Complete -- Baseline Average Established\n\r");
00168         } else {
00169             float sum = 0;
00170             for (int j = 0; j < WINDOW_SIZE; j++) 
00171                 sum += readings[j];   
00172             current_avg = sum / WINDOW_SIZE;
00173         }
00174         
00175         if (pb1_chosen && pb1_asserted == 1 && rxn_time != 0) {
00176             pb1_asserted = 0;
00177             pc.printf("Reaction Time: %fs  Baseline Reaction Time: %fs Average Reaction Time: %fs \n\r", rxn_time, baseline_avg, current_avg);
00178             pb1_chosen = 0;
00179             clear_timers();
00180         } else if (pb2_chosen && pb2_asserted == 1 && rxn_time != 0) {
00181             pb2_asserted = 0;
00182              pc.printf("Reaction Time: %fs  Baseline Reaction Time: %fs Average Reaction Time: %fs \n\r", rxn_time, baseline_avg, current_avg);
00183             pb2_chosen = 0;
00184             clear_timers();
00185         } else if(pb1_asserted || pb2_asserted) {
00186             pc.printf("Wrong Button Press\n\r");
00187             pb1_asserted = 0;
00188             pb2_asserted = 0;
00189             
00190             // Penalize for the wrong button press into the current average
00191             if (baseline_avg != 0) {
00192                 readings[step] = INCORRECT_PENALTY;
00193                 step++;
00194                 if (step == WINDOW_SIZE) { 
00195                     step = 0;
00196                 }
00197             }
00198             
00199             clear_timers();
00200             incorrect_count++;
00201         } else if (timeout) {
00202             pc.printf("Button timeout\n\r");
00203             timeout = false;
00204         } 
00205         
00206         
00207         if((interval%5==0)&&(interval!=0)){
00208                accuracy = ((float) total_count - incorrect_count)/total_count;
00209                accuracy = accuracy*100;
00210                pc.printf("--- TotalCount: %d IncorrectCount: %d Current Accuracy: %.2f%% ---\n\r", total_count, incorrect_count, accuracy);
00211                pc.printf("\n\r");
00212                //pc.printf("Current Accuracy: %.2f%%\n\r", accuracy);
00213                interval = 0;
00214         }  
00215                 
00216         Thread::wait(100);
00217     }
00218 }