/**
Vendo Machine
Note: This only a test, for actual function it
needs following boards to function the 16-trays or more.
1)Adafruit_PWMServoDriver
2)Keypad_I2C
*/
//* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#include <LiquidCrystal_I2C.h>
#include <Keypad.h> // Change this if using I2C Keypad
#include <Servo.h> // Change this if using Adafruit_PWMServoDriver
#include <EEPROM.h>
Servo servo[7]; //**********************************************************
//Servo servo2; //
//Servo servo3; // Change this codes if using
//Servo servo4; // Adafruit_PWMServoDriver
//Servo servo5; //
//Servo servo6; //**********************************************************
/* Display */
//* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
LiquidCrystal_I2C lcd(0x27, 20, 4);
const unsigned long eventInterval = 60000;
unsigned long previousTime = 0;
int PriceCount=7; //Change 7 to 17 for 16-trays or just number of trays + 1
int OldPrice[7]; //Change 7 to 17 for 16-trays or just number of trays + 1
int NewPrice[7]; //Change 7 to 17 for 16-trays or just number of trays + 1
int CoinT=0; // Coin Total Deposit
int clsLCD=1; // Clear LCD toggle 1 or 0
int redLED=12;
int redSwitch=4;
int greenLED=13;
int greenSwitch=5;
long Number;
String DispStr;
int count=1;
//Elevator Constants =================================
const int dirPin = 7;
const int stepPin = 8;
const int stepsPerRevolution = 200;
const int EndStop = 6;
const int StepperEnable = 9;
//Elevator Constants =================================
/* Keypad setup */
//* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
const byte KEYPAD_ROWS = 4;
const byte KEYPAD_COLS = 4;
byte rowPins[KEYPAD_ROWS] = {8, 7, 4, 2};
byte colPins[KEYPAD_COLS] = {A3, A2, A1, A0};
char keys[KEYPAD_ROWS][KEYPAD_COLS] = {
{'1', '2', '3', 'U'},
{'4', '5', '6', 'D'},
{'7', '8', '9', 'O'},
{'.', '0', 'C', 'S'}
};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KEYPAD_ROWS, KEYPAD_COLS);
void setup() {
//for (int i = 1; i < 17; i++) //*********************sample only remove when upload
// EEPROM.write(i, i*5); //*********************sample only remove when upload
// Declare pins as Outputs and INPUTS
pinMode(EndStop, INPUT_PULLUP);
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(redLED, OUTPUT);
pinMode(redSwitch, INPUT_PULLUP); //coin registered
pinMode(greenLED, OUTPUT);
pinMode(greenSwitch, INPUT_PULLUP); //MODE 1=normal operation 0=modify prices
pinMode(StepperEnable, OUTPUT);
servo[1].attach(10);
servo[1].write(0); //***************************************************
servo[2].attach(11);
servo[2].write(0); //
//servo[3].attach(6); //
//servo[4].attach(9); // Change this codes if using
//servo[5].attach(10); //
//servo[6].attach(11); // Adafruit_PWMServoDriver
//servo[1].write(0); //
//servo[2].write(0); //
//servo[3].write(0); //
//servo[4].write(0); //
//servo[5].write(0); //
//servo[6].write(0); //***************************************************
digitalWrite(redLED,HIGH);
digitalWrite(greenLED,HIGH);
lcd.init(); // initialize the lcd
lcd.backlight();
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Please Wait...");
lcd.setCursor(0, 1);
lcd.print("Homing...");
Homing();
//lcd.clear();
//lcd.setCursor(0,0);
//lcd.print("Prices for today:");
//for (int count=1; count<PriceCount;count++){
//OldPrice[count]= EEPROM.read(count); //retrave prices stored in memory
//DispStr="Tray "+ String(count)+ " = " + String(OldPrice[count])+ " ";
//lcd.setCursor(0, 1);
//lcd.print(DispStr);
//delay(500); //************************change to 1000 for final
//}
Welcome(); // Call Function
}
void loop() {
digitalWrite(redLED, HIGH);
digitalWrite(greenLED, HIGH);
if (digitalRead(redSwitch)==LOW) {
digitalWrite(greenLED, LOW);
Homing();
ElevatorUP();
for (int count=1; count<180;count++){ // goes from 0 degrees to 180 degrees
servo[1].write(count);
delay(15); // waits 15 ms for the servo to reach the position
}
for (int count=180; count>0;count--){ // goes from 180 degrees to 0 degrees
servo[1].write(count);
delay(15); // waits 15 ms for the servo to reach the position
}
ElevatorDOWN();
//ServoMove(1);
//delay(2000);
}
if (digitalRead(greenSwitch)==LOW) {
digitalWrite(redLED, LOW);
Homing();
ElevatorUP();
for (int count=1; count<180;count++){ // goes from 0 degrees to 180 degrees
servo[2].write(count);
delay(15); // waits 15 ms for the servo to reach the position
}
for (int count=180; count>0;count--){ // goes from 180 degrees to 0 degrees
servo[2].write(count);
delay(15); // waits 15 ms for the servo to reach the position
}
ElevatorDOWN();
//ServoMove(2);
//delay(2000);
}
/*
//unsigned long currentTime = millis();
//if (currentTime - previousTime >= eventInterval) {
//Welcome(); // Call Function
//CoinT=0;
//previousTime = currentTime;
//}
//int CoinInserted = digitalRead(12);
//if (CoinInserted == LOW) {
//previousTime = currentTime;
//CoinT=CoinT+10;
//lcd.clear();
//lcd.setCursor(0,0);
//lcd.print("Inserted 10pesos");
//lcd.setCursor(0,1);
//lcd.print("Total =");
//lcd.setCursor(7,1);
//lcd.print(CoinT);
//lcd.setCursor(11,1);
//lcd.print("pesos");
//delay(400);
//}
//int PriceModify = digitalRead(13);
//if (PriceModify == LOW) {
//previousTime = currentTime;
//if (clsLCD==1){
//lcd.clear();
//clsLCD=0;
//}
//Price_Modify(); // Call Fumction
//}
else {
if (clsLCD==0){
lcd.clear();
clsLCD=1;
Welcome(); // Call Function
}
}
char key = keypad.getKey();
switch (key) {
case '1':
if (CoinT>=OldPrice[1]){
ServoMove(1);
}
previousTime = currentTime;
if (CoinT<=0){
Welcome(); // Call Function
}
break;
case '2':
if (CoinT>=OldPrice[2]){
ServoMove(2);
}
previousTime = currentTime;
if (CoinT<=0){
Welcome(); // Call Function
}
break;
case '3':
if (CoinT>=OldPrice[3]){
ServoMove(3);
}
previousTime = currentTime;
if (CoinT<=0){
Welcome(); // Call Function
}
break;
case '4':
if (CoinT>=OldPrice[4]){
ServoMove(4);
}
previousTime = currentTime;
if (CoinT<=0){
Welcome(); // Call Function
}
break;
case '5':
if (CoinT>=OldPrice[5]){
ServoMove(5);
}
previousTime = currentTime;
if (CoinT<=0){
Welcome(); // Call Function
}
break;
case '6':
if (CoinT>=OldPrice[6]){
ServoMove(6);
}
previousTime = currentTime;
if (CoinT<=0){
Welcome(); // Call Function
}
break;
}
*/
//* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
}
//********************************************
// Sub Routines //
//********************************************
//********* Welcome Sub-Routine Start ********************
void Welcome(void) {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Vendo Machine");
lcd.setCursor(0,1);
lcd.print("Pls. insert Coin!");
}
//********* Welcome Sub-Routine End **********************
//********* Price Modify Sub-Routine Start ***************
void Price_Modify() {
DispStr="Old priceT"+ String(count)+ "=" + String(OldPrice[count])+ " ";
lcd.setCursor(0,0);
lcd.print(DispStr);
//lcd.setCursor(11,0);
//lcd.print(OldPrice[count]);
lcd.setCursor(0,1);
lcd.print("New price =");
// Put value of pressed key on keypad in key variable
char key = keypad.getKey();
switch (key) {
case '1':
if (Number==0)
Number=1;
else
Number = (Number*10) + 1; //Pressed twice
lcd.setCursor(11,1);
lcd.print(Number);
break;
case '2':
if (Number==0)
Number=2;
else
Number = (Number*10) + 2; //Pressed twice
lcd.setCursor(11,1);
lcd.print(Number);
break;
case '3':
if (Number==0)
Number=3;
else
Number = (Number*10) + 3; //Pressed twice
lcd.setCursor(11,1);
lcd.print(Number);
break;
case '4':
if (Number==0)
Number=4;
else
Number = (Number*10) + 4; //Pressed twice
lcd.setCursor(11,1);
lcd.print(Number);
break;
case '5':
if (Number==0)
Number=5;
else
Number = (Number*10) + 5; //Pressed twice
lcd.setCursor(11,1);
lcd.print(Number);
break;
case '6':
if (Number==0)
Number=6;
else
Number = (Number*10) + 6; //Pressed twice
lcd.setCursor(11,1);
lcd.print(Number);
break;
case '7':
if (Number==0)
Number=7;
else
Number = (Number*10) + 7; //Pressed twice
lcd.setCursor(11,1);
lcd.print(Number);
break;
case '8':
if (Number==0)
Number=8;
else
Number = (Number*10) + 8; //Pressed twice
lcd.setCursor(11,1);
lcd.print(Number);
break;
case '9':
if (Number==0)
Number=9;
else
Number = (Number*10) + 9; //Pressed twice
lcd.setCursor(11,1);
lcd.print(Number);
break;
case '0':
if (Number==0)
Number=0;
else
Number = (Number*10) + 0; //Pressed twice
lcd.setCursor(11,1);
lcd.print(Number);
break;
case 'U': //Up or Next Tray
if (count<=15) count++;
break;
case 'D': //Down or Prevous Tray
if (count>=2)count--;
break;
case 'O': // Okay or accept
OldPrice[count]=Number;
lcd.clear();Number=0;
break;
case 'C': //Clear
lcd.clear();Number=0;
break;
case 'S': //Store to EEPROM
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Store New Price.");
lcd.setCursor(0,1);
for (int count=1; count<PriceCount;count++){
EEPROM.write(count,OldPrice[count]); //write new prices to EEPROM
DispStr="Tray "+ String(count)+ " = " + String(OldPrice[count])+ " ";
lcd.setCursor(0, 1);
lcd.print(DispStr);
delay(500);
}
lcd.clear();Number=0;count=1;
break;
}
}
//********* Price Modify Sub-Routine End ***************
//********* Sevo Move Sub-Routine Start *****************
void ServoMove(int ServoNumber) {
for (int count=1; count<180;count++){ // goes from 0 degrees to 180 degrees
servo[ServoNumber].write(count);
delay(15); // waits 15 ms for the servo to reach the position
}
for (int count=180; count>0;count--){ // goes from 180 degrees to 0 degrees
servo[ServoNumber].write(count);
delay(15); // waits 15 ms for the servo to reach the position
}
CoinT=CoinT-OldPrice[ServoNumber];
lcd.setCursor(7,1);
lcd.print(CoinT);
lcd.print(" ");
//previousTime = currentTime;
}
//********* Sevo Move Sub-Routine End *****************
//========= Stepper Move Sub-Routine Start ============
void ElevatorUP()
{
// Set motor direction clockwise
digitalWrite(dirPin, HIGH);
digitalWrite(StepperEnable, LOW);
// Spin motor slowly
for(int x = 0; x < stepsPerRevolution; x++)
{
digitalWrite(stepPin, HIGH);
delayMicroseconds(2000);
digitalWrite(stepPin, LOW);
delayMicroseconds(2000);
}
delay(1000); // Wait a second
digitalWrite(StepperEnable, HIGH);
}
void ElevatorDOWN()
{
// Set motor direction counterclockwise
digitalWrite(dirPin, LOW);
digitalWrite(StepperEnable, LOW);
// Spin motor quickly
for(int x = 0; x < stepsPerRevolution; x++)
{
digitalWrite(stepPin, HIGH);
delayMicroseconds(1000);
digitalWrite(stepPin, LOW);
delayMicroseconds(1000);
}
delay(1000); // Wait a second
digitalWrite(StepperEnable, HIGH);
}
//========= Stepper Move Sub-Routine End ==============
//********* Homming Sub-Routine Start *****************
void Homing()
{
digitalWrite(StepperEnable, LOW);
do {
//ElevatorDOWN();
digitalWrite(dirPin, LOW);
digitalWrite(stepPin, HIGH);
delayMicroseconds(2000);
digitalWrite(stepPin, LOW);
delayMicroseconds(2000);
}
while (digitalRead(EndStop)==HIGH);
digitalWrite(StepperEnable, HIGH);
}
//********* Homming Sub-Routine End *******************
//*/ //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// Include the AccelStepper Library
/* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#include <AccelStepper.h>
// Define pin connections
const int dirPin = 8; //2;
const int stepPin = 9; //3;
// Define motor interface type
#define motorInterfaceType 1
// Creates an instance
AccelStepper myStepper(motorInterfaceType, stepPin, dirPin);
void setup() {
// set the maximum speed, acceleration factor,
// initial speed and the target position
myStepper.setMaxSpeed(1000);
myStepper.setAcceleration(50);
myStepper.setSpeed(200);
myStepper.moveTo(200);
}
void loop() {
// Change direction once the motor reaches target position
if (myStepper.distanceToGo() == 0)
myStepper.moveTo(-myStepper.currentPosition());
// Move the motor one step
myStepper.run();
}
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx */
/* TEMPORARY ==================================================
// Define pin connections & motor's steps per revolution
const int dirPin = 8;
const int stepPin = 9;
const int stepsPerRevolution = 200;
void setup()
{
// Declare pins as Outputs
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
}
void loop()
{
// Set motor direction clockwise
digitalWrite(dirPin, HIGH);
// Spin motor slowly
for(int x = 0; x < stepsPerRevolution; x++)
{
digitalWrite(stepPin, HIGH);
delayMicroseconds(2000);
digitalWrite(stepPin, LOW);
delayMicroseconds(2000);
}
delay(1000); // Wait a second
// Set motor direction counterclockwise
digitalWrite(dirPin, LOW);
// Spin motor quickly
for(int x = 0; x < stepsPerRevolution; x++)
{
digitalWrite(stepPin, HIGH);
delayMicroseconds(1000);
digitalWrite(stepPin, LOW);
delayMicroseconds(1000);
}
delay(1000); // Wait a second
}
TEMPORARY ====================================================== */