Demo Code version of the Project Test Drive.
Dependencies: mbed mbed-rtos PinDetect
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 }
Generated on Sat Jul 16 2022 06:48:21 by
1.7.2