/*
https://forum.arduino.cc/t/arduino-coin-operated-charging-station/1297373
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Initialize the LCD
LiquidCrystal_I2C lcd(0x27, 20, 4); // Set the I2C address of the LCD
// Pin definitions
const int relayPins[4] = {2, 3, 4, 5}; // Relay pins
const int buttonPins[4] = {6, 7, 8, 9}; // Button pins
const int buzzerPin = 10; // Buzzer pin
const int coinSlotPin = 11; // Coin slot pin
// Timing variables
unsigned long relayEndTimes[4] = {0, 0, 0, 0}; // End time for each relay
const unsigned long chargeTimePerCoin = 120; // 2 minutes per coin in seconds
int coinsInserted = 0;
unsigned long lastUpdateTime = 0;
const unsigned long updateInterval = 1000; // Update every second
// Variables to store previous LCD values for comparison
int prevCoinsInserted = -1;
unsigned long prevRelayTimes[4] = {0, 0, 0, 0};
void setup() {
// Set up the LCD
lcd.init();
lcd.backlight();
// Set relay and button pins as output/input
for (int i = 0; i < 4; i++) {
pinMode(relayPins[i], OUTPUT);
digitalWrite(relayPins[i], LOW); // Ensure relays are off
pinMode(buttonPins[i], INPUT_PULLUP); // Buttons are active LOW
}
pinMode(buzzerPin, OUTPUT);
pinMode(coinSlotPin, INPUT_PULLUP); // Use internal pull-up resistor
// Display initial message on the LCD
lcd.setCursor(0, 0);
lcd.print("E-Piso Charger");
lcd.setCursor(0, 1);
lcd.print("2 mins/PHP");
lcd.setCursor(0, 2);
lcd.print("1|00:00 2|00:00");
lcd.setCursor(0, 3);
lcd.print("3|00:00 4|00:00");
}
void loop() {
// Check for coin insertion
if (digitalRead(coinSlotPin) == LOW) { // Coin detected
delay(50); // Debounce
if (digitalRead(coinSlotPin) == LOW) { // Confirm coin detection
coinsInserted++;
tone(buzzerPin, 1000, 100); // Beep the buzzer
while (digitalRead(coinSlotPin) == LOW) {
// Wait until the coin is removed
delay(10);
}
}
delay(500); // Prevent double counting
}
// Check buttons for starting charging
for (int i = 0; i < 4; i++) {
if (digitalRead(buttonPins[i]) == LOW) { // Button pressed
delay(50); // Debounce
if (digitalRead(buttonPins[i]) == LOW && coinsInserted > 0 && digitalRead(coinSlotPin) == HIGH) {
startCharging(i);
delay(300); // Avoid multiple triggers
}
}
}
// Update relay timing
for (int i = 0; i < 4; i++) {
if (relayEndTimes[i] > 0 && millis() >= relayEndTimes[i]) {
stopCharging(i);
relayEndTimes[i] = 0; // Reset the relay end time
}
}
// Only update the LCD every second
if (millis() - lastUpdateTime >= updateInterval) {
updateLCD();
lastUpdateTime = millis();
}
}
void startCharging(int relay) {
digitalWrite(relayPins[relay], HIGH); // Turn on the relay
relayEndTimes[relay] += millis() + coinsInserted * chargeTimePerCoin * 1000; // Set the end time for the relay based on the number of coins inserted
coinsInserted = 0; // Reset the coin count after starting the charging
}
void stopCharging(int relay) {
digitalWrite(relayPins[relay], LOW); // Turn off the relay
}
void updateLCD() {
// Update only if values have changed
if (coinsInserted != prevCoinsInserted) {
lcd.setCursor(14, 1);
lcd.print("C: ");
lcd.print(coinsInserted);
prevCoinsInserted = coinsInserted;
}
for (int i = 0; i < 4; i++) {
unsigned long remainingTime = relayEndTimes[i] > 0 ? (relayEndTimes[i] - millis()) / 1000 : 0;
if (remainingTime != prevRelayTimes[i]) {
// Update relay time display
int row = i < 2 ? 2 : 3;
// int col = i % 2 == 0 ? 0 : 11;
int col = i % 2 == 0 ? 0 : 8;
lcd.setCursor(col, row);
lcd.print(i + 1);
lcd.print("|");
lcd.print(formatTime(remainingTime));
prevRelayTimes[i] = remainingTime;
}
}
}
String formatTime(unsigned long timeInSeconds) {
unsigned long minutes = timeInSeconds / 60;
unsigned long seconds = timeInSeconds % 60;
char buffer[6];
sprintf(buffer, "%02lu:%02lu", minutes, seconds);
return String(buffer);
}