Introduction: Convert Your POP/Drink Machine to Use RFID With Arduino

This is my first instructable so any helpful comments are appreciated. I started this project about a year ago.

I started searching on how to use arduino to control a vending machine and I found one project that without it I wouldn't have gotten anywhere. My gratitude goes out to http://www.avbrand.com and the popcard project.

So I started with a mixture between his popcard version 1 and his popcard version 2. The pop machine I have is older then his, so I had to make some changes based on that.

So my version 1 was setup as every drink was the same price, I used one relay and then when someone swiped their card, the arduino would read the card send the data to my web server, the web server would respond back with if the card was active or unknown, the users name and the amount remaining on their card. I had an admin page that I could go and add money to their card. The best part is that everytime someone buys a drink, the drink machine would email them and tell them their current amount on their card. Worked extremely well, I only had issues with how long it took the arduino to contact the webserver.

So I told a couple friends and they wanted to do the same thing, except they don't have a web server they could connect to. So, this is why I decided to start from scratch and designed version 2 & 3.

I wanted a RFID reader/ controller that was all contained within the drink machine. A way to add and update cards without having to open the machine. I also wanted to be able to assign different prices for the different drinks in the machine.

Version 3 as shown below has the following features

1) Reads the RFID tag and uses it the same as the number on the tag
2) Pricing is loaded from the SD card
3) Every RFID Tag is stored as a separate file on the SD card containing the cardnumber, emailaddress,value
4) Current Time is read in from a NTP server
5) Email is sent out to the card holder with current amount available on their card at every purchase
6) Every Friday from 4:30 - 6 PM the machine automatically goes into Free Mode and using a rfid tag will get you a free drink
7) with a tag that has been set to Admin mode - Using the drink buttons:

option 1:add money to the last scanned RFID tags account in increments of .25 -.25,1.00,-1.00, 5.00 -5.00.
option 2: set the machine into free drink mode
option 3: turn off free drink mode
option 6: reset the arduino device

8) I have also added the code for a web server, so that you can log in to the arduino and update the cards. this portion hasn't been completed yet, but the starting blocks are also included.

Version 2 and 3 use the SD card to contain all the user information, and prices for the buttons. I created an admin RFID tag that when scanned can update the last read RFID tag by using the drink buttons on the machine. The difference is Version 3 uses the network card to read in the current time, and send out emails on every purchase.

This is version 3 that I will be explaining in this instructable.

Step 1: Items to Purchase

my Parts List:

I think everything I needed was just under $100, but I purchased it over several months as I was increasing the scope of the project.

1) New Arduino Mega2560 R3 ATMEGA16U2 Ethernet Shield W5100 Kit

2) 125K RFID rdm6300 ID RF UART

3)1602 16x2 LCD Character Display + IIC/I2C/TWI

4) 40PCS Female/Female & 40 PCS Male/Famale Dupont Wire

5) 8 Channel 5v Relay (you need 7 relay channels for a 6 button drink machine)

6) computer wire, and 120 volt wire. misc connectors.

7) 100x 125Khz RFID Proximity ID Card Token Tags Key

8) 110v to USB 1 amp power supply

9) a pc speaker

10) Electrical tape

11) Wire cutters

12 Soldering Iron

13) Resistors

I will have to take some pictures of the stuff I purchased.

Step 2: Wiring Everything Together.

The 8 channel relay board - Relay side
looking at the picture shown, there the red wires are about 6" long and have a red male flat connector on the end and they replace the connection that the button on the machine use to connect to.

starting from the bottom of the picture is relay 1 which connects to the ready to vend on the vending machine as shown in the picture with the three clear wires with the yellow connectors on the end. You will need to verify with your machine which are the proper connections.

For the drink buttons you will notice that I have a clear wire that jumbers from the middle of one relay to the middle of the next one and so forth. There is only one power line and which ever button is press is the one that uses the power to signal the drink machine a button is pressed.

The 8 channel relay board - arduino side

