#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
volatile int coins = 0; // Count of coins
const int buttonPin = A0;
const int relayPins[] = {3, 2, 14, 15, 16, 17};
const int ledPins[] = {A1, A2, A3, A4, A5, A6};
const int coinPulsePin = A14; // Coin pulse input pin
const int additionalLedPin = A13; // Additional LED pin
int selectedButton = 0;
unsigned long startTimes[] = {0, 0, 0, 0, 0, 0}; // Adjusted to 6 buttons
unsigned long activationTimes[] = {0, 0, 0, 0, 0, 0};
unsigned long lastButtonPressTime = 0;
bool buttonDisabled[] = {false, false, false, false, false, false};
// Function to calculate activation time based on coin pulses
unsigned long calculateActivationTime(int pulseCount) {
if (pulseCount % 10 == 0) {
return 10800000; // 180 minutes for 10 or more pulses
} else if (pulseCount % 5 == 0) {
return 3600000; // 60 minutes for multiples of 5 (except 10)
} else {
return pulseCount * 600000; // 10 minutes for each pulse
}
}
// Interrupt function for coin pulse detection
void coinPulse() {
coins++;
}
void setup() {
lcd.backlight();
lcd.begin(20, 4);
lcd.print(" CHARGING STATION");
lcd.setCursor(0, 2);
lcd.print(" by: Shirhan A. B.");
delay(2000);
lcd.clear();
// Initialize pins
for (int i = 0; i < 6; i++) {
pinMode(relayPins[i], OUTPUT);
pinMode(ledPins[i], OUTPUT);
}
pinMode(buttonPin, INPUT_PULLUP);
pinMode(coinPulsePin, INPUT_PULLUP); // Set coin pulse pin as input
pinMode(additionalLedPin, OUTPUT);
digitalWrite(additionalLedPin, HIGH);
// Attach interrupt for coin pulse
attachInterrupt(digitalPinToInterrupt(coinPulsePin), coinPulse, FALLING);
}
void loop() {
// Check for button press to select port
if (digitalRead(buttonPin) == LOW) {
delay(50); // Debouncing delay
if (digitalRead(buttonPin) == LOW) {
// Button pressed
selectedButton++;
if (selectedButton > 6) {
selectedButton = 1;
}
lcd.setCursor(0, 0);
lcd.print("Choose port:" + String(selectedButton));
lastButtonPressTime = millis(); // Record the time of the button press
unsigned long displayDuration = 500; // 10 seconds
unsigned long startDisplayTime = lastButtonPressTime; // Start the timer
// Display the selected button for 10 seconds or until a coin is inserted
while (millis() - startDisplayTime < displayDuration) {
if (coins > 0) { // Check if a coin has been inserted
break; // Exit the display loop if a coin is inserted
}
// Optionally update the LCD here if needed, e.g., to refresh the display
delay(100); // Small delay to prevent busy-waiting
}
}
}
if (coins > 0 && selectedButton != 0) {
lcd.clear();
// Set the activation time based on the number of coins
activationTimes[selectedButton - 1] = calculateActivationTime(coins);
activateRelayAndLed(relayPins[selectedButton - 1], ledPins[selectedButton - 1], startTimes[selectedButton - 1]);
coins = 0; // Reset coins after using them
selectedButton = 0;
}
if (millis() - lastButtonPressTime >= 10000) {
digitalWrite(additionalLedPin, LOW);
} else {
digitalWrite(additionalLedPin, HIGH);
}
lcd.setCursor(0, 0);
lcd.print("Choose port:");
for (int i = 0; i < 6; i++) {
if (startTimes[i] > 0) {
unsigned long remainingTime = activationTimes[i] - (millis() - startTimes[i]);
unsigned long remainingMinutes = remainingTime / 60000;
unsigned long remainingSeconds = (remainingTime % 60000) / 1000;
lcd.setCursor((i < 3) ? 0 : 10, (i % 3) + 1);
lcd.print(String(1 + i) + ":" + String(remainingMinutes) + "m " + String(remainingSeconds) + "s");
}
if (millis() - startTimes[i] >= activationTimes[i] && digitalRead(relayPins[i]) == LOW) {
digitalWrite(relayPins[i], HIGH);
digitalWrite(ledPins[i], LOW);
startTimes[i] = 0;
activationTimes[i] = 0;
selectedButton = 0;
buttonDisabled[i] = false;
}
}
}
void activateRelayAndLed(int relay, int led, unsigned long &startTime) {
if (startTime == 0) {
digitalWrite(relay, LOW);
digitalWrite(led, HIGH);
startTime = millis();
}
}