Skip to content

Arduino Vending Machine Interface

Build a vending machine interface using Arduino with buttons for money input, snack selection, and change return.

  • Arduino
  • Intermediate
  • 60 minutes
  • 5 steps

Shop this project

Cart

Prices from vilros.com. Tax and shipping at checkout.

Before you start, you'll need

  • Arduino Uno
  • 9 push buttons
  • 16×2 LCD display
  • Breadboard
  • Jumper wires
  • 10kΩ resistors (for button pull-downs)

Plan the vending machine interface

About 5 minutes

Understand the button layout and logic.

  1. 4 buttons for money: Dollar ($1.00), Quarter ($0.25), Dime ($0.10), Nickel ($0.05).
  2. 4 buttons for snacks: Snickers ($1.25), M&Ms ($1.00), Doritos ($1.50), Gum ($0.75).
  3. 1 button for change return.
  4. LCD displays: current balance, selected item, and change due.

You should see

You understand how the interface will work.

Wire all buttons

About 20 minutes

Connect 9 buttons to Arduino digital pins.

  1. Place 9 buttons on the breadboard.
  2. Connect each button: one side to 5V through a 10kΩ pull-down resistor, other side to GND.
  3. Wire button signals to Arduino pins 2-10 (one pin per button).
  4. Button assignments: Pin 2=Dollar, 3=Quarter, 4=Dime, 5=Nickel, 6=Snickers, 7=M&Ms, 8=Doritos, 9=Gum, 10=Change Return.

You should see

All 9 buttons are wired to Arduino.

Connect the LCD display

About 10 minutes

Wire the LCD to show transaction info.

  1. Connect the LCD to Arduino (VCC→5V, GND→GND, SDA→A4, SCL→A5 for I2C).
  2. If using a parallel LCD, wire according to your specific model.

You should see

The LCD powers on and is ready to display text.

Upload the vending machine sketch

About 20 minutes

Program the Arduino to handle transactions.

  1. Open Arduino IDE and create a new sketch.
  2. Include the LiquidCrystal or LiquidCrystal_I2C library.
  3. Implement logic: track balance, check if balance is sufficient for selected item, dispense (simulate with Serial output), and calculate change.
  4. The sketch below provides a complete vending machine implementation.
cpp
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 10, 9, 8, 7);

const int btnDollar = 2;
const int btnQuarter = 3;
const int btnDime = 4;
const int btnNickel = 5;
const int btnSnickers = 6;
const int btnMMs = 7;
const int btnDoritos = 8;
const int btnGum = 9;
const int btnChange = 10;

float balance = 0.00;

void setup() {
  pinMode(btnDollar, INPUT);
  pinMode(btnQuarter, INPUT);
  pinMode(btnDime, INPUT);
  pinMode(btnNickel, INPUT);
  pinMode(btnSnickers, INPUT);
  pinMode(btnMMs, INPUT);
  pinMode(btnDoritos, INPUT);
  pinMode(btnGum, INPUT);
  pinMode(btnChange, INPUT);
  
  lcd.begin(16, 2);
  lcd.print("Vending Machine");
  delay(2000);
  updateDisplay();
  
  Serial.begin(9600);
}

void loop() {
  if (digitalRead(btnDollar) == HIGH) {
    balance += 1.00;
    updateDisplay();
    delay(300);
  }
  if (digitalRead(btnQuarter) == HIGH) {
    balance += 0.25;
    updateDisplay();
    delay(300);
  }
  if (digitalRead(btnDime) == HIGH) {
    balance += 0.10;
    updateDisplay();
    delay(300);
  }
  if (digitalRead(btnNickel) == HIGH) {
    balance += 0.05;
    updateDisplay();
    delay(300);
  }
  
  if (digitalRead(btnSnickers) == HIGH) {
    dispenseItem("Snickers", 1.25);
  }
  if (digitalRead(btnMMs) == HIGH) {
    dispenseItem("M&Ms", 1.00);
  }
  if (digitalRead(btnDoritos) == HIGH) {
    dispenseItem("Doritos", 1.50);
  }
  if (digitalRead(btnGum) == HIGH) {
    dispenseItem("Gum", 0.75);
  }
  
  if (digitalRead(btnChange) == HIGH) {
    returnChange();
  }
}

void updateDisplay() {
  lcd.clear();
  lcd.print("Balance: $");
  lcd.print(balance, 2);
}

void dispenseItem(String item, float price) {
  if (balance >= price) {
    lcd.clear();
    lcd.print("Dispensing...");
    lcd.setCursor(0, 1);
    lcd.print(item);
    Serial.println("Dispensed: " + item);
    
    balance -= price;
    delay(2000);
    
    if (balance > 0) {
      lcd.clear();
      lcd.print("Change: $");
      lcd.print(balance, 2);
      delay(2000);
    }
    balance = 0;
    updateDisplay();
  } else {
    lcd.clear();
    lcd.print("Insufficient $");
    delay(1500);
    updateDisplay();
  }
  delay(300);
}

void returnChange() {
  if (balance > 0) {
    lcd.clear();
    lcd.print("Returning $");
    lcd.print(balance, 2);
    Serial.print("Change returned: $");
    Serial.println(balance, 2);
    balance = 0;
    delay(2000);
    updateDisplay();
  }
  delay(300);
}

This uses a parallel LCD. For I2C, use LiquidCrystal_I2C library and adjust initialization.

You should see

The sketch uploads successfully.

Test the vending machine

About 5 minutes

Verify all transactions work correctly.

  1. Open Serial Monitor to see dispensing messages.
  2. Press money buttons to add to balance.
  3. Press a snack button when you have enough money.
  4. Watch the LCD show 'Dispensing...' and calculate change.
  5. Press the change return button to get money back.

You should see

The vending machine accepts money, dispenses items when balance is sufficient, and returns change.

It didn't work
  • Buttons trigger multiple times per press.

    Add debouncing: increase the delay after button reads, or implement proper software debouncing with millis().

What to do next

Stuck? Contact Vilros Support with your board model and what you see on screen.