VENDING MACHINE
A vending machine is an automated machine that provides items such as snacks, beverages,
cigarettes, and lottery tickets to consumers after cash, a credit card,
or other forms of payment are inserted into the machine or otherwise made.
The first modern vending machines were developed in England in the early 1880s and dispensed postcards.
Vending machines exist in many countries and, in more recent times, specialized vending machines that provide
less common products compared to traditional vending machine items have been created.
more about follow here
FINAL PROJECT DESCRIPTION
my project is vending machine which has six slot that will be containning different items for celling, the project is mechanical
and electronics it has it is furnitured, plastic, acrylic glass.
in electronics controls it is composed with microcontroller, motor controller(switching mosfet), lcd display, coin detector and power supply.
HOW IT WORKS
when a user needs something from vendor, lets say a snacks, they first push a button by calling an item and will be asked to tap a card to pay and push the button again to get an item,
this button is designed and mapped with the place of the items in machine accordingly, though if this button is pressed the corresponding for example snack is going to be picked and come down by mechanism.
PROJECT PLAN AND SKETCH
for the first sketch it shows the front view of the proposed sketch design
where it shows how everything is ready and aligned on the sketch

by the sketch and planning about the project i started design it in CAD software solidworks
electronic design
for the electronic design i have used kiCad designer
and started in schematic designer

microcotroller atmega 328p section in schematic diagram

another microcontroller used as ESP32

for switching motors i have used mosfet to switch the motors

also for powering both microcontrollers there's 5v and 3.3v voltage regulators
ams1117 5 as 5v voltage regulator, and ams1117 3.3 for 3v voltage regulator
PCB designer and elctronics production
for the PCB i have opened pcb editor clicked on "update pcb button"

arranged all components on the right place and started tracing for signal and power lines

so as we expecting to see it in real world this is how 3d model looks like

for the electronics i has two parts of the projeect one is the one i introduced above as a body or controller
another one is keys or push buttons that will be used to select an items from the machine
at first i designed schematic and then the pcb

review for the circuit on the top i have vcc 5v on the low gnd so we can make the voltage divider
that may enable us to read different analog input
as it is shown in the image below the current moving as shown in the depending on pressed button

then i open pcb editor and started making arrangement of components and traces
preparing for milling
starting with saving pcb as SVG file from kicad designer so that we import SVG file as we make gcode file
opened the following to generates pcb milling file
https://mods.cba.mit.edu/
then before generating the pcb g code file this is the SVG file
.png)
then to from mods right click i scroll down find SRM-20 (my printer) under PCB SVG

i imported the image i saved as SVG clicked on invert so that the copper trace remain on top

after inverting then i click on mil traces as i am going to mill the pcb

on top i insert the diameter of tool i am goint to use for milling

on this part i set the orgin to start from 0 then after setting all those paratmeters i click on calculate to download the g code file

for more about how i prepare for pcb milling
LINK HERE from one of the recent Assignment

done soldering the whole pcb
design description

in my design i have power regulation of 5v and 3.3v with the supply voltage of 12v,
and also i have section of microcontroller where i have used two microcontrollers atmega328p and esp32
i also have switching section with six transistors that are used to switch six motors
why i chose 2 different microcontrollers
as it is seen in the project above i have six motors so to avoid conflicts in the design i have chose to use atmega328p
to control all six motors and buttons and also the esp32 doesn't have many pins i would be out of pins for esp32 only which i chose use
in my project when i was making project plan because it is powerful
so esp32 is chosen to control lcd display and RFID reader,
and also this system integration would be more easy for me to troubleshoot if there's some issues found in project and easy to relocate the problem origin
here's the integration with RFID

all circuit assembly with all devices are integrated together as shown following
all system integration

also the whole system is powered with 12v power supply
programming
for the programming codes i used arduino ide, as i have used two microcontrollers atmega328p and esp-wromm-32
as the project implies with tasks inside the project processing
the atmega328p controls dc motors and read buttons then the esp32 handdle the rest
like lcd connecting to server and reading rfid tag
the following codes are for the atmega328p
#include
int dly = 2000;
int motorStatus;
int val;
int rotdelay = 2000;
int buttonStatus;
int dl = 500;
///////////////
int m1 = 5;
int m2 = 6;
int m3 = 7;
int m4 = 8;
int m5 = 9;
int m6 = 10;
//////////////
void setup() {
pinMode(A0, INPUT);
pinMode(m1, OUTPUT);
pinMode(m2, OUTPUT);
pinMode(m3, OUTPUT);
pinMode(m4, OUTPUT);
pinMode(m5, OUTPUT);
pinMode(m6, OUTPUT);
Serial.begin(112500);
while (!Serial) continue;
}
void loop() {
/////////////button selecting///////////////
int val = analogRead(A0);
if (val >= 580 && val<= 620){
buttonStatus = 1;
serialpush();
Serial.println("button1 selected");
delay(dl);
}
if (val >= 650 && val<= 680){
buttonStatus = 2;
serialpush();
Serial.println("button2 selected");
delay(dl);
}
if (val >= 700 && val<= 715){
buttonStatus = 3;
serialpush();
Serial.println("button3 selected");
delay(dl);
}
if (val >= 760 && val<= 775){
buttonStatus = 4;
serialpush();
Serial.println("button4 selected");
delay(dl);
}
if (val >= 830 && val<= 850){
buttonStatus = 5;
serialpush();
Serial.println("button5 selected");
delay(dl);
}
if (val >= 915 && val<= 935){
buttonStatus = 6;
serialpush();
Serial.println("button6 selected");
delay(dl);
}
///////////////////////selecting and switching motors/////////////////////////////////////////
if (Serial.available()){
serialpull();
if (motorStatus== 1) {
void motor1();
}
}
if (Serial.available()){
if (motorStatus== 2) {
void motor2();
}
}
if (Serial.available()){
if (motorStatus== 3) {
void motor3();
}
}
if (Serial.available()){
if (motorStatus== 4) {
void motor4();
}
}
if (Serial.available()){
if (motorStatus== 5) {
void motor5();
}
}
if (Serial.available()){
if (motorStatus== 6) {
void motor6();
}
}
////////////////////////////////////////////////////////////////
}
void serialpush(){
StaticJsonDocument<200> doc;
doc["buttonStatus"] = buttonStatus;
// Send the JSON document over the "link" serial port
serializeJson(doc, Serial);
// Wait
delay(2000);
}
void serialpull(){
StaticJsonDocument<200> doc;
doc["motorStatus"] = motorStatus;
deserializeJson(doc, Serial);
delay(2000);
}
//////////////////////////////////////////
void motor1(){
digitalWrite(m1, HIGH);
delay(rotdelay);
digitalWrite(m1, LOW);
}
void motor2(){
digitalWrite(m2, HIGH);
delay(rotdelay);
digitalWrite(m2, LOW);
}
void motor3(){
digitalWrite(m3, HIGH);
delay(rotdelay);
digitalWrite(m3, LOW);
}
void motor4(){
digitalWrite(m4, HIGH);
delay(rotdelay);
digitalWrite(m4, LOW);
}
void motor5(){
digitalWrite(m5, HIGH);
delay(rotdelay);
digitalWrite(m5, LOW);
}
void motor6(){
digitalWrite(m6, HIGH);
delay(rotdelay);
digitalWrite(m6, LOW);
}
the following codes are for esp32
#include
#include
#include
LCD_I2C lcd(0x27, 20, 4);
#define RST_PIN 4 // Configurable, see typical pin layout above
#define SS_PIN 5 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
MFRC522::MIFARE_Key key;
#define RXp2 16
#define TXp2 17
uint32_t CardBalance = 0;
uint32_t total_cost=0;
String Card="";
uint32_t Card_Balance=0;
int progress=0, stage=0;
const unsigned long period = 1000;
float volume=0.0;
uint32_t unit_cost[]={200,300,400,500,600,700};
String item;
String prod1 = "choco";
String prod2 = "teabag";
String prod3 = "coffee";
String prod4 = "snack";
String prod5 = "candy";
String prod6 = "nut";
const char* ssid = "SOV36";
const char* password = "123456780";
String machine = "1A2B3C";
int cost;
String product;
int servstatus;
int buttonStatus;
int motorStatus;
int serdl = 60;
int32_t value;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial2.begin(115200, SERIAL_8N1, RXp2, TXp2);
WiFi.begin(ssid, password);
SPI.begin();
lcd.begin();
lcd.backlight();
mfrc522.PCD_Init(); // Init MFRC522 card
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
// Serial.println(F("tap your card"));
}
void loop() {
tap();
while (Serial2.available()){
serialpull();
while(buttonStatus!=0 || buttonStatus!=NULL){
stage=1;
Serial.println(buttonStatus);
total_cost= unit_cost[buttonStatus-1];
Serial.println("item cost= "+String(total_cost));
while(stage==1){
checkcardinfo();
}
if(CardBalance>=total_cost){
Serial.print("nice");}
else{DenielScreen();
}
buttonStatus=NULL;
motorStatus=NULL;
CardBalance=NULL;
total_cost=NULL;
}
}
}
void DenielScreen(){
Serial.println("insufficient balance");
lcd.clear();
lcd.setCursor(0,0);
lcd.print("insufficient bal");
}
void serialpush(){
Serial2.println(motorStatus);
// Wait
//delay(2000);
Serial.println("serial push stage end");
}
void serialpull(){
if (Serial2.available()){
StaticJsonDocument<300> doc;
DeserializationError err = deserializeJson(doc, Serial2);
if (err == DeserializationError::Ok)
{
buttonStatus = doc["buttonStatus"].as();
Serial.println(buttonStatus);
delay(2000);
}
}
}
void serialpull1(){
if (Serial2.available()){
Serial.println(Serial2.read());
}
}
//void cardRequest(){
//Serial.print("tap a card");
//
//
// lcd.clear();
// lcd.setCursor(2, 1);
// lcd.print("TAP CARD TO PAY");
// lcd.setCursor(5, 2);
// lcd.print(product);
//}
////////////////////////////////////////////////////////////////////////////////////
/* checking new card information and storing them */
///////////////////////////////////////////////////////////////////////////////////////
void checkcardinfo(){
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
if ( ! mfrc522.PICC_IsNewCardPresent())
return;
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial())
return;
Card="";
for (byte i = 0; i < mfrc522.uid.size; i++)
{
Card+=String(mfrc522.uid.uidByte[i],HEX);
Card.toUpperCase();
}
Serial.println ("new card = "+String(Card));
// screen();
// In this sample we use the second sector,
// that is: sector #1, covering block #4 up to and including block #7
byte sector = 1;
byte valueBlockB = 6;
byte trailerBlock = 7;
MFRC522::StatusCode status;
byte buffer[18];
byte size = sizeof(buffer);
// Authenticate using key A
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
byte trailerBuffer[] = {
255, 255, 255, 255, 255, 255, // Keep default key A
0, 0, 0,
0,
255, 255, 255, 255, 255, 255}; // Keep default key B
mfrc522.MIFARE_SetAccessBits(&trailerBuffer[6], 0, 6, 6, 3);
status = mfrc522.MIFARE_Read(trailerBlock, buffer, &size);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Read() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Check if it matches the desired access pattern already;
// because if it does, we don't need to write it again...
if ( buffer[6] != trailerBuffer[6]
|| buffer[7] != trailerBuffer[7]
|| buffer[8] != trailerBuffer[8]) {
// They don't match (yet), so write it to the PICC
Serial.println(F("Writing new sector trailer..."));
status = mfrc522.MIFARE_Write(trailerBlock, trailerBuffer, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Write() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
}
// Authenticate using key B
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Show the new value of valueBlockB
status = mfrc522.MIFARE_GetValue(valueBlockB, &value);
CardBalance=value;
if (status != MFRC522::STATUS_OK) {
Serial.print(F("mifare_GetValue() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
Serial.println("card balance = "+String(CardBalance));
Serial.println();
if(CardBalance>=total_cost){
/////////////////////////////////////////////////
status = mfrc522.MIFARE_Decrement(valueBlockB, total_cost);//rest cost
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Decrement() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
status = mfrc522.MIFARE_Transfer(valueBlockB);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Transfer() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Show the new value of valueBlockB
status = mfrc522.MIFARE_GetValue(valueBlockB, &value);
Serial.println("new balance= "+String(value));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("mifare_GetValue() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
////////////////////////////////
motorStatus=buttonStatus;
product = ("item"+String(buttonStatus));
Serial.println("motor "+String(motorStatus));
serialpush();
serialpull1();
// sendToserver();
balanceScreen();
delay(serdl);
}else{
DenielScreen();
}
mfrc522.PCD_StopCrypto1();
stage=0;
}
void tap(){
lcd.clear();
if (product == "1"){item = prod1;}
else if(product == "2"){item = prod2;}
else if(product == "3"){item = prod3;}
else if(product == "4"){item = prod4;}
else if(product == "5"){item = prod5;}
else if(product == "6"){item = prod6;}
// else {item = NULL;}
lcd.setCursor(4,1);
lcd.print("tap card");
lcd.setCursor(3,2);
lcd.print("pick a product");
lcd.setCursor(3,3);
lcd.print(item);
}
void balanceScreen(){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("balance "+String(CardBalance));
lcd.setCursor(0,1);
lcd.print("new_bal "+String(value));
lcd.setCursor(0,2);
lcd.print("card "+String(Card));
lcd.setCursor(0,3);
lcd.print("price "+String(total_cost));
delay(3000);
}
problem rising while trying to upload my codes, shows an error over and over while trying upload to the atmega328p

error
trying to look for an error i searched on internet different sites but can't find a solution
meanwhile i started checking my soldering on pcb and and connections checked but my connection was okay
so then after i realized that i forgot someting on my pcb while designing
if you noticed i forgot to connect reset pin from ISP header for programmer which is not connected from anywhere

error
i have fixed the problem and the codes uploaded successfull and also included original pcb files with fixed issues
CAD and 2D&3D design and 3d printing
for this part of the project it is CAD design for 3d and 2d design and also modeling of whole design
for inspecting the design
so i also make the assembling here where i deal with machining (cnc)
i started making 2d sketch of some parts of the case
this is the back side of the case and the holes in it is the slot of dc motors

the extruded and 3d design

and also this is the top side designed

this the 3d model if top side

and this is the side part of the case and it is also similar to the other side

the 3d view model

for the whole machine as it will be storing different items i designed the inside 2 parts to hold all items where they will be standing
so here is the sketch of it

the 3d model of inside part

and then the front cover or as a door is designed as follows this is the starting sketch

and here is the 3d model of the front door

so from this website you can find many different components model visit
www.grabcad.com
due to time availability i downloaded all models i needed from the website
the lcd display

the motors used

this is for holding motor shaft and a spiral structure

making spring

done a whole assembling
3d printing & assembly
for the motor holder i have 3d printed this structure

this is for motor shaft holder

assembled with motor