Hello all! Complete newbie to programming and coding and in need of some help. I've built my own vending machine and I tried to adapt a code that I found online to fit my machine, but it doesn't seem to be working very well. The LED and the Keypad are working, but the servo motors are not (there are 4). As soon as I plug in the machine, the servo motors start going, whereas I want them to wait until one has made a selection (such as A1) on the keypad. Basically, I have zero control over the servo motors. They are 360 motors and I'm afraid they may be continuous, and if so, I'm not sure how to control that.
All I want for this machine to do is for someone to be able to make a selection, for that to trigger the servo, and therefor have the coil its attached to rotate to drop the item.
If anyone can help me fix this my stomach and I would be very grateful!
Here is a list of parts that I am using:
Arduino Mega 2560 Rev3
9VDC 1A Arduino Compatible Power Supply Adapter 110V AC 5.5 x 2.1mm Tip Positive Part#LJH -186 (For the Arduino Mega)
Breadboard
12 Volt 6 Amp Power Supply Adapter,12V 6A 72W US Plug DC Power Supply (for the breadboard)
SunFounder IIC/I2C/TWI LCD1602 Display Module
DEVMO 2PCS 4 x 4 Matrix Array 16 Key Membrane Switch Keypad Keyboard
4 MG90S Servo Micro 360° 9G Servo Motor
Here is a link to a workup of the project I did on Wokwi:
Finally, here is the code I'm trying to make work. I don't get any errors with it:
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <Servo.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
// 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] = {22, 24, 26, 28};
byte colPins[COLS] = {30, 32, 34, 36};
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
// Declare servo pins
int servoPin1 = 38;
int servoPin2 = 40;
int servoPin3 = 42;
int servoPin4 = 44;
// Create servo objects
Servo Servo1, Servo2, Servo3, Servo4;
// Global Variables
String selectedCode = "";
float selectedPrice = 0.0;
bool isServoRunning = false;
// Constants
const int numItems = 4;
struct Item {
String code;
float price;
};
Item items[numItems] = {
{"A1", 100},
{"A2", 200},
{"B3", 300},
{"B4", 500}
};
// Servo Positions
const int lockedPosition = 20;
const int unlockedPosition = 180;
// Servo Run Time (in milliseconds)
const unsigned long servoRunTime = 5000; // 5 seconds
void setup() {
// Initialize LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 1);
lcd.print("Welcome to SuperVending");
// Initialize Servo
Servo1.attach(servoPin1);
Servo2.attach(servoPin2);
Servo3.attach(servoPin3);
Servo4.attach(servoPin4);
Servo1.write(lockedPosition);
Servo2.write(lockedPosition);
Servo3.write(lockedPosition);
Servo4.write(lockedPosition);
// Reset the machine
resetMachine();
}
void loop() {
// Handle keypad input
char customKey = customKeypad.getKey();
if (customKey) {
if (customKey == '#') {
selectedCode += customKey;
} else if (customKey == '*') {
resetMachine();
lcd.clear();
lcd.print("Canceled");
delay(2000);
lcd.clear();
lcd.print("Make Your Choice");
lcd.setCursor(0, 1);
lcd.print("Item: ");
return;
} else {
selectedCode += customKey;
lcd.setCursor(7, 1);
lcd.print(selectedCode);
// Check if item selection is complete
if (selectedCode.length() == 2) {
selectedPrice = getItemPrice(selectedCode);
if (selectedPrice != 0.0) {
lcd.clear();
lcd.print("Price: $");
lcd.print(selectedPrice);
lcd.setCursor(0, 1);
} else {
lcd.clear();
lcd.print("Error");
delay(2000);
lcd.clear();
lcd.print("Make Your Choice");
lcd.setCursor(0, 1);
lcd.print("Item: ");
selectedCode = "";
}
}
}
}
}
float getItemPrice(String code) {
for (int i = 0; i < numItems; i++) {
if (items[i].code == code) {
return items[i].price;
}
}
return 0.0;
}
void processTransaction() {
lcd.clear();
lcd.print("Processing");
lcd.setCursor(0, 1);
delay(500);
lcd.clear();
lcd.print("Processing");
lcd.setCursor(0, 1);
delay(500);
lcd.clear();
lcd.print("Processing");
lcd.setCursor(0, 1);
delay(500);
lcd.clear();
lcd.print("Processing");
lcd.setCursor(0, 1);
delay(500);
lcd.clear();
lcd.print("Processing");
lcd.setCursor(0, 1);
// Check if the transaction was successful
if (selectedCode == "A1") {
lcd.clear();
lcd.print("Transaction");
lcd.setCursor(0, 1);
lcd.print("Completed!");
if (selectedCode == "A2")
lcd.clear();
lcd.print("Transaction");
lcd.setCursor(0, 1);
lcd.print("Completed!");
if (selectedCode == "B3")
lcd.clear();
lcd.print("Transaction");
lcd.setCursor(0, 1);
lcd.print("Completed!");
if (selectedCode == "B4")
lcd.clear();
lcd.print("Transaction");
lcd.setCursor(0, 1);
lcd.print("Completed!");
if (selectedCode == "A1") {
spinServo(38, 1);
}
else if (selectedCode == "A2") {
spinServo(40, 2);
}
else if (selectedCode == "B3") {
spinServo(42, 1);
}
else if (selectedCode == "B4") {
spinServo(44, 1);
}
lcd.clear();
lcd.print("Enjoy!");
delay(8000); // Wait for 8 seconds
resetMachine();
lcd.clear();
lcd.print("Please Select");
lcd.setCursor(0, 1);
lcd.print("Item: ");
}
}
void resetMachine() {
selectedCode = "";
selectedPrice = 0.0;
isServoRunning = false;
Servo1.write(lockedPosition);
stopServo();
}
void spinServo(int servoPin, unsigned long duration) {
digitalWrite(servoPin, HIGH);
isServoRunning = true;
delay(duration * 1000);
digitalWrite(servoPin, LOW);
isServoRunning = false;
}
void stopServo() {
if (isServoRunning) {
digitalWrite(servoPin1, LOW);
digitalWrite(servoPin2, LOW);
digitalWrite(servoPin3, LOW);
digitalWrite(servoPin4, LOW);
isServoRunning = false;
}
}
