Arduino coin operated charging station

thank you so much the lcd is working when i use the 12v adaptor to power the arduino..tomorrow after work i will test the coins..thank you,, thank you

sir question is it possible to add another button for setting time for example I will change the default time of 2 minutes by just using that button then the display on the lcd will show when setting up the time..after setting up the time you press the arduino's reset button so you can save your setup time?

yes. but it should be good protected against unallowed access

1 Like

i will pud that button inside the box so that i am the only one can access that

Can you please check the code I made if it is correct? I added a button to adjust the default time

#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] = {4, 5, 6, 7}; // Relay pins
const int buttonPins[4] = {8, 9, 10, 11}; // Button pins
const int buzzerPin = 3; // Buzzer pin
const int coinSlotPin = 2; // Coin slot pin
const int adjustTimeButtonPin = 12; // Button for adjusting default time

// Timing variables
unsigned long relayEndTimes[4]; // End time for each relay
volatile int coinsInserted = 0;
int chargeTimePerCoin = 120; // 2 minutes per coin in seconds (modifiable)
#define Relay_On(b) digitalWrite(relayPins[b], LOW)
#define RelayOff(b) digitalWrite(relayPins[b], HIGH)

void setup() {
  // Set up the LCD
  lcd.init();
  lcd.backlight();

  // Set relay, button pins, and adjustTimeButtonPin as output/input
  for (int i = 0; i < 4; i++) {
    digitalWrite(relayPins[i], HIGH); // Ensure relays are off
    pinMode(relayPins[i], OUTPUT);
    pinMode(buttonPins[i], INPUT_PULLUP); // Buttons are active LOW
  }
  
  pinMode(adjustTimeButtonPin, INPUT_PULLUP); // Button to adjust time is 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    C: 0");
  lcd.setCursor(0, 2);
  lcd.print("1|00:00 2|00:00");
  lcd.setCursor(0, 3);
  lcd.print("3|00:00 4|00:00");
  attachInterrupt(digitalPinToInterrupt(coinSlotPin), Add, FALLING);
}

void Add() {
  coinsInserted++;
}

void loop() {
  const uint32_t tausend = 1000UL;
  static uint32_t lastUpdateTime = 0;

  // Check for coin insertion
  if (digitalRead(coinSlotPin) ) {
    delay(800);
    lcd.setCursor(17, 1);
    lcd.print(coinsInserted > 99 ? 99 : coinsInserted);
    tone(buzzerPin, tausend, 100); // Beep the buzzer
  }

  // Check the adjust time button
  static bool adjustingTime = false;
  if (digitalRead(adjustTimeButtonPin) == LOW) {
    delay(300); // Debounce delay
    adjustingTime = !adjustingTime; // Toggle the adjusting mode
    
    if (adjustingTime) {
      lcd.setCursor(0, 0);
      lcd.print("Adjust Time Mode ");
      lcd.setCursor(0, 1);
      lcd.print("Current Time: ");
      lcd.print(chargeTimePerCoin / 60);
      lcd.print(" mins");
    } else {
      lcd.setCursor(0, 0);
      lcd.print("E-Piso Charger    ");
      lcd.setCursor(0, 1);
      lcd.print(chargeTimePerCoin / 60);
      lcd.print(" mins/PHP    C: ");
      lcd.print(coinsInserted);
    }
  }

  if (adjustingTime && digitalRead(adjustTimeButtonPin) == LOW) {
    delay(300); // Debounce delay
    chargeTimePerCoin += 30; // Increase time by 30 seconds
    if (chargeTimePerCoin > 600) chargeTimePerCoin = 30; // Limit the maximum time to 10 minutes (600 seconds)

    lcd.setCursor(0, 1);
    lcd.print("Current Time: ");
    lcd.print(chargeTimePerCoin / 60);
    lcd.print(" mins    ");
  }

  for (int i = 0; i < 4; i++) {
    // Check buttons for starting charging
    if (coinsInserted > 0 && digitalRead(buttonPins[i]) == LOW ) {
      Relay_On(i); // Turn on the relay
      if (!relayEndTimes[i]) relayEndTimes[i] = millis();
      relayEndTimes[i] += tausend * coinsInserted * chargeTimePerCoin; // Set the end time for the relay based on the number of coins inserted
      coinsInserted = 0; // Reset the coin count after starting the charging
      lcd.setCursor(17, 1);
      lcd.print("0 ");
    }

    // Update relay timing
    if (relayEndTimes[i] > 0 && millis() >= relayEndTimes[i]) {
      RelayOff(i); // Turn off the relay
      relayEndTimes[i] = 0; // Reset the relay end time
    }
  }

  // Only update the LCD every second
  if (millis() - lastUpdateTime >= tausend) {
    char buffer[6];

    for (uint8_t i = 0; i < 4; i++) {
      uint16_t remainingTime = relayEndTimes[i] > 0 ? (relayEndTimes[i] - millis()) / tausend : 0;
      uint8_t row = i < 2 ? 2 : 3;
      uint8_t col = i % 2 == 0 ? 2 : 10;
      lcd.setCursor(col, row);

      sprintf(buffer, "%02u:%02u", remainingTime / 60, remainingTime % 60);
      lcd.print(buffer);
    }
    lastUpdateTime += tausend;
  }
}

