#include <Servo.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
Servo servos[4]; //servo identities
byte barLine[8] = {0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b00000, 0b00000};
#define button1 2 //----------------
#define button2 3 //| BUTTON |
#define button3 4 //| PIN NUMBERS |
#define button4 5 //----------------
#define coinSlot 6 // coin slot counter wire to pin 6
#define LED 7 // LED Anode to pin 7 for processing indicator
#define vending 8 // vendin button to pin 8
#define changeBTN 9
#define acceptBTN 10
#define settingBTN 11
#define relayRes 12
#define sensor1 50
#define sensor2 51
#define sensor3 52
#define sensor4 53
int sensorPins[] = {sensor1, sensor2, sensor3, sensor4};
//Iteam amount variables
int itemvalue1; // Replace 10 with the actual value for item #1
int itemvalue2; // Replace 20 with the actual value for item #2
int itemvalue3; // Replace 30 with the actual value for item #3
int itemvalue4; // Replace 40 with the actual value for item #4
//button selection variables
const int numItems = 4;
int itemValues[numItems] = {itemvalue1, itemvalue2, itemvalue3, itemvalue4};
int buttonPins[numItems] = {button1, button2, button3, button4};
int buttonStatus;
//coin slot variables
int coinBalance;
int pulse;
int coinSlotStatus;
int buttonPressed;
int selectedItem; // Track the selected item
bool coinsInserted = false;
//vending item variables
int vendingStatus;
boolean userBalance = false;
int setDone;
boolean settingsDone = false;
int changeBTNState;
void setup() {
// put your setup code here, to run once:
initializing();
pinMode(sensor1, INPUT_PULLUP);
pinMode(sensor2, INPUT_PULLUP);
pinMode(sensor3, INPUT_PULLUP);
pinMode(sensor4, INPUT_PULLUP);
pinMode(button1, INPUT_PULLUP);
pinMode(button2, INPUT_PULLUP);
pinMode(button3, INPUT_PULLUP);
pinMode(button4, INPUT_PULLUP);
pinMode(coinSlot, INPUT_PULLUP);
pinMode(LED, OUTPUT);
pinMode(vending, INPUT_PULLUP);
pinMode(changeBTN, INPUT_PULLUP);
pinMode(acceptBTN, INPUT_PULLUP);
pinMode(settingBTN, INPUT_PULLUP);
pinMode(relayRes, OUTPUT);
servos[0].attach(30); // Attach servo1 to pin 30
servos[1].attach(31); // Attach servo2 to pin 31
servos[2].attach(32); // Attach servo3 to pin 32
servos[3].attach(33); // Attach servo4 to pin 33
// Load item values from EEPROM
for (int i = 0; i < 4; i++) {
itemValues[i] = EEPROM.read(i); // Read from EEPROM
}
}
void loop() {
checkSensorStatus(); // Check sensor status before item selection
//Wait until one of the item buttons is pressed.
itemSelection();
//After one of the buttons is pressed, execute the LCD display.
//INSERT COIN
insertCoin();
// INSERT COINS ends here.
// VENDING the item selected
vendingItem();
// Vending done. Select item again.
settingsMenu();
}
void balanceDisplay(){
delay(1000);
char lcdBuffer[16];
sprintf(lcdBuffer, " Bal. PHP%d.00", coinBalance);
lcd.setCursor(0, 0);
lcd.print(lcdBuffer);
}
void vendingDisplay() {
lcd.clear();
LEDindicator();
delay(500);
char lcdBuffer[16];
sprintf(lcdBuffer, " Bal. PHP%d.00", coinBalance);
lcd.setCursor(0, 0);
lcd.print(" ITEM VENDED");
lcd.setCursor(0, 1);
lcd.print(lcdBuffer);
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" THANK YOU");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" SELECT ITEM");
lcd.setCursor(0, 1);
lcd.print("PRESS THE BUTTON");
LEDindicator();
}
void loading(){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" LOADING");
delay(5);
lcd.createChar(0, barLine);
lcd.setCursor(3, 1);
lcd.write(byte(0));
delay(5);
lcd.createChar(0, barLine);
lcd.setCursor(4, 1);
lcd.write(byte(0));
delay(5);
lcd.createChar(0, barLine);
lcd.setCursor(5, 1);
lcd.write(byte(0));
delay(5);
lcd.createChar(0, barLine);
lcd.setCursor(6, 1);
lcd.write(byte(0));
delay(5);
lcd.createChar(0, barLine);
lcd.setCursor(7, 1);
lcd.write(byte(0));
delay(5);
lcd.createChar(0, barLine);
lcd.setCursor(8, 1);
lcd.write(byte(0));
delay(5);
lcd.createChar(0, barLine);
lcd.setCursor(9, 1);
lcd.write(byte(0));
delay(5);
lcd.createChar(0, barLine);
lcd.setCursor(10, 1);
lcd.write(byte(0));
delay(5);
lcd.createChar(11, barLine);
lcd.setCursor(11, 1);
lcd.write(byte(0));
delay(5);
lcd.createChar(0, barLine);
lcd.setCursor(12, 1);
lcd.write(byte(0));
delay(5);
delay(1000);
digitalWrite(LED, LOW);
}
void initializing(){
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" INITIALIZNG");
lcd.setCursor(0, 1);
lcd.print(" VENDING MACH.");
delay(1000);
loading();
digitalWrite(LED, HIGH);
delay(500);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" SELECT ITEM");
lcd.setCursor(0, 1);
lcd.print("PRESS THE BUTTON");
}
void itemSelection() {
for (int i = 0; i < numItems; i++) {
int buttonStatus = digitalRead(buttonPins[i]);
int sensorStatus = digitalRead(sensorPins[i]);
if (buttonStatus == 0 && !coinsInserted && sensorStatus != LOW) {
// Check if the button is pressed, coins are not inserted, and the sensor is not LOW
buttonPressed = 1;
selectedItem = i; // Track the selected item
LEDindicator();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" ITEM #" + String(i + 1, DEC));
lcd.setCursor(0, 1);
lcd.print(" IS SELECTED");
delay(1000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" INSERT COINS");
lcd.setCursor(0, 1);
lcd.print(" PHP ");
lcd.setCursor(8, 1);
lcd.print(itemValues[i]);
balanceDisplay();
} else if (buttonStatus == 0 && sensorStatus == LOW) {
// If the sensor is LOW, indicate that the item is unavailable
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("ITEM UNAVAILABLE");
lcd.setCursor(0, 1);
lcd.print(" SELECT OTHERS");
delay(2000);
lcd.clear();
initializing(); // You can call the initializing function to return to the initial state
}
}
}
void LEDindicator(){
digitalWrite(LED, LOW);
delay(200);
digitalWrite(LED, HIGH);
delay(200);
digitalWrite(LED, LOW);
delay(200);
digitalWrite(LED, HIGH);
}
void insertCoin(){
if (buttonPressed == 1) { // If no button is pressed, coinslot is disabled.
coinSlotStatus = digitalRead(coinSlot); // wait to insert coins.
delay(30);
if (coinSlotStatus == LOW) {
digitalWrite(LED, LOW);
userBalance = true;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" COINS INSERTED");
pulse += 1;
char lcdBuffer[16];
sprintf(lcdBuffer, " Bal. PHP %d.00", pulse);
lcd.setCursor(0, 1);
lcd.print(lcdBuffer);
delay(30);
// Set the coinsInserted flag to true
coinsInserted = true;
}
}
}
void vendingItem(){
vendingStatus = digitalRead(vending);
if (vendingStatus == 0 && buttonPressed == 1 && pulse >= itemValues[selectedItem]) {
coinBalance = pulse - itemValues[selectedItem];
buttonPressed = 0;
userBalance = false;
servos[selectedItem].writeMicroseconds(2000); // rotate
delay(950);
servos[selectedItem].writeMicroseconds(1500); // stop
delay(500);
vendingDisplay();
pulse = coinBalance;
coinsInserted = false;
}
}
void tone1(){
}
void checkSensorStatus() {
for (int i = 0; i < numItems; i++) {
int buttonStatus = digitalRead(buttonPins[i]);
int sensorStatus = digitalRead(sensorPins[i]);
if (buttonStatus == 0 && sensorStatus == LOW) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("ITEM UNAVAILABLE");
lcd.setCursor(0, 1);
lcd.print(" SELECT OTHERS");
delay(2000);
lcd.clear();
initializing(); // You can call the initializing function to return to the initial state
}
}
}
void settingsMenu(){
// Wait to press settingBTN
if (digitalRead(settingBTN) == LOW) {
setDone = 1;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" SETTINGS MENU");
lcd.setCursor(0, 1);
lcd.print("CHANGE THE PRICE");
delay(1000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("CHANGE THE PRICE");
lcd.setCursor(0, 1);
displayItemValue(selectedItem + 1, itemValues[selectedItem]);
settingsDone = true;
delay(1000);
}
// After settingBTN is pressed, wait to press changeBTN
if (settingsDone == true) {
changeBTNState = digitalRead(changeBTN);
if (changeBTNState == LOW && setDone == 1) {
if (itemValues[selectedItem] < 99) {
itemValues[selectedItem] += 1;
} else {
itemValues[selectedItem] = 0; // Reset to 0 if it reaches 99
}
displayItemValue(selectedItem + 1, itemValues[selectedItem]);
delay(150);
}
}
// Press acceptBTN to finish setting an item and move to the next one
if (digitalRead(acceptBTN) == LOW && settingsDone) {
selectedItem++;
if (selectedItem >= 4) {
// All items are done, exit the settings
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" ALL SETTINGS");
lcd.setCursor(0, 1);
lcd.print(" ARE DONE");
settingsDone = false;
// Save item values to EEPROM
for (int i = 0; i < 4; i++) {
EEPROM.write(i, itemValues[i]); // Write to EEPROM
}
delay(1000);
digitalWrite(relayRes, HIGH);
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("CHANGE THE PRICE");
lcd.setCursor(0, 1);
displayItemValue(selectedItem + 1, itemValues[selectedItem]);
delay(1000);
}
}
}
void displayItemValue(int itemNumber, int itemValue) {
lcd.setCursor(0, 1);
char lcdBuffer[16];
sprintf(lcdBuffer, "ITEM %d: P%d.00", itemNumber, itemValue);
lcd.print(lcdBuffer);
}