// vending machine
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <Servo.h>
LiquidCrystal_I2C lcd (0x27, 16, 2);
// ---------------------------------------------------------
// Keypad Pins
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = { 9, 8, 7, 6 };
byte colPins[COLS] = { 5, 4, 3, 2 };
Keypad customKeypad = Keypad (makeKeymap (hexaKeys), rowPins, colPins, ROWS, COLS);
// ---------------------------------------------------------
struct Item {
const byte PinServo;
const char Row;
const char Col;
float price;
const char *label;
Servo servo;
}
item [] = {
{ 38, 'A', '1', 1.00, "cookie" },
{ 40, 'A', '2', 1.20, "charm" },
{ 42, 'B', '3', 0.25, "shake" },
{ 44, 'C', '7', 1.00, "candy" },
};
const int Nitem = sizeof (item)/sizeof (Item);
// ---------------------------------------------------------
const int ServoClose = 90;
const int ServoOpen = 180;
const unsigned long ServoRunTime = 5000; // 5 seconds
const char *MakeSel = "Make Selection";
char row;
char col;
// -----------------------------------------------------------------------------
void
lcdDisp (
const char *s0,
const char *s1 )
{
lcd.clear ();
lcd.print (s0);
lcd.setCursor (0, 1);
lcd.print (s1);
char s [90];
sprintf (s, "%20s // %20s", s0, s1);
Serial.println (s);
}
// -----------------------------------------------------------------------------
void setup ()
{
Serial.begin (9600);
Serial.println ("ready");
// initialize Servos
for (int n = 0; n < Nitem; n++) {
Serial.println (n);
item [n].servo.attach (item [n].PinServo);
item [n].servo.write (ServoClose);
}
// Initialize LCD
lcd.init ();
lcd.backlight ();
lcdDisp ("Welcome to", "SuperVending");
delay (3000);
reset ();;
}
// -----------------------------------------------------------------------------
void reset ()
{
row = col = 0;
lcdDisp ("Make Selection", "");
}
// -----------------------------------------------------------------------------
void processSel (
int itemIdx )
{
lcdDisp ("enjoy your", item [itemIdx].label);
item [itemIdx].servo.write (ServoOpen);
delay (ServoRunTime);
item [itemIdx].servo.write (ServoClose);
}
// -----------------------------------------------------------------------------
void checkSel ()
{
for (int n = 0; n < Nitem; n++) {
if (item [n].Row == row && item [n].Col == col) {
processSel (n);
return;
}
}
lcdDisp ("Invalid Selection", " return coins");
delay (3000);
}
// -----------------------------------------------------------------------------
void loop ()
{
// Handle keypad input
char key = customKeypad.getKey ();
if (! key)
return; // no key pressed
Serial.println (key);
char s [50];
if ('A' <= key && key <= 'F')
row = key;
else if ('0' <= key && key <= '9')
col = key;
else if ('#' == key) {
lcdDisp ("Cancel", "");
delay (3000);
reset ();
}
if (row && col) {
sprintf (s, "row %c, col %c", row, col);
lcdDisp ("Your Selection", s);
checkSel ();
reset ();
}
else {
sprintf (s, "row %c, col %c", row, col);
lcdDisp (MakeSel, s);
}
}