make separated sketch to test time adjusting. it is better to place this in setup(), before current code, just after LCD ini. it should check pin 12 on start up, and 4 other buttons can be up, down and OK action.

1 Like

after lcd.backlight?

everything messing up

first:

1 Like

i made one but doesnt work

ok, at least you tried, now you can give up

1 Like

Is it difficult to add him to the code?

we will think when we have something to add.

1 Like

hello everone..need help with my project which is an arduino coin operated charging station..when i power on the arduino then only the lcd is attached and the display is ok..i use a 12 5a power supply but when everything is connected the relay push button then conslot the LCD doesn't work the display is box box only visible.. then if I power it on using 5v 2a the LCD works when all the components are connected the coinslot autocredits.. please someone can help?.. here is the code i am using given by sir kolaha

/*
  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] = {4, 5, 6, 7}; // Relay pins
const int buttonPins[4] = {8, 9, 10, 11}; // Button pins
const int buzzerPin = 3; // Buzzer pin
const int coinSlotPin = 2; // Coin slot pin <-------------------------------------< ATTENTION ! all pins are changed

// Timing variables
unsigned long relayEndTimes[4]; // End time for each relay
volatile int coinsInserted = 0;
const int chargeTimePerCoin = 120; // 2 minutes per coin in seconds
#define Relay_On(b) digitalWrite(relayPins[b], LOW)
#define RelayOff(b) digitalWrite(relayPins[b], HIGH)

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++) {
    digitalWrite(relayPins[i], HIGH); // Ensure relays are off
    pinMode(relayPins[i], OUTPUT);
    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    C: 0");
  lcd.setCursor(0, 2);
  lcd.print("1|00:00 2|00:00");
  lcd.setCursor(0, 3);
  lcd.print("3|00:00 4|00:00");
  attachInterrupt(digitalPinToInterrupt(coinSlotPin), Add, FALLING);
}

void Add() {
  coinsInserted++;
}

void loop() {
  const uint32_t tausend = 1000UL;
  static uint32_t lastUpdateTime = 0;

  // Check for coin insertion
  if (digitalRead(coinSlotPin) ) {
    delay(800);
    lcd.setCursor(17, 1);
    lcd.print(coinsInserted > 99 ? 99 : coinsInserted);
    tone(buzzerPin, tausend, 100); // Beep the buzzer
  }

  for (int i = 0; i < 4; i++) {
    // Check buttons for starting charging
    if (coinsInserted > 0 && digitalRead(buttonPins[i]) == LOW ) {
      Relay_On(i); // Turn on the relay
      if (!relayEndTimes[i])relayEndTimes[i] = millis();
      relayEndTimes[i] +=  tausend * coinsInserted * chargeTimePerCoin ; // Set the end time for the relay based on the number of coins inserted
      coinsInserted = 0; // Reset the coin count after starting the charging
      lcd.setCursor(17, 1);
      lcd.print("0 ");
    }

    // Update relay timing
    if (relayEndTimes[i] > 0)
      if ( millis()  >= relayEndTimes[i] ) {
        RelayOff(i); // Turn off the relay
        relayEndTimes[i] = 0; // Reset the relay end time
      }
  }

  // Only update the LCD every second
  if (millis() - lastUpdateTime >= tausend) {
    char buffer[6];
    // Update only if values have changed

    for (uint8_t i = 0; i < 4; i++) {
      uint16_t remainingTime = relayEndTimes[i] > 0 ? (relayEndTimes[i] - millis()) / tausend : 0;
      uint8_t  row = i < 2 ? 2 : 3;
      uint8_t col = i % 2 == 0 ? 2 : 10;
      lcd.setCursor(col, row);

      sprintf(buffer, "%02u:%02u", remainingTime / 60, remainingTime % 60);
      lcd.print(buffer);
    }
    lastUpdateTime += tausend;
  }
}

here is the display of the lcd..i already separate the power of my relay

i think my lcd now is broken