/*
Eksempel på tankemåte for å lage en safe med arduino
Studieassistanse for 5E ved Fagskolen Rogaland
10. Januar 2023
Skrevet av: Vidar Hestad
*/
// #### System Variables ####
const int speaker_pin = 7;
const int button_pin = 6;
const int pot_pin = A0;
const int green_led_pin = 4;
const int red_led_pin = 3;
unsigned long button_timer = 0;
unsigned long button_delay = 300;
// #### Safe variables ####
const int num_of_combinations = 4;
const int num_of_tries = 4;
int tries_count = 0;
int correct_count = 0;
int fails_count = 0;
bool user_failed = false;
bool user_fail_warning = false;
bool safe_sucsess = false;
unsigned int tone_warning = 1000;
unsigned int tone_alert_high = 1400;
unsigned int tone_alert_low = 1200;
const int alert_time = 300;
int pot_value = 0;
// The combinations must have a value between 0 and 1023
// It is recomended to have a allowed specter of at least 50 for each combination
// These are the correct combinations
const int combination_1 = 25;
const int combination_2 = 850;
const int combination_3 = 600;
const int combination_4 = 230;
// The allowed offset in each direction to be granted access
const int combination_step = 50;
const int combination_low_1 = combination_1 - combination_step;
const int combination_low_2 = combination_2 - combination_step;
const int combination_low_3 = combination_3 - combination_step;
const int combination_low_4 = combination_4 - combination_step;
const int combination_high_1 = combination_1 + combination_step;
const int combination_high_2 = combination_2 + combination_step;
const int combination_high_3 = combination_3 + combination_step;
const int combination_high_4 = combination_4 + combination_step;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(speaker_pin, OUTPUT);
pinMode(green_led_pin, OUTPUT);
pinMode(red_led_pin, OUTPUT);
pinMode(pot_pin, INPUT);
pinMode(button_pin, INPUT_PULLUP);
}
void loop() {
// put your main code here, to run repeatedly:
if ((millis() > button_timer + button_delay) && digitalRead(button_pin) == false) {
button_timer = millis();
check_input();
print_serial();
if (safe_sucsess) {
sucsess();
} else if (user_failed) {
fail();
}
}
}
void sucsess() {
bool congratulate_success = true;
bool light_on = true;
bool tone_active = true;
unsigned int congratulate_start = millis();
unsigned long green_blink_timer = 0;
unsigned long tone_timer = 0;
int green_blink_time = 300;
int tone_count = 0;
int delay = 0;
digitalWrite(red_led_pin, LOW);
user_fail_warning = false;
Serial.println("-------------------------");
Serial.println("The safe is now open!");
Serial.println("-------------------------");
while (congratulate_success) {
if (millis() > green_blink_timer + green_blink_time) {
green_blink_timer = millis();
digitalWrite(green_led_pin, light_on);
light_on = !light_on;
}
if (tone_active) {
switch (tone_count) {
case 0:
tone(speaker_pin, 560);
delay = 250;
break;
case 1:
tone(speaker_pin, 750);
delay = 250;
break;
case 2:
tone(speaker_pin, 300);
delay = 200;
break;
case 3:
tone(speaker_pin, 1200);
delay = 100;
break;
case 4:
tone(speaker_pin, 1500);
delay = 500;
break;
case 5:
tone(speaker_pin, 1000);
delay = 200;
break;
case 6:
tone(speaker_pin, 1900);
delay = 300;
break;
case 7:
congratulate_success = false;
}
tone_count++;
tone_active = false;
tone_timer = millis();
}
if (millis() > tone_timer + delay) tone_active = true;
}
digitalWrite(green_led_pin, LOW);
noTone(speaker_pin);
tries_count = 0;
correct_count = 0;
fails_count = 0;
safe_sucsess = false;
}
void fail() {
bool total_failure;
bool alert_flag = false;
unsigned long alert_timer = 0;
user_failed = false;
fails_count++;
Serial.println("--------------------------------------");
Serial.println("The combination was wrong, try again");
Serial.println("--------------------------------------");
if (!user_fail_warning) {
user_fail_warning = true;
digitalWrite(red_led_pin, HIGH);
tone(speaker_pin, tone_warning);
} else if (user_fail_warning && fails_count >= num_of_tries) {
total_failure = true;
Serial.println("--------------------------------------");
Serial.println("You have passed 4 wrong combinations");
Serial.println(" --------");
Serial.println("The safe is now permanently locked!");
Serial.println("--------------------------------------");
while (total_failure) {
if ((millis() > alert_timer + alert_time) && !alert_flag) {
alert_timer = millis();
digitalWrite(red_led_pin, LOW);
tone(speaker_pin, tone_alert_high);
alert_flag = !alert_flag;
} else if ((millis() > alert_timer + alert_time) && alert_flag) {
alert_timer = millis();
digitalWrite(red_led_pin, HIGH);
tone(speaker_pin, tone_alert_low);
alert_flag = !alert_flag;
}
}
}
}
void check_input() {
pot_value = analogRead(pot_pin);
switch (tries_count) {
case 0:
if (pot_value <= combination_high_1 && pot_value >= combination_low_1) {
correct_count++;
}
break;
case 1:
if (pot_value <= combination_high_2 && pot_value >= combination_low_2) {
correct_count++;
}
break;
case 2:
if (pot_value <= combination_high_3 && pot_value >= combination_low_3) {
correct_count++;
}
break;
case 3:
if (pot_value <= combination_high_4 && pot_value >= combination_low_4) {
correct_count++;
}
break;
}
tries_count++;
if (correct_count >= num_of_combinations) {
safe_sucsess = true;
}
else if (tries_count >= num_of_combinations & ! (correct_count >= num_of_combinations)) {
user_failed = true;
tries_count = 0;
correct_count = 0;
}
}
void print_serial() {
Serial.print("Potmeter: "); Serial.println(pot_value);
Serial.print("Kombinasjoner: "); Serial.println(tries_count);
Serial.print("Korrekte: "); Serial.println(correct_count);
Serial.print("Av: "); Serial.println(num_of_combinations);
Serial.print("Forsøk: "); Serial.println(fails_count);
Serial.print("Av: "); Serial.println(num_of_tries);
}