#include <SPI.h>
#include <Wire.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 OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const int BEEP_PITCH = 502;
const int FEEDBACK_PITCH = 294;
const int BUZZER= 3;
const int START= 2;
const int CONFIG= 9;
const long DURATIONS[] = {60000, 90000, 120000, 180000, 240000, 30000};
const int CONFIG_COUNT = sizeof(DURATIONS) / sizeof(DURATIONS[0]);
const long WARNING_DURATION = 30000;
const long READY_DURATION = 10000;
int configIndex = 0;
long startTime = 0;
long currentDuration = 0;
void showTimerSettingOnScreen(bool showPressStart = true){
display.clearDisplay();
display.println("Time: ");
display.setCursor(5,10);
display.println(DURATIONS[configIndex]/1000);
if (showPressStart){
display.setCursor(20,42);
display.println("Press start");
}
}
void setup() {
// put your setup code here, to run once:
display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
pinMode (BUZZER, OUTPUT);
pinMode (START, INPUT);
pinMode (CONFIG, INPUT);
display.print("ARCHERY TIMER");
}
int beep(int count, int frequency = BEEP_PITCH, int duration = 800, int delayBetweenBeeps = 1000){
int delaySum = 0;
tone(BUZZER, frequency, duration);
for (int i=1; i<count; i++){
delay(delayBetweenBeeps);
delaySum += delayBetweenBeeps;
tone(BUZZER, frequency, duration);
}
return delaySum;
}
void configButtonPressed()
{
//move to next duration in duration array
configIndex = (configIndex + 1) % CONFIG_COUNT;
}
void displayTime(long time)
{
display.setCursor(7,1);
display.println(time);
display.println(" ");
}
bool timerLoop(long duration, long warningTime = -1)
{
long start = millis();
bool exitButtonPressed = false;
long timer;
if (warningTime >= duration)
{
warningTime = -1;
}
do
{
delay(100);
timer = duration - (millis() - start) ;
long timeToShow = timer/1000 + 1;
displayTime(timeToShow);
if (timeToShow == warningTime/1000)
{
beep(1, BEEP_PITCH, 400);
warningTime = -1;
}
int startButtonState = digitalRead(START);
if (startButtonState == HIGH) {
exitButtonPressed = true;
}
delay(100);
}while(!exitButtonPressed && timer > 0);
displayTime(0);
return exitButtonPressed;
}
// the loop function runs over and over again forever
void loop() {
while(true){
// wait for user's input for new round or configuration change
int startButtonState = digitalRead(START);
if (startButtonState == HIGH) {
currentDuration = DURATIONS[configIndex];
break;
}
int configButtonState = digitalRead(CONFIG);
if (configButtonState == HIGH){
configButtonPressed();
}
}
beep(2);
bool emergencyExit = timerLoop(READY_DURATION);
if (!emergencyExit)
{
beep(1);
emergencyExit = timerLoop(currentDuration, WARNING_DURATION);
}
beep(3);
}