The task for the seventh week is to connect an output device and measure its power consuption.
I chose to create a reaction time tester using these components
You can see the wiring and code down bellow. Just a quick heads up, I used pull-up resistors for the button pins to define their voltage to HIGH when not pressed.
I used breadboard for connecting all components.
#include <Arduino.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define SCREEN_ADDRESS 0x3C // OLED display address
// Initialize display object
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT);
// LED pin definitions
#define LED_R 2 // Red LED
#define LED_G 3 // Green LED
#define LED_Y 4 // Yellow LED
#define LED_B 5 // Blue LED
// Button pin definitions
#define BUTTON_G 7 // Green button
#define BUTTON_Y 8 // Yellow button
#define BUTTON_B 9 // Blue button
#define BUTTON_W 11 // White button
// LED offset definitions
#define LED_TO_ZERO 3
#define LED_TO_BUTTON 4
// Store the best 5 average times and corresponding run IDs
#define LEADERBOARD_SIZE 5
#define ULONG_MAX 4294967295
unsigned long leaderboard_times[LEADERBOARD_SIZE] = {ULONG_MAX, ULONG_MAX, ULONG_MAX, ULONG_MAX, ULONG_MAX};
int leaderboard_ids[LEADERBOARD_SIZE] = {0, 0, 0, 0, 0};
int current_run_id = 1; // Run ID for the current test
// Function headers
void showMessage(String line1, String line2, String largeText1, String largeText2);
void showResults(String blue_time, String yellow_time, String green_time, String average_time, String id);
void showLeaderboard();
void updateLeaderboard(unsigned long averageTime);
void order(int random_case, int led_order[3]);
void setup() {
// Initialize serial communication
Serial.begin(9600);
randomSeed(analogRead(0)); // Seed random number generator using analog pin 0
// Set LED pins as outputs
pinMode(LED_R, OUTPUT);
pinMode(LED_G, OUTPUT);
pinMode(LED_Y, OUTPUT);
pinMode(LED_B, OUTPUT);
// Set button pins as inputs with pull-up resistors
pinMode(BUTTON_W, INPUT_PULLUP);
pinMode(BUTTON_G, INPUT_PULLUP);
pinMode(BUTTON_Y, INPUT_PULLUP);
pinMode(BUTTON_B, INPUT_PULLUP);
// Turn off all LEDs initially
digitalWrite(LED_R, LOW);
digitalWrite(LED_G, LOW);
digitalWrite(LED_Y, LOW);
digitalWrite(LED_B, LOW);
// Initialize the display
display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
showMessage("Welcome to", "", "REACTION", "TESTER");
delay(5000); // Display welcome message for 5 seconds
}
void loop() {
showMessage("Start by", "pressing", "WHITE", "BUTTON");
// Turn on the red LED
digitalWrite(LED_R, HIGH);
// Wait for the white button to be pressed
while (digitalRead(BUTTON_W) == HIGH) {
// Do nothing, just wait for the button press
}
// Show "Get Ready" message
showMessage("Now", "", "GET", "READY");
// Blink the red LED three times
for (int i = 0; i < 3; i++) {
digitalWrite(LED_R, LOW);
delay(500);
digitalWrite(LED_R, HIGH);
delay(500);
}
// Turn off the red LED
digitalWrite(LED_R, LOW);
delay(500); // Small delay before measuring reaction time
// Show "Measuring Reaction Time" message
showMessage("Measuring", "", "REACTION", "TIME");
// LED order array and random number initialization
int led_order[3];
int randomNumber = random(1, 7); // Generate a random number between 1 and 6
order(randomNumber, led_order); // Set the LED order based on the random number
// Variables for measuring reaction times
unsigned long startTime;
unsigned long reactionTime;
unsigned long averageTime;
unsigned long reaction_times[3]; // Array to store reaction times for each LED
// Measure reaction times for each LED
for (int i = 0; i < 3; i++) {
// Generate random delay before lighting up the LED
int randomTime = random(200, 5000); // 0.2 to 5 s
delay(randomTime);
// Turn on the LED
digitalWrite(led_order[i], HIGH);
startTime = millis(); // Record the start time
// Wait until the corresponding button is pressed
while (digitalRead(led_order[i] + LED_TO_BUTTON) == HIGH) {
// Do nothing, just wait for the button press
}
// Calculate reaction time
reactionTime = millis() - startTime;
digitalWrite(led_order[i], LOW); // Turn off the LED
reaction_times[led_order[i] - LED_TO_ZERO] = reactionTime; // Store the reaction time
}
// Calculate the average reaction time
averageTime = (reaction_times[0] + reaction_times[1] + reaction_times[2]) / 3;
// Display the results
showResults(String(reaction_times[2]), String(reaction_times[1]), String(reaction_times[0]), String(averageTime), String(current_run_id)); //, String(current_run_id));
delay(5000); // Wait for 5 seconds
// Update the leaderboard if the new average time is better than the worst time
updateLeaderboard(averageTime);
// Show the leaderboard
showLeaderboard();
delay(10000); // Wait for 10 seconds before starting again
}
void updateLeaderboard(unsigned long averageTime) {
// Check if the new average time is better than any of the current leaderboard times
for (int i = 0; i < LEADERBOARD_SIZE; i++) {
if (averageTime < leaderboard_times[i]) {
// Shift the other leaderboard times down
for (int j = LEADERBOARD_SIZE - 1; j > i; j--) {
leaderboard_times[j] = leaderboard_times[j - 1];
leaderboard_ids[j] = leaderboard_ids[j - 1];
}
// Insert the new time in the correct position
leaderboard_times[i] = averageTime;
leaderboard_ids[i] = current_run_id;
break;
}
}
current_run_id++; // Increment the run ID for the next test
}
void showResults(String blue_time, String yellow_time, String green_time, String average_time, String id) {
display.clearDisplay();
display.setTextSize(1); // Normal size text
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
// Print first lines
display.println("Results:");
display.println("Blue: " + blue_time + " ms");
display.println("Yellow: " + yellow_time + " ms");
display.println("Green: " + green_time + " ms");
// Print larger text
display.setTextSize(2);
display.println("ID: " + id);
display.println("~" + average_time + " ms");
display.display(); // Update the screen
}
void showLeaderboard() {
display.clearDisplay();
display.setTextSize(1); // Normal text size
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println(F("Leaderboard:"));
display.println(F(""));
display.setTextSize(1); // Normal text size
for (int i = 0; i < LEADERBOARD_SIZE; i++) {
if (leaderboard_times[i] != ULONG_MAX) { // Only display non-max times
display.print("ID: ");
display.print(leaderboard_ids[i]);
display.print(" Time: ");
display.println(leaderboard_times[i]);
}
}
display.display(); // Update the screen
}
void showMessage(String line1, String line2, String largeText1, String largeText2) {
display.clearDisplay();
display.setTextSize(1); // Normal text size
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
// Print first lines
display.println(F("")); // Empty line for spacing
display.println(line1);
display.println(line2);
display.println(F("")); // Empty line for spacing
// Print larger text
display.setTextSize(2);
display.println(largeText1);
display.println(largeText2);
display.display(); // Update the screen
}
void order(int random_case, int led_order[3]) {
switch (random_case) {
case 1:
led_order[0] = LED_B;
led_order[1] = LED_Y;
led_order[2] = LED_G;
break;
case 2:
led_order[0] = LED_B;
led_order[1] = LED_G;
led_order[2] = LED_Y;
break;
case 3:
led_order[0] = LED_Y;
led_order[1] = LED_B;
led_order[2] = LED_G;
break;
case 4:
led_order[0] = LED_Y;
led_order[1] = LED_G;
led_order[2] = LED_B;
break;
case 5:
led_order[0] = LED_G;
led_order[1] = LED_Y;
led_order[2] = LED_B;
break;
default:
led_order[0] = LED_G;
led_order[1] = LED_B;
led_order[2] = LED_Y;
break;
}
}
I coded it using Arduino IDE and loaded the program using microUSB cable. I used ChatGPT for formating and syntax.
I also mesured the power consuption of the red LED by measuring voltage on the current-limit resistor (R = 470 Ω). I measured 2.974 V. We can get the current by