#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); // LCD 20x4, address 0x27
// Pins
const int COIN_PIN = 27; // Pushbutton as coin slot
const int RELAY_PIN = 26; // Relay to turn ON/OFF PC
// Config
const int SECONDS_PER_PESO = 180; // 1 peso = 3 min = 180s
const int PREPARE_SECONDS = 10; // 10s before play starts
// Variables
volatile int credits = 0;
unsigned long totalSeconds = 0;
bool playing = false;
unsigned long lastCoinTime = 0;
void IRAM_ATTR coinInserted() {
credits++;
totalSeconds += SECONDS_PER_PESO;
lastCoinTime = millis();
}
void setup() {
Serial.begin(115200);
pinMode(COIN_PIN, INPUT_PULLUP);
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
attachInterrupt(digitalPinToInterrupt(COIN_PIN), coinInserted, FALLING);
lcd.init();
lcd.backlight();
lcd.setCursor(0,0); lcd.print(" PISONET V1.0");
lcd.setCursor(0,1); lcd.print(" Insert Coins...");
delay(2000);
lcd.clear();
}
void loop() {
unsigned long now = millis();
if (!playing) {
lcd.setCursor(0,0); lcd.print("Insert Coins ");
lcd.setCursor(0,1); lcd.print("Credits: ");
lcd.print(credits);
if (credits > 0 && (now - lastCoinTime > PREPARE_SECONDS * 1000)) {
playing = true;
digitalWrite(RELAY_PIN, HIGH); // turn ON load/PC
lcd.clear();
}
} else {
if (totalSeconds > 0) {
totalSeconds--;
showTime(totalSeconds);
delay(1000);
} else {
// Time up
digitalWrite(RELAY_PIN, LOW);
credits = 0;
playing = false;
lcd.clear();
lcd.setCursor(0,0); lcd.print("Time Finished!");
delay(2000);
lcd.clear();
}
}
}
void showTime(unsigned long sec) {
int hours = sec / 3600;
int mins = (sec % 3600) / 60;
int secs = sec % 60;
lcd.setCursor(0,0); lcd.print("Time Remaining: ");
lcd.setCursor(0,1);
if (hours > 0) {
lcd.print(hours); lcd.print("h ");
}
lcd.print(mins); lcd.print("m ");
lcd.print(secs); lcd.print("s ");
}