#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); // LCD Object
#include<Servo.h> // Servo Library
Servo servo_A;
Servo servo_B;
Servo servo_C;
#define coinSlot 2
#define button 3
#define buzzer 12
#define motorA 6
#define motorB 7
//Timer variables
unsigned long motorA_on = 60000; // Time in milliseconds(ms) it takes for Motor A to be ON: 60000ms/1000 = 60 s
unsigned long delay_motorB = 2000; // Time delay in ms before turning On Motor B
unsigned long motorB_on = 5000; // Time in ms in which Motor B is on
unsigned long timeA_on;
unsigned long timeB_on;
unsigned long display_blink = 0;
unsigned long countdown_timer = 0;
//Servo timer variables
unsigned long servo_A_on = 500;
//unsigned long servo_B_on = 2000;
//unsigned long servo_AB_delay = 2000; //Time delay(ms) before Servo B moves
unsigned long servo_C_on = 10000;
unsigned long servo_timer = 0;
//Servo position variables
//---- Initial Positions ----//
int init_pos_A = 0;
int init_pos_B = 0;
int init_pos_C = 0;
//----Final positions -----//
int final_pos_A = 90;
int final_pos_B = 90;
int final_pos_C = 90;
// Coin Slot Variables
int required_amount = 30; // Amount in Pesos needed to be inserted
int inserted_amount = 0;
byte prev_pulse_state = 1;
// The coin slot send a series of pulses when a coin is detected
/* The Following illustrates the series of pulses
* ____ ____ ____ ____ ____
* | | | | | | | | | |
* | | | | | | | | | |
* | | | | | | | | | |
* | | | | | | | | | |
* ---- ---- ---- ----
* When the pulse is transitioning from HIGH to LOW (FAllING), prev_pulse_state is not equal to recent pulse and this increments the "inserted_amount" counter
*/
byte state = 0; // State of the Vending Machine
/* 0 --->> Vending Machine in Welcome Mode, display insert coin message
* 1 --->> Required amount is reached, get ready for dispensing
* 2 --->> Vending Machine in dispensing mode, Motor is running
* 3 --->> Vending operation is finished, display thank you message
*/
bool t = true; // Auxiliary variable to blink the display
bool countdown = false;
bool move_servo = false;
bool run_motor = false;
int count_num = 5 ;
void setup(){
lcd.init();
lcd.backlight();
lcd.clear();
//Servo intialization
servo_A.attach(8); //Connect servo A to digital Pin 8
servo_B.attach(9); //Connect servo A to digital Pin 9
servo_C.attach(10); //Connect servo A to digital Pin 10
//Move Servo to Initial Positions
servo_A.write(init_pos_A);
servo_B.write(init_pos_B);
servo_C.write(init_pos_C);
delay(500);
lcd.setCursor(0, 0);
lcd.print(" SUGARCANE");
lcd.setCursor(0, 1);
lcd.print("VENDNING MACHINE");
delay(2000);
lcd.clear();
//Pin Initialization
pinMode(motorA, OUTPUT);
pinMode(motorB, OUTPUT);
digitalWrite(motorA,LOW); // Turn off motor A
digitalWrite(motorB, LOW); // Turn off motor B
pinMode(button, INPUT_PULLUP);
pinMode(coinSlot,INPUT);
}
void loop(){
switch(state){
case 0:
if(inserted_amount == 0){
lcd.setCursor(0,0);
lcd.print(" PLEASE ");
lcd.setCursor(0,1);
lcd.print("INSERT COINS!!!");
}
prev_pulse_state = digitalRead(coinSlot);
delay(20);
if(!digitalRead(coinSlot)){
inserted_amount=inserted_amount+5;
tone(buzzer, 1000);
lcd.setCursor(0,0);
lcd.print(" Bal. Php: ");
lcd.print(inserted_amount);
lcd.print(".00");
delay(50);
}
noTone(buzzer);
if(inserted_amount >= required_amount ){
lcd.setCursor(0,0);
lcd.print(" Bal. Php: " + String(inserted_amount)+ ".00");
lcd.setCursor(0,1);
lcd.print("PRESS BUTTON!!!");
count_num = 5;
state = 1;
}
break;
case 1:
if(digitalRead(button) == LOW && !countdown && !run_motor){
lcd.setCursor(0,0);
lcd.print(" - GO JUICEEE! -");
lcd.setCursor(0,1);
lcd.print("Dispensing in: ");
countdown = true;
countdown_timer = millis();
move_servo = true;
servo_timer = millis();
}
if(move_servo){
if(millis()-servo_timer < 50){
servo_A.write(final_pos_A);
servo_C.write(final_pos_C);
}
if(millis()-servo_timer > servo_A_on){
servo_A.write(init_pos_A);
/*if(millis() - servo_timer > servo_A_on + servo_AB_delay){
if(millis() - servo_timer < servo_A_on + servo_AB_delay + servo_B_on){
servo_B.write(final_pos_B);
}
} */
}
/*if(millis() - servo_timer > servo_A_on + servo_AB_delay + servo_B_on){
servo_B.write(init_pos_B);
} */
if(millis()-servo_timer > servo_C_on){
servo_C.write(init_pos_C);
}
}
if(countdown){
lcd.setCursor(15,1);
lcd.print(count_num +1 );
if(count_num == 5 || millis()-countdown_timer > 1000 ){
count_num = count_num-1;
tone(buzzer,500,500);
countdown_timer = millis();
}
if(count_num < 0){
delay(1000);
countdown = false;
run_motor = true;
}
}
//Activate and Deactivate Motors
if(run_motor){
if(digitalRead(motorA) == LOW){ // If motor A is off
digitalWrite(motorA, HIGH);
timeA_on = millis();
}
if(millis() - timeA_on >= delay_motorB && millis() - timeA_on < delay_motorB+20){
digitalWrite(motorB,HIGH);
timeB_on = millis();
}
if(millis() - timeB_on >= motorB_on ){
digitalWrite(motorB, LOW); // Alloted time is reached , turn off Motor B
}
if(millis() - timeA_on >= motorA_on){
digitalWrite(motorA, LOW); // Alloted time is reached, turn off Motor A
state = 2;
}
if(millis()- display_blink >=500){
lcd.setCursor(0,0);
lcd.print("-- Dispensing --");
lcd.setCursor(0,1);
if(t){lcd.print(". . . . . . . . ");}
else {lcd.print(" . . . . . . . .");}
display_blink = millis();
t = !t;
}
}
break;
case 2:
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" THANK YOU!!!");
delay(1500);
tone(buzzer, 2000);
delay(200);
noTone(buzzer);
delay(150);
tone(buzzer, 1800,250);
delay(1500);
inserted_amount = 0;
move_servo = false;
run_motor = false;
state = 0; // ---->>> Go back to Welcome Page
break;
}
}