Kristyn DiGiovanni / Mbed 2 deprecated 4180_FinalProject_DeploymentVersion

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 // Hardware devices
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 
00013 // Constants and Timers
00014 Timer t1;
00015 Timer t2;
00016 const int FIFTEEN_SEC_DEL = 15000;
00017 const int MIN_DEL = 3000;
00018 const int WINDOW_SIZE = 5;
00019 const float INCORRECT_PENALTY = 3.00;
00020 const float WEIGHT = 1.25; 
00021 
00022 
00023 // Pushbutton flags and inputs
00024 volatile float rxn_time = 0;
00025 volatile int pb1_asserted = 0;
00026 volatile int pb2_asserted = 0;
00027 volatile int pb1_chosen = 0;
00028 volatile int pb2_chosen = 0;
00029 
00030 // Reading windows, counters, and accuracy calculations
00031 volatile int total_count = 0;
00032 volatile int incorrect_count = 0;
00033 volatile int interval = 0;
00034 volatile bool timeout = false;
00035 volatile float baseline_avg = 0;
00036 volatile float current_avg = 0;
00037 volatile float readings[WINDOW_SIZE]; 
00038 volatile int step = 0;
00039 volatile bool calc_baseline = false;
00040 
00041 void clear_timers() {
00042     t1.stop();
00043     t1.reset();
00044     t2.stop();
00045     t2.reset();
00046 }
00047 
00048 // Main LED control thread
00049 void flash(void const *args) {
00050     float timeout_time = 0;
00051     while(1){
00052         
00053         if(t1.read()>0 || t2.read()>0){
00054             clear_timers();
00055             incorrect_count++;  
00056             timeout = true; 
00057             
00058             // Add in the timeout reading into the current average 
00059             if (baseline_avg != 0) {
00060                 // Convert to seconds 
00061                 readings[step] = timeout_time / 1000.0;
00062                 step++;
00063                 if (step == WINDOW_SIZE) { 
00064                     step = 0;
00065                 }
00066             }
00067         }
00068         
00069         int choose = rand()%2;
00070         if (choose == 0) {
00071             pb1_chosen = 1;
00072             myled = 1;
00073             t1.start();
00074             Thread::wait(2000);
00075             myled = 0;
00076         } else {
00077             pb2_chosen = 1;
00078             myled2 = 1;
00079             t2.start();
00080             Thread::wait(2000);
00081             myled2 = 0;
00082         }
00083         
00084         float weight = rand() / (float) RAND_MAX;
00085         timeout_time = (int) (FIFTEEN_SEC_DEL * weight);
00086         Thread::wait(MIN_DEL + timeout_time);
00087         
00088         total_count++;
00089         interval++;
00090     }
00091 }
00092 
00093 // Pushbutton interrupts to read in a reaction time reading
00094 void button_ready(void) {
00095     pb1_asserted = 1;
00096     rxn_time = t1.read();
00097     readings[step] = rxn_time;
00098     step++;
00099     if (step == WINDOW_SIZE) {
00100         calc_baseline = true;
00101         step = 0;
00102     }
00103     t1.stop();
00104     t1.reset();
00105 }
00106 
00107 void button_ready2(void) {
00108     pb2_asserted = 1;
00109     rxn_time = t2.read();
00110     readings[step] = rxn_time;
00111     step++;
00112     if (step == WINDOW_SIZE) {
00113         calc_baseline = true;
00114         step = 0;
00115     }
00116     t2.stop();
00117     t2.reset();
00118 }
00119 
00120 // Alarm and sound control thread
00121 void sound(void const* args) {
00122     bool playOnce = true;
00123     while(1) {
00124         if (baseline_avg != 0 && playOnce) {
00125             speaker.period(1.0/1000.0);
00126             speaker = 0.5;
00127             Thread::wait(500);
00128             speaker = 0;
00129             playOnce = false;    
00130         }   
00131         
00132         if (baseline_avg != 0 && current_avg >= WEIGHT * baseline_avg) {
00133             speaker.period(1.0/100.0);
00134             speaker = 0.5;
00135             Thread::wait(250);
00136             speaker = 0;
00137             Thread::wait(250);
00138             speaker.period(1.0/200.0);
00139             speaker = 0.5;
00140             Thread::wait(250);
00141             speaker = 0;
00142             Thread::wait(250);
00143         }
00144         
00145         Thread::wait(100);
00146     }
00147 }
00148     
00149 int main() {
00150 
00151     // Messages to alert the user that the system is starting
00152     pc.printf("System starting in ...");
00153     for(int i = 1; i <= 5; i++) {  
00154         pc.printf("%d...", i);
00155         wait(1);
00156     }
00157     pc.printf("Go!\n\r");
00158 
00159     // Pushbutton setup
00160     pb.attach_deasserted(&button_ready);
00161     pb.setSampleFrequency();
00162     pb2.attach_deasserted(&button_ready2);
00163     pb2.setSampleFrequency();
00164 
00165     // Start led and sound control threads
00166     Thread thread1(flash);
00167     Thread thread2(sound);
00168 
00169     float accuracy;
00170     pc.printf("Starting Training Phase\n\r");
00171 
00172     // Continuously monitor the user's reaction 10x a second
00173     while(1) {
00174         if (calc_baseline && baseline_avg == 0) {
00175             float sum = 0;
00176             for (int j = 0; j < WINDOW_SIZE; j++)
00177                 sum += readings[j];
00178                 
00179             baseline_avg = sum / WINDOW_SIZE;
00180             pc.printf("Training Complete -- Baseline Average Established\n\r");
00181         } else {
00182             float sum = 0;
00183             for (int j = 0; j < WINDOW_SIZE; j++) 
00184                 sum += readings[j];   
00185             current_avg = sum / WINDOW_SIZE;
00186         }
00187         
00188         if (pb1_chosen && pb1_asserted == 1 && rxn_time != 0) {
00189             pb1_asserted = 0;
00190             pc.printf("Reaction Time: %fs  Baseline Reaction Time: %fs Average Reaction Time: %fs \n\r", rxn_time, baseline_avg, current_avg);
00191             pb1_chosen = 0;
00192             clear_timers();
00193         } else if (pb2_chosen && pb2_asserted == 1 && rxn_time != 0) {
00194             pb2_asserted = 0;
00195              pc.printf("Reaction Time: %fs  Baseline Reaction Time: %fs Average Reaction Time: %fs \n\r", rxn_time, baseline_avg, current_avg);
00196             pb2_chosen = 0;
00197             clear_timers();
00198         } else if(pb1_asserted || pb2_asserted) {
00199             pc.printf("Wrong Button Press\n\r");
00200             pb1_asserted = 0;
00201             pb2_asserted = 0;
00202             
00203             // Penalize for the wrong button press into the current average
00204             if (baseline_avg != 0) {
00205                 readings[step] = INCORRECT_PENALTY;
00206                 step++;
00207                 if (step == WINDOW_SIZE) { 
00208                     step = 0;
00209                 }
00210             }
00211             
00212             clear_timers();
00213             incorrect_count++;
00214         } else if (timeout) {
00215             pc.printf("Button timeout\n\r");
00216             timeout = false;
00217         } 
00218         
00219         
00220         if((interval%5==0)&&(interval!=0)){
00221                accuracy = ((float) total_count - incorrect_count)/total_count;
00222                accuracy = accuracy*100;
00223                pc.printf("--- TotalCount: %d IncorrectCount: %d Current Accuracy: %.2f%% ---\n\r", total_count, incorrect_count, accuracy);
00224                pc.printf("\n\r");
00225                interval = 0;
00226         }  
00227                 
00228         Thread::wait(100);
00229     }
00230 }