// 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] = {
{'D', '#', '0', '*'},
{'C', '9', '8', '7'},
{'B', '6', '5', '4'},
{'A', '3', '2', '1'}
};
#if 0
byte rowPins[ROWS] = {22, 24, 26, 28};
byte colPins[COLS] = {30, 32, 34, 36};
#else
byte colPins[ROWS] = {22, 24, 26, 28};
byte rowPins[COLS] = {30, 32, 34, 36};
#endif
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);
}
// -----------------------------------------------------------------------------
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 ("Welcome to SuperVending", "");
}
// -----------------------------------------------------------------------------
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) {
Serial.print("pressed key=");
Serial.println(key);
}
if (! key)
return; // no key pressed
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);
}
}