#include <Wire.h>
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
Servo servos[16];
#define coinSlot 10 // coin slot counter wire to pin 6
#define LED 11 // LED Anode to pin 7 for processing indicator
#define vending 12 // vendin button to pin 8
#define relayRES 38 // use relay module to pin the reset and restart the arduino
#define relayCOIN 39 // this is to disable coin acceptor when choosing item
byte padamdam1[8] = {0b01110,0b11111,0b11111,0b11111,0b11111,0b11111,0b01110,0b01110};
byte padamdam2[8] = {0b00100,0b00000,0b00000,0b01110,0b11111,0b11111,0b11111,0b01110};
const byte ROWS = 4; // Four rows
const byte COLS = 4; // Four columns
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6}; // Connect to R1, R2, R3, R4
byte colPins[COLS] = {5, 4, 3, 2}; // Connect to C1, C2, C3, C4
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);
//Keypad Variables
char keyPressChar;
char keyPressNum;
//Prices of each items
char itemNames[4] = {'A', 'B', 'C', 'D'};
int itemPrices[4][4] = {
{5, 10, 15, 20},
{25, 30, 35, 40},
{45, 50, 55, 60},
{65, 70, 75, 80}
};
int kpadPressed;
int itemCode;
int coinSlotStatus;
int vendingStatus;
int pulse;
int coinBalance;
boolean typeKpad = false;
boolean coinsInserted = false;
boolean code = false;
boolean userBalance = false;
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" MARVIN");
lcd.setCursor(0,1);
lcd.print(" VENDO MACHINE");
delay(500);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("TYPE YOUR");
lcd.setCursor(0, 1);
lcd.print("CODE: ");
for(int servoNum = 0; servoNum < 16; servoNum++){
servos[servoNum].attach(22 + servoNum);
}
pinMode(coinSlot, INPUT_PULLUP);
pinMode(vending, INPUT_PULLUP);
pinMode(LED, OUTPUT);
pinMode(relayRES, OUTPUT);
pinMode(relayCOIN, OUTPUT);
}
void loop() {
kpadTyping();//typing in keypad process. selecting Item Label: A1-A4, B1-B4, C1-C4 and D1-D4
selectingCode(); // generate code from pressing A1 - D4
insertCoins(); // Inserting coin process
vendingProcess(); // process the item vending
// add code here for coin changer here
}
void vendingProcess(){
vendingStatus = digitalRead(vending);
if (vendingStatus == LOW) {
int itemRow = (itemCode - 1) / 4; // Determine the row in itemPrices
int itemCol = (itemCode - 1) % 4; // Determine the column in itemPrices
if (itemCode >= 1 && itemCode <= 16 && pulse >= itemPrices[itemRow][itemCol]) {
int servoIndex = itemCode - 1;
coinBalance = pulse - itemPrices[itemRow][itemCol];
servos[servoIndex].writeMicroseconds(2000); // rotate
delay(950);
servos[servoIndex].writeMicroseconds(1500); // stop
delay(500);
vendingDone();
delay(1000);
if(coinBalance == 0){
balanceDisplay1();
delay(1000);
lcd.setCursor(0,0);
lcd.print(" ITEM VENDED");
lcd.setCursor(0,1);
lcd.print(" THANK YOU");
delay(2000);
//relay module that resets the arduino MEGA 2650 thru PIN Slot
digitalWrite(relayRES, HIGH);
}else{
balanceDisplay1();
delay(1000);
coinChange();
delay(2000);
//relay module that resets the arduino MEGA 2650 thru PIN Slot
digitalWrite(relayRES, HIGH);
}
}
}
}
void insertCoins(){
if(typeKpad == true && code == true){
coinSlotStatus = digitalRead(coinSlot); // wait to insert coins.
delay(30);
if (coinSlotStatus == LOW) {
digitalWrite(LED, LOW);
userBalance = true;
lcd.clear();
lcd.setCursor(0, 1);
lcd.print(" COINS INSERTED");
pulse += 1;
char lcdBuffer[16];
sprintf(lcdBuffer, " Bal. PHP %d.00", pulse);
lcd.setCursor(0, 0);
lcd.print(lcdBuffer);
delay(30);
coinsInserted = true; // Set the coinsInserted flag to true
}
}
}
void selectingCode(){
if(!typeKpad){
void selectItem(char keyPressChar, char keyPressNum); // Declare the selectItem function
selectItem(keyPressChar, keyPressNum); // Call the selectItem function
}
if (!code){
if (keyPressChar >= 'A' && keyPressChar <= 'D' && keyPressNum >= '1' && keyPressNum <= '4') {
itemCode = (keyPressChar - 'A') * 4 + (keyPressNum - '1') + 1;
code = true;
}
digitalWrite(relayCOIN, HIGH);
digitalWrite(LED, HIGH);
}
}
void kpadTyping(){
char key = keypad.getKey();
if (!coinsInserted && !typeKpad) {Serial.println(itemCode);
if (key == '#' || key == '*' || key == '8' ||
key == '7' || key == '6' || key == '5') {
lcd.clear();
puncMarkleft();
syntaxError();
puncMarkright();
delay(1000);
digitalWrite(relayRES, HIGH);
} else if (key >= 'A' && key <= 'D') {
keyPressChar = key;
lcd.setCursor(7, 1);
lcd.print(keyPressChar);
} else if (key == '1' || key == '2' || key == '3' || key == '4') {
keyPressNum = key;
lcd.setCursor(8, 1);
lcd.print(keyPressNum);
LEDselectIndicator();
delay(500);
} else if(key == '0' || key == '9'){
itemCode = 0;
digitalWrite(relayRES, HIGH);
}
}
}
void selectItem(char keyPressChar, char keyPressNum) {
int row, col;
// Find the row and column for the selected item
for (row = 0; row < 4; row++) {
if (itemNames[row] == keyPressChar) {
for (col = 0; col < 4; col++) {
if (keyPressNum == '1' + col) {
break;
}
}
break;
}
}
// Check if a valid item was selected
if (row < 4 && col < 4) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" ITEM ");
lcd.print(keyPressChar);
lcd.print(keyPressNum);
lcd.setCursor(0, 1);
lcd.print(" IS SELECTED");
delay(1000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" PLEASE");
lcd.setCursor(0, 1);
lcd.print(" WAIT");
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(itemPrices[row][col]);
delay(1000);
balanceDisplay();
typeKpad = true;
}
}
void syntaxError(){
lcd.setCursor(2,0);
lcd.print("SYNTAX ERROR");
lcd.setCursor(3,1);
lcd.print("TYPE AGAIN");
}
void selectDisplay(){
delay(1000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("TYPE YOUR ITEM");
lcd.setCursor(0, 1);
lcd.print("CODE: ");
}
void puncMarkleft(){
lcd.createChar(0,padamdam1);
lcd.setCursor(0,0);
lcd.write(byte(0));
lcd.createChar(1,padamdam2);
lcd.setCursor(0,1);
lcd.write(byte(1));
}
void puncMarkright(){
lcd.createChar(0,padamdam1);
lcd.setCursor(15,0);
lcd.write(byte(0));
lcd.createChar(1,padamdam2);
lcd.setCursor(15,1);
lcd.write(byte(1));
}
void balanceDisplay(){
lcd.clear();
char lcdBuffer[16];
sprintf(lcdBuffer, " Bal. PHP%d.00", coinBalance);
lcd.setCursor(0, 0);
lcd.print(lcdBuffer);
}
void balanceDisplay1(){
lcd.clear();
char lcdBuffer[16];
sprintf(lcdBuffer, " Bal. PHP%d.00", coinBalance);
lcd.setCursor(0, 0);
lcd.print("REMAINNING BAL:");
lcd.setCursor(0, 1);
lcd.print(lcdBuffer);
}
void LEDselectIndicator(){
digitalWrite(LED, LOW);
delay(100);
digitalWrite(LED, HIGH);
delay(100);
digitalWrite(LED, LOW);
delay(100);
digitalWrite(LED, HIGH);
delay(100);
}
void vendingDone(){
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" ITEM VENDED");
lcd.setCursor(0,1);
lcd.print(" LOADING");
}
void coinChange(){
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" CHANGING COINS");
lcd.setCursor(0,1);
lcd.print(" PLEASE, WAIT");
delay(3000);
lcd.setCursor(0,0);
lcd.print("CHANGE DISPENSED");
lcd.setCursor(0,1);
lcd.print(" THANK YOU!");
}