#include <avr/io.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
LiquidCrystal_I2C lcd(0x27, 20, 04);
#define coinslot 2
#define charge1 8
#define charge2 9
#define charge3 10
#define charge4 11
const int buttonPin1 = 4;
const int buttonPin2 = 5;
const int buttonPin3 = 6;
const int buttonPin4 = 7;
bool buttonState1 = true;
bool buttonState2 = true;
bool buttonState3 = true;
bool buttonState4 = true;
bool lastButtonState1 = true;
bool lastButtonState2 = true;
bool lastButtonState3 = true;
bool lastButtonState4 = true;
bool T1_tone, T2_tone, T3_tone, T4_tone;
unsigned long lastDebounceTime1 = 0;
unsigned long lastDebounceTime2 = 0;
unsigned long lastDebounceTime3 = 0;
unsigned long lastDebounceTime4 = 0;
unsigned long debounceDelay = 50;
const int T1 = A0; // Use analog pin A0 for tone generation
const int T2 = A1; // Use analog pin A0 for tone generation
const int T3 = A2; // Use analog pin A0 for tone generation
const int T4 = A3; // Use analog pin A0 for tone generation
const unsigned long toneDuration = 500; // Time in milliseconds for each half of the tone (on and off)
unsigned long previousMillis_tone = 0; // Variable to store the last time the tone state was changed
bool toneState = false; // Variable to store the current state of the tone
unsigned long previousMillis = 0;
const long interval = 900;
int time1, time2, time3, time4;
volatile int coin;
int percoin = 0;
int delayvalue = 500;;
int minutes;
int remainingSeconds;
String output;
int time1zero, time2zero, time3zero, time4zero, set;
/////////////////////////////////////////////
/////////////////////////////////////////////
uint32_t ChipID = 4294967295; /// DEVICE ID MUST be UNIQUE every board
#define prod ///set to prod once all is OK, this test to include ChipID to avoid copy of HEX code
////////////////////////////////////////////
uint32_t CHIPID() {
uint32_t chipId = 0;
for (int i = 0; i < 4; i++) {
chipId |= (uint32_t)(eeprom_read_byte((uint8_t*)(0x0E + i)) << (i * 8));
}
Serial.print("chipId ");
Serial.println(chipId);
if (chipId != ChipID) {
lcd.setCursor(0, 0);
lcd.print("NOT VALID DEVICE ID");
lcd.setCursor(0, 1);
lcd.print("CODE has a copyright");
lcd.setCursor(0, 2);
lcd.print("contact manufacturer");
lcd.setCursor(0, 3);
lcd.print("for code detail !!!");
while (true);
} else {
lcd.setCursor(5, 0);
lcd.print("Like Us On ");
lcd.setCursor(6, 1);
lcd.print("Facebook");
lcd.setCursor(1, 2);
lcd.print("AB AGVM 4in1 Timer");
}
delay(5000);
}
void setup() {
Serial.begin(115200);
lcd.init();
lcd.backlight();
EEPROM.put(1, 60); // test
percoin = EEPROM.get(1, percoin);
#ifdef prod
CHIPID();
#endif
lcd.setCursor(2, 3);
lcd.print("!! Thank You !!");
// put your setup code here, to run once:
pinMode(charge1, OUTPUT);
pinMode(charge2, OUTPUT);
pinMode(charge3, OUTPUT);
pinMode(charge4, OUTPUT);
pinMode(T1, OUTPUT);
pinMode(T2, OUTPUT);
pinMode(T3, OUTPUT);
pinMode(T3, OUTPUT);
pinMode(coinslot, INPUT_PULLUP);
pinMode(buttonPin1, INPUT_PULLUP);
pinMode(buttonPin2, INPUT_PULLUP);
pinMode(buttonPin3, INPUT_PULLUP);
pinMode(buttonPin4, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(coinslot), addcoin, FALLING);
delay(2000);
lcd.clear();
bool reading1 = digitalRead(buttonPin1);
if (!reading1 or percoin <= 0) {
while (1) {
if (percoin < 0) {
percoin = 0;
}
lcd.setCursor(0, 0);
lcd.print("Setting Mode");
bool reading2 = digitalRead(buttonPin2);
bool reading3 = digitalRead(buttonPin3);
bool reading4 = digitalRead(buttonPin4);
lcd.setCursor(0, 2);
lcd.print("Second Per Coin:");
lcd.print(percoin);
lcd.print(" ");
if (!reading2) {
percoin ++;
delay(delayvalue);
delayvalue -= 50;
if (delayvalue <= 50) {
delayvalue = 50;
}
lcd.setCursor(0, 2);
lcd.print("Second Per Coin:");
lcd.print(percoin);
lcd.print(" ");
}
if (!reading3 && percoin > 0) {
percoin --;
delay(delayvalue);
delayvalue -= 50;
if (delayvalue <= 50) {
delayvalue = 50;
}
lcd.setCursor(0, 2);
lcd.print("Second Per Coin:");
lcd.print(percoin);
lcd.print(" ");
}
if (reading2 && reading3) {
delayvalue = 500;
}
if (percoin < 0) {
percoin = 0;
}
if (!reading4) {
if (percoin > 0) {
EEPROM.put(1, percoin);
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Saving Value!!");
lcd.setCursor(0, 2);
lcd.print("Second Per Coin:");
lcd.print(percoin);
delay(2000);
percoin = EEPROM.get(1, percoin);
lcd.clear();
return 0;
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Unable to save zero");
lcd.setCursor(0, 1);
lcd.print("value");
delay(1000);
lcd.clear();
}
}
}
}
}
void loop() {
// put your main code here, to run repeatedly:
countdown();
if (coin > 0) {
if (set) {
lcd.setCursor(16, 0);
lcd.print(" ");
set = 0;
}
lcd.setCursor(17, 0);
lcd.print(coin / percoin);
lcd.print(" ");
} else {
if (time1 <= 0) {
lcd.setCursor(16, 0);
lcd.print("coin");
} else {
lcd.setCursor(16, 0);
lcd.print(" ");
}
set = 1;
}
lcd.setCursor(0, 0);
lcd.print("Station1:");
lcd.setCursor(9, 0);
if (time1 > 0) {
minutes = time1 / 60;
remainingSeconds = time1 % 60;
//output = " " + String(minutes) + ":" + String(remainingSeconds) + " ";
//Serial.println(output);
if (time1zero) {
lcd.print(" ");
time1zero = 0;
}
lcd.setCursor(9, 0);
lcd.print(" ");
lcd.print(minutes);
lcd.print(":");
lcd.print(remainingSeconds);
lcd.print(" ");
} else {
//output = "insert coin";
lcd.print("insert");
time1zero = 1;
//lcd.print(" ");
}
lcd.setCursor(0, 1);
lcd.print("Station2:");
lcd.setCursor(9, 1);
if (time2 > 0) {
minutes = time2 / 60;
remainingSeconds = time2 % 60;
//output = " " + String(minutes) + ":" + String(remainingSeconds) + " ";
//Serial.println(output);
if (time2zero) {
lcd.print(" ");
time2zero = 0;
}
lcd.setCursor(9, 1);
lcd.print(" ");
lcd.print(minutes);
lcd.print(":");
lcd.print(remainingSeconds);
lcd.print(" ");
} else {
//output = "insert coin";
lcd.print("insert coin");
time2zero = 1;
//lcd.print(" ");
}
lcd.setCursor(0, 2);
lcd.print("Station3:");
lcd.setCursor(9, 2);
if (time3 > 0) {
minutes = time3 / 60;
remainingSeconds = time3 % 60;
//output = " " + String(minutes) + ":" + String(remainingSeconds) + " ";
//Serial.println(output);
if (time3zero) {
lcd.print(" ");
time3zero = 0;
}
lcd.setCursor(9, 2);
lcd.print(" ");
lcd.print(minutes);
lcd.print(":");
lcd.print(remainingSeconds);
lcd.print(" ");
} else {
//output = "insert coin";
lcd.print("insert coin");
time3zero = 1;
//lcd.print(" ");
}
lcd.setCursor(0, 3);
lcd.print("Station4:");
lcd.setCursor(9, 3);
if (time4 > 0) {
minutes = time4 / 60;
remainingSeconds = time4 % 60;
//output = " " + String(minutes) + ":" + String(remainingSeconds) + " ";
//Serial.println(output);
if (time4zero) {
lcd.print(" ");
time4zero = 0;
}
lcd.setCursor(9, 3);
lcd.print(" ");
lcd.print(minutes);
lcd.print(":");
lcd.print(remainingSeconds);
lcd.print(" ");
} else {
//output = "insert coin";
lcd.print("insert coin");
time4zero = 1;
//lcd.print(" ");
}
if (coin > 0) {
bool reading1 = digitalRead(buttonPin1);
bool reading2 = digitalRead(buttonPin2);
bool reading3 = digitalRead(buttonPin3);
bool reading4 = digitalRead(buttonPin4);
if (reading1 != lastButtonState1) {
lastDebounceTime1 = millis();
}
if (reading2 != lastButtonState2) {
lastDebounceTime2 = millis();
}
if (reading3 != lastButtonState3) {
lastDebounceTime3 = millis();
}
if (reading4 != lastButtonState4) {
lastDebounceTime4 = millis();
}
if ((millis() - lastDebounceTime1) > debounceDelay) {
if (reading1 != buttonState1) {
buttonState1 = reading1;
if (buttonState1 == LOW) {
Serial.println("Button 1 pressed!");
// Do any additional actions here
time1 = time1 + coin;
coin = 0;
}
}
}
if ((millis() - lastDebounceTime2) > debounceDelay) {
if (reading2 != buttonState2) {
buttonState2 = reading2;
if (buttonState2 == LOW) {
Serial.println("Button 2 pressed!");
// Do any additional actions here
time2 = time2 + coin;
coin = 0;
}
}
}
if ((millis() - lastDebounceTime3) > debounceDelay) {
if (reading3 != buttonState3) {
buttonState3 = reading3;
if (buttonState3 == LOW) {
Serial.println("Button 3 pressed!");
// Do any additional actions here
time3 = time3 + coin;
coin = 0;
}
}
}
if ((millis() - lastDebounceTime4) > debounceDelay) {
if (reading4 != buttonState4) {
buttonState4 = reading4;
if (buttonState4 == LOW) {
Serial.println("Button 4 pressed!");
// Do any additional actions here
time4 = time4 + coin;
coin = 0;
}
}
}
lastButtonState1 = reading1;
lastButtonState2 = reading2;
lastButtonState3 = reading3;
lastButtonState4 = reading4;
}
}
void countdown() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if (time1 > 0) {
time1 --;
Serial.print("time1 : ");
Serial.println(time1);
digitalWrite(charge1, LOW);
} else {
digitalWrite(charge1, HIGH);
}
if (time2 > 0) {
time2 --;
Serial.print("time2 :");
Serial.println(time2);
digitalWrite(charge2, LOW);
} else {
digitalWrite(charge2, HIGH);
}
if (time3 > 0) {
time3 --;
Serial.print("time3 :");
Serial.println(time3);
digitalWrite(charge3, LOW);
} else {
digitalWrite(charge3, HIGH);
}
if (time4 > 0) {
time4 --;
Serial.print("time4 :");
Serial.println(time4);
digitalWrite(charge4, LOW);
} else {
digitalWrite(charge4, HIGH);
}
}
Alarm();
}
void addcoin() {
coin += percoin;
Serial.println(coin);
}
void Alarm() {
unsigned long currentMillis = millis(); // Get the current time in milliseconds
// Check if it's time to change the tone state
if (currentMillis - previousMillis_tone >= toneDuration) {
previousMillis_tone = currentMillis; // Update the previous time
toneState = !toneState; // Toggle the tone state (on or off)
if (toneState) {
// Turn on the tone
if (time1 < 31 && time1 > 26 || time1 < 6 && time1 > 0 && T1_tone) {
tone(T1, 1000);
Serial.println("T1");
}
if (time2 < 31 && time2 > 26 || time2 < 6 && time2 > 0 && T2_tone) {
tone(T2, 1000);
Serial.println("T2");
}
if (time3 < 31 && time3 > 26 || time3 < 6 && time3 > 0 && T3_tone) {
tone(T3, 1000);
Serial.println("T3");
}
if (time4 < 31 && time4 > 26 || time4 < 6 && time4 > 0 && T4_tone) {
tone(T4, 1000);
Serial.println("T4");
}
//ternary operation
T1_tone = (time1 == 0) ? false : true;
T2_tone = (time2 == 0) ? false : true;
T3_tone = (time3 == 0) ? false : true;
T4_tone = (time4 == 0) ? false : true;
} else {
// Turn off the tone
noTone(T1);
noTone(T2);
noTone(T3);
noTone(T4);
}
}
}