Demo Code version of the Project Test Drive.
Dependencies: mbed mbed-rtos PinDetect
Diff: main.cpp
- Revision:
- 0:c18a60fc6636
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Nov 28 03:53:53 2019 +0000 @@ -0,0 +1,218 @@ +#include "mbed.h" +#include "rtos.h" +#include "PinDetect.h" + + +RawSerial pc(USBTX, USBRX); +DigitalOut myled(p21); +DigitalOut myled2(p22); +PinDetect pb(p26, PullDown); +PinDetect pb2(p27, PullDown); +PwmOut speaker(p25); +Timer t1; +Timer t2; +const int TEN_SEC_DEL = 5000; // Change back to 10 seconds (changed for testing purposes) +const int WINDOW_SIZE = 5; +const float INCORRECT_PENALTY = 3.00; +const float WEIGHT = 1.25; + +volatile float rxn_time = 0; +volatile int pb1_asserted = 0; +volatile int pb2_asserted = 0; +volatile int pb1_chosen = 0; +volatile int pb2_chosen = 0; +volatile int total_count = 0; +volatile int incorrect_count = 0; +volatile int interval = 0; +volatile bool timeout = false; +volatile float baseline_avg = 0; +volatile float current_avg = 0; +volatile float readings[WINDOW_SIZE]; // Change back to 10 later +volatile int step = 0; +volatile bool calc_baseline = false; + + +void clear_timers() { + t1.stop(); + t1.reset(); + t2.stop(); + t2.reset(); +} + +void flash(void const *args) { + float timeout_time = 0; + while(1){ + + if(t1.read()>0 || t2.read()>0){ + clear_timers(); + incorrect_count++; + timeout = true; + + // Add in the timeout reading into the current average + if (baseline_avg != 0) { + // Convert to seconds + readings[step] = timeout_time / 1000.0; + step++; + if (step == WINDOW_SIZE) { + step = 0; + } + } + } + + int choose = rand()%2; + if (choose == 0) { + pb1_chosen = 1; + myled = 1; + t1.start(); + Thread::wait(1000); + myled = 0; + } else { + pb2_chosen = 1; + myled2 = 1; + t2.start(); + Thread::wait(1000); + myled2 = 0; + } + + float weight = rand() / (float) RAND_MAX; + timeout_time = (int) (TEN_SEC_DEL * weight); + Thread::wait(timeout_time); + + total_count++; + interval++; + } +} + +void button_ready(void) { + pb1_asserted = 1; + rxn_time = t1.read(); + readings[step] = rxn_time; + step++; + if (step == WINDOW_SIZE) { + calc_baseline = true; + step = 0; + } + t1.stop(); + t1.reset(); +} + +void button_ready2(void) { + pb2_asserted = 1; + rxn_time = t2.read(); + readings[step] = rxn_time; + step++; + if (step == WINDOW_SIZE) { + calc_baseline = true; + step = 0; + } + t2.stop(); + t2.reset(); +} + +void sound(void const* args) { + bool playOnce = true; + while(1) { + if (baseline_avg != 0 && playOnce) { + speaker.period(1.0/1000.0); + speaker = 0.5; + Thread::wait(500); + speaker = 0; + playOnce = false; + } + + if (baseline_avg != 0 && current_avg >= WEIGHT * baseline_avg) { + speaker.period(1.0/100.0); + speaker = 0.5; + Thread::wait(250); + speaker = 0; + Thread::wait(250); + speaker.period(1.0/200.0); + speaker = 0.5; + Thread::wait(250); + speaker = 0; + Thread::wait(250); + } + + Thread::wait(100); + } +} + +int main() { + + pc.printf("System starting in ..."); + for(int i = 1; i <= 5; i++) { + pc.printf("%d...", i); + wait(1); + } + pc.printf("Go!\n\r"); + pb.attach_deasserted(&button_ready); + pb.setSampleFrequency(); + pb2.attach_deasserted(&button_ready2); + pb2.setSampleFrequency(); + + Thread thread1(flash); + Thread thread2(sound); + + float accuracy; + pc.printf("Starting Training Phase\n\r"); + + while(1) { + // Change back to 10 later + if (calc_baseline && baseline_avg == 0) { + float sum = 0; + for (int j = 0; j < WINDOW_SIZE; j++) + sum += readings[j]; + + baseline_avg = sum / WINDOW_SIZE; + pc.printf("Training Complete -- Baseline Average Established\n\r"); + } else { + float sum = 0; + for (int j = 0; j < WINDOW_SIZE; j++) + sum += readings[j]; + current_avg = sum / WINDOW_SIZE; + } + + if (pb1_chosen && pb1_asserted == 1 && rxn_time != 0) { + pb1_asserted = 0; + pc.printf("Reaction Time: %fs Baseline Reaction Time: %fs Average Reaction Time: %fs \n\r", rxn_time, baseline_avg, current_avg); + pb1_chosen = 0; + clear_timers(); + } else if (pb2_chosen && pb2_asserted == 1 && rxn_time != 0) { + pb2_asserted = 0; + pc.printf("Reaction Time: %fs Baseline Reaction Time: %fs Average Reaction Time: %fs \n\r", rxn_time, baseline_avg, current_avg); + pb2_chosen = 0; + clear_timers(); + } else if(pb1_asserted || pb2_asserted) { + pc.printf("Wrong Button Press\n\r"); + pb1_asserted = 0; + pb2_asserted = 0; + + // Penalize for the wrong button press into the current average + if (baseline_avg != 0) { + readings[step] = INCORRECT_PENALTY; + step++; + if (step == WINDOW_SIZE) { + step = 0; + } + } + + clear_timers(); + incorrect_count++; + } else if (timeout) { + pc.printf("Button timeout\n\r"); + timeout = false; + } + + + if((interval%5==0)&&(interval!=0)){ + accuracy = ((float) total_count - incorrect_count)/total_count; + accuracy = accuracy*100; + pc.printf("--- TotalCount: %d IncorrectCount: %d Current Accuracy: %.2f%% ---\n\r", total_count, incorrect_count, accuracy); + pc.printf("\n\r"); + //pc.printf("Current Accuracy: %.2f%%\n\r", accuracy); + interval = 0; + } + + Thread::wait(100); + } +} \ No newline at end of file