using 10 female to male wires

Female side goes to the relay board (wrap some black tape around the connectors to hold them together in one straight line.

1 -GND (recommend black wire)
2 - Relay1
3 - Relay2
4 - Relay3
5 - Relay4
6 - Relay5
7 - Relay6
8 - Relay7
9 - Relay8 (not used)
10 - 5volt (recommend red wire)

Male side plugs into the arduino board

1 - Pin 50
2 - Pin 40
3 - Pin 41
4 - Pin 42
5 - Pin 43
6 - Pin 44
7 - Pin 45
8 - Pin 46
9 - Pin 47 (not used)
10 - joined to the 5 volt power

as shown in the code pin 40 is relay 1 used for the vend ready on the drink machine, and 41-46 is drink buttons 1 - 6

(This is the arduino code)
#define PIN_VEND_RELAY 40
int drinkPins[] = {41,42,43,44,45,46};

The Relay to replace the drink buttons

The drink buttons need a resistor added between them and ground (as shown in the picture above), to make things simple I created a ground wire soldered 6 resistors to it and then connected one side to the pins shown below and then the other side to the centre pin on the push buttons on the machine.


Drink button 1 - Pin 31
Drink button 2 - Pin 32
Drink button 3 - Pin 33
Drink button 4 - Pin 34
Drink button 5 - Pin 35
Drink button 6 - Pin 36

(This is the arduino code)
int buttonPins[] ={31,32,33,34,35,36};

The RFID connector

Female to Male
Pin 5 - Pin 2
Pin 4 - GND
Pin 1 - Pin 19

(This is the arduino code)

#define PIN_RFID_RX 19

#define PIN_RFID_RESET 2

The speaker
gnd and A4

(This is the arduino code)
#define PIN_BUZZER A2 // the piezo buzzer


The LCD screen

This code is based on the LCD screen I2C backboard that I purchased, it might have to be changed to match the one you purchase
5v to pin 3,
GND to pin GND
SDA to pin 20
SCL to pin 21

(This is the arduino code)
#define LCD_5volt 3
#define BACKLIGHT_PIN 13
LiquidCrystal_I2C lcd(0x20, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);

Step 3: The Code

The actual code will be available to download later but here are some important parts of the code

The pins are shown below. I used arrays to manage the drink buttons, this way if you have a drink machine that has more buttons, it is simple to increase the button array. I hope that in the next version, I will have a setup file to read all of these setttings in from the SD card so that the code doesn't have to be recompiled differently for each machine.

#define BACKLIGHT_PIN 13
LiquidCrystal_I2C lcd(0x20, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);

#define PIN_BUZZER A2 // the piezo buzzer
#define PIN_SDCARD 4 //do not use, sdcard uses it.
// LCD Screen
#define LCD_5volt 3
#define PIN_RFID_RX 19
#define PIN_RFID_RESET 2
#define PIN_VEND_RELAY 40

int drinkPins[] = {41,42,43,44,45,46};
int buttonPins[] ={31,32,33,34,35,36};
int buttonState[] ={0,0,0,0,0,0};
String drinkName[] = {"empty","empty","empty","empty","empty","empty"};
float drinkCost[] = {0,0,0,0,0,0}; float updateCard[] = {.25,-.25,1,-1,5,-5};
int drinkPinCount = 6;
int admintimeout = 0;

#define PIN_RESET_NET A3 // network module reset

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 0, 2);//the IP address for the shield:
IPAddress gateway( 192, 168, 0, 1 );
IPAddress subnet( 255, 255, 255, 0 );
IPAddress timeServer(132, 163, 4, 102); // time-a.timefreq.bldrdoc.gov
char emailserver[] = "192.168.0.3"; // smtp mail server (mine.com)
char emaildomain[] ="yourdomain.ca";
const int timeZone = -6; // Central Time

Step 4: Files on the Sd Card

Price file

create a file in notepad

save it as prices (the name and price will be displayed when the button is pressed on the drink machine)

1,Beer,2.00
2,Beer,2.00
3,Pepsi,1.00
4,Diet Coke,1.00
5,Dr.Pepper,1.00
6,Ginger Ale,1.00

User rfid tag

I am using our company email server so I dropped the @domain.com. If you are not using the email server then the files can automatically be added by scanning them on the machine and using the admin rfid tag to add money to it.

create a file in notepad using the 7 digits from the rfid tag and replace the 6260593.

6260593,jasit,22.00,1

using the 7 digits (ignore the zeros) save the file name.

Admin rfid tag.

create a file in notepad using the 7 digits from the rfid tag replace 6254429

6254429,admin,1,1

using the 7 digits (ignore the zeros) save the file name.

Just to explain this again. Each RFID tag gets its own file. so rfid tag 6254429 will need a file created called 6254429 inside the file is the TagID,EmailAddress,Amount, admin (1 or 0)

Any tag can be an admin tag, but if it's flagged admin, it cannot buy drinks just change settings and add money to other rfid tags.

so in the file

6254429,jasit@example.com,25.00,0

is a rfid tag that has $25 on it.

6254429,jasit@example.com,25.00,1

is a rfid tag that has admin access

Step 5: Vending a Drink

The code shown below is how a drink is actually dispersed. Once the RFID tag is read and the SD card brings back the amount remaining on the RFID tag, the machine goes into the SelectDrink sub routine. The person has 5500 milliseconds to decide/ press a drink button before the machine goes back to Ready to Scan. Once their drink is selected it then presses the opens the relay to for the readytovend and then opens the corresponding drink relay as if they pressed the button.

void SelectDrink()
{

soundOneUp();
long mil = millis();
long timer = 0;
lcd.clear();
lcd.print("Card Amt $");
lcd.print(myNewCredit);
lcd.setCursor(0,1);
lcd.print("Select a Drink");
Serial.print("Card Value $");
Serial.println(myNewCredit);
Serial.println("Select a drink");
int buttonpressed = 0;
while(buttonpressed < 1)
{
timer = millis();
for (int thisPin = 0; thisPin < drinkPinCount; thisPin++)
{
buttonState[thisPin] = digitalRead(buttonPins[thisPin]);
buttonpressed += buttonState[thisPin];
}
if(timer - mil > 5500) {buttonpressed = 1;}
}
if(timer - mil < 5500)
{
for (int thisPin = 0; thisPin < drinkPinCount; thisPin++)
{
if (buttonState[thisPin] == HIGH)
{
buzz(NOTE_C4, 8); // Startup sound
if(myNewCredit >=drinkCost[thisPin])
{
Serial.print(drinkName[thisPin]);
Serial.print(" New Credit $");
Serial.println(myNewCredit - drinkCost[thisPin]);
myNewCredit = myNewCredit - drinkCost[thisPin];
lcd.clear();
lcd.print("Card at $");
lcd.print(myNewCredit);
lcd.setCursor(0,1);
lcd.print("$");
lcd.print(drinkCost[thisPin]);
lcd.print(" ");
lcd.print(drinkName[thisPin]);
UpdateAccount();
ReadytoVend();
lcd.setCursor(0,1);
lcd.print(" Vending Drink! ");
pinMode(drinkPins[thisPin], OUTPUT);
delay(300);
digitalWrite(drinkPins[thisPin], LOW);
delay(300);
digitalWrite(drinkPins[thisPin], HIGH);
}
else
{
NotEnoughFunds();
}
}

}
}
else
{
TooktoLong();
}
}

Step 6: Simple Warnings to Remember

Please remember to unplug the drink machine before you decide to open it up.

I was consistently doing mods to my project and I accidentally touched 110 volt live wire to one of the 5 volt pins while I was settings up the drink buttons. if you zoom in you can see the burnt wire. That mistake cost me $50 in materials, I had to replace almost everything.

So remember to take your time and unplug the machine until you know all the wires are connected properly.