Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed mbed-rtos PinDetect
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 }
Generated on Sun Jul 24 2022 16:16:49 by
1.7.2