Final Project

The Idea

Everyone hates Vending Machines.
They are big, ugly, unreliable and ineffective pieces of metal, packed with the unhealthiest stuff we may find.
Doesn’t it sound like a good problem to solve ?

My final project is a prototype of a low-cost, fabbable and customisable Vending Machine. And also one that serves you a product, instead of throwing it at you : )

A Quick Background

I know that most initial projects either transform into something different or evolve into a more elaborate version, but, in my case, it changed completely one month ahead of the deadline.

I am starting a healthy-snack business and one of the big problems of healthy snacking is that it’s not convenient enough.

An interesting approach to increase convenience is to decrease distance and distributing the product (also) via low-cost, fabbable and highly customisable Vending Machines seemed like a perfect fit to both: the business and a final project.

Currently, there are some machines that are more modern and accept bills (with photocells or cameras that recognise the visual markings of various bills) and cards (trough and EMV system such as Nayax) and some make the product on-site, like coffee and even food like burgers and pizza, but, most vending machines are coin operated and use the same mechanism:

  • A Payment System, composed by:
    A coin slot - where coins are inserted;
    A coin ramp - with cooper coils and diodes to detect the size and material of the coins;
    A coin changer - where coins are sorted and stored;
    A coin change slot - where coins from the coin changer compartment are given as change, if needed;

  • A Storage System Composed by shelfs with spiral coils that holds products;

  • A Delivery System A motor that turns the coils and moves the product forward, making it fall from the edge of the shelf.

All systems above are connected to a motherboard.

Vending Machine prices range from $1.500 to $3.000 (FOB), depending of size and features. You can even buy them at AliBaba directly. This prototype has cost less than $ 200.

The machine I’m designing is not meant to be placed in high traffic areas and streets, it is meant to sell niche products (in my case, healthy snacks, but could be electronics or tools in FabLabs, for an instance) and will be put in selected and (mostly) supervised spaces. Due to its digital fabrication process, as opposed to industrial, the machines are meant to be low cost and should be easily customisable and replicated, meaning that smaller customer groups could be targeted at very low costs.

The idea is that these vending machines should look like a furniture, rather than a big square box, so that they could be placed, in exchange of a max. 10% return over revenues, in selected locations, according to its targeted group. In the case of healthy snacks, the niche locations would Creative Offices, Co-working spaces, Gyms, Crossfit boxes, Natural Product Shops, Design Galleries, Universities, Schools, Small Natural Supermarkets, etc.

The Production

The mechanics of the project were inspired by low-cost 3D printers like RepRap and Small CNC Machines, using a belt-motor-pulley system, but in our case to collect, transport and deliver products, vertically.

Besides serving you a product rather than throwing it at you, products are delivered on top, meaning that users no longer would have to bend and force their hands into a hand-trap like compartment.

More like this:

rather than this:

After researching many options (starting with very basic styrofoam structures to understand the flow of the tube), I have done a a pair of quick prototypes of the internal structure / shelves. The first in Cardboard and the second in thin plywood, to check the shelve’s angle and overall fit.

3D Printed Parts
We have different 3D printers (RepRaps, MakerBot Replicator and Formbytes) here at FabLab BCN and each one of them has its own characteristics when printing and some kind of difference between design size and result size. I realised the RepRaps were printing with a variation of up to 1.25 mm from the designs on the inner diameter, while the Makerbot would generate a difference of .25mm only. Since I needed to be exact on the measurements, so that my parts would fit the 8mm rods and bearings, size mattered a lot. After many attempts and design adjustments, I was able to match printing and design size nicely. I have designed the parts in Fusion 360, generated the G-code for printing with Cura and the final versions were printed at our Replicator.

CNC Milled Parts
The enclosure of the machine is made of 18mm thick plywood. For this first prototype, I didn’t want to do anything on press-fit, because it’s a big piece and I wanted to be able to quickly assemble and disassemble the enclosure for eventual internal adjustments, without needing to force the whole structure which could, eventually, bend or rip parts that are already well connected. I have designed the part is Fusion 360 and milled them at our ShopBot.

Laser Cut Parts
The shelves were created to hold kraft paper tubes, so, all calculations were made based on the size of the tubes. They slide in via the pockets in the enclosure wall and have holes, so that the motors (initially servos, but changed to steppers) could be mounted and the 3D printed pieces that hold the products in place could turn 360. The shelves are inclined 10 degrees, so that gravity could force the tubes to roll and fall on the “elevator”. I have designed these parts in Fusion 360, exported them as pdf, them imported at Rhino to distribute them and cut using our Trotec Speedy 400.

Mechanical parts
The items used to move the “elevator” are the same used in 3D printers/small CNC machines.

Electronic parts
The project uses a fabricated “Arduino” modified to integrate a WiFi ESP8226 module, plus an Arduino Uno Rev3 (pinout here) with a CNC Shield V.3 (pinout here), and Pololu DVR8825 Stepper Drivers. The sensor I planned to use at first (which the top part was design for) was a SEN0019 Infrared Sensor, but I accidentally burned it and had to quickly replace for the one that was immediately available, the HC-SR04 Ultrasonic Sensor. I have also used a 24V 15A Regulated Switching Power Supply and Nema 17 stepper motors.


Since I needed to have a master that would send G-code coordinates to my Arduino Uno+CNC Shield, also needed to add a WIFI module and needed extra pins for inputing sensors and eventually more motors, I have decided to fabricate my own “Arduino”, adapting the one from the famous “Daniele Ingrassia’s Satchakit, so that it would have extras RX, TX, Ground and VCC to permanently hold my ESP8266 WIFI module.

As usual, I designed the board in Eagle:

Generated the G-code file for the SRM-20 at fabmodules and milled it:

Here is the Pinout of the board, which I’m calling “KITANDRE” as “ANDRUINO” sounded even sillier:

I have bootloaded the board using my previously made FabISP as a programmer and it worked nicely:

And did some tests, like the “Blink” sketch from Arduino Library:

At this stage, I still had my Infrared Sensor working (before I switch to the Ultrasonic), so I also ran a test of it on the “KITANDRE” board:

Note: I had a problem with my LEDs in the board, though the board worked well, the LEDs didn’t light up, I realized it was due to the resistors (499 - possibly to strong), so I have removed them and replaced by lower ones and it worked nicely.


1 - Connect Power Supply
The most obvious and first step for running stepper motors is to provide them with a power supply. I am using a 24V 15A Regulated Switching Power Supply in this project, because I plan to run them in high feed-rates (which would require more voltage) and add more motors (which would require more amperage) in the near future. This was my first time connecting a power supply to a DC cablefrom scratch and this tutorial was very helpful.

Since I didn’t have and DC cable, I had to buy, dismantle one and find out which were the right cables to use. When you look at the front of a DC plug, you usually see signs that represent Neutral, Live and Ground.

All you need to do is test continuity between each slot in the plug and the cables behind it, so you can identify which is which.

Then, you can safely connect them to your power supply.

After connecting your power supply to power, is a good practice to measure your current to make sure all is as expected.

2 - Connect your Arduino Uno to your computer via USB
You have to know through which port your computer is communicating to Arduino, you can find out by typing ls /dev/* on terminal. It is also valid to check what you have connected through USB, by (also on terminal) typing system_profiler SPUSBDataType

3 - Compile Grbl on Arduino
Grbl is a free, open source, high performance software for controlling the motion of machines that move. Follow the instructions on this link to compile Grbl on Arduino Uno.

4 - Connect the Arduino Uno to the CNC Shield, the Drivers and power supply to your CNC Shield (Arduino Uno is powered via USB).

5 - Check the current of the stepper motors and motor drivers
We have to register the current limit that will be supplied to the motor by the stepper driver. The DRV8825 has a potentiometer that lets you regulate this setting. Here’s a detailed tutorial on how to do this and a simpler, but also helpful video.

My Nema 17 motors have a rated Current per phase of 1.7A, but the motor drivers (Pololu DVR8825 Stepper Drivers) have a maximum continuous current per phase of 1.5, so the driver will limit the current limit to 1.5.

In the DRV 8825 the Current limit = VREF x 2.
Curent Limit (1.5) = VREF x 2
VREF = 1.5 / 2
VREF = 0.75 A

This the current limit I had to set, you do this by turning the potentiometer clockwise to decrease voltage and counterclockwise to increase it.

Here’s a video of the initial current:

And the adjusted one:

6 - Install Virtual COM PORT Drivers

7 - Connect your motors! I started out connecting one motor to each axis, until I realised the CNC shield allows 4th Axis Configuration, by using two jumpers the 4th axis can be configured to clone the X or Y or Z axis. In my case, I have cloned the X as required here. But I needed to invert the axis, so that the two motors would run one clockwise and the other counterclockwise. All I had to do was to flip the stepper connector and connect it again in the same pins.

Here is part of this process documented:

8 - Microstepping
Microstepping is driving a stepper motor at less the one full step per movement. Under usual operating conditions, a stepper motor operates by turning one full step with every pulse of current. Microstepping allows a motor to make far finer steps. This done by having the controller and drive send the proper kinds of current pulses to the stepper motor. The Nema 17 motors I’m using have a relatively large step size, 1/200 of a revolution or 1.8°. The biggest advantage of microstepping is smooth operation and the elimination of resonance. I also felt that I could also be more precise in the positioning of the belt, but I learned there is no relation to it and the finer the micro step the less power you’ll have. But, I have decided anyway to microstep to 1/32, meaning that each step would represent 0.056°.

In the CNC Shield you can do this by adding a series of jumpers to the board, as described here in the Configuring Micro Stepping for Each Axis Section:

The image above was taken from this website.

9 - Configuring Grbl
I have initially thought of using Grbl because I wanted to quickly be able to test the mechanics of my project. My plan was to stream G-Code to the motors so that I could check pulleys-belt-elevator interaction and iterate accordingly. I am using Universal G-code sender to stream G-code to Grlb, it has a nice and intuitive interface. Grbl lets you configure a series of parameters, I have changed the steps/mm, the max rate and the accelaration, all to make the machine move faster, as I didn’t have to worry about other axis, once the machine is pretty much an UP and Down elevator movement. I have also added a hard limit, so that I could use endstops (explained below).

Here’s a bit of the mechanical testing I did while using Grbl:

10 - Adding endstops Unfortunately, I have not been able yet to code the endstops to create an upper limit (in the top of the machine) and a Home in the lower part of the machine. By doing this, I can “automatize” the stopping of the machine on both ends. But I have connected them to the shield and already tested them as pure physical switches. As mentioned above, I have added them hard limits. This is a quick video showing how to do it on Grlb, though the latest Grbl version (I’m using v1.1 ) does not have the same firmware menu shown in the video, which was removed to save space.

Programming and Operation

I have absolutely no previous experience with programming and my knowledge in coding is still very limited. Since I changed the final project only one month ahead of the delivery, time was also a pressing issue and I had to make things work, being very aware of the time each task would take.

So I decided to program everything with a minimal code, that could allow me to prove the concept that the whole system (3D printed parts + shelfs + motors + pulleys + belt + product release/delivery) would work.

Though this is definitely not the final version of the code (more about how I will do the final version listed in this Trello List as an issue tracker.), it helped me achieve a Minimum Viable Product, from which I now can quickly collect feedback and iterate more rapidly.

Still inspired by the way 3D printers and milling machines work, I wanted to use G-code to move the elevator to a shelves’ position, so I decided to use GRBL in the Arduino Uno and use my “Fabduino” to control the one with GRBL and the CNC Shield. Having the “Fabduino” as a master, also allowed me to have more pins available for inputing sensors and eventually more motors.


Each shelf shelf holds 7 units of one type of product and this prototype has 6 shelf slots, meaning that it can hold a maximum of 42 products/tubes. It can be easily modified to hold more products (by adding more shelves) or change the size of the tubes (by changing the shelf size) whilst keeping the same amount of motors.

Depending on the product chosen by the user (each product “line” is placed in a different shelf), the Master “KITANDRE” sends a series of G-code coordinates to the slave “ARDUINO”, which follows the coordinates via Grbl:

  • The 1st coordinate moves the 2 motors on the CNC shield marked as the X axis (both receiving the same pulse, but one turning clockwise and the other counterclockwise to support both sides of the elevator) taking the elevator for that position, slightly below the shelf where that chosen product is.

  • Then, the 2nd coordinate, makes the “Y” motor with the barrier piece that is holding the product on the shelf to turn 90 degrees, releasing the product which, due to a 10 degree inclination on the shelf, falls on the elevator “compartment”.

  • Then, after a small delay to make sure that the product fell from the shelf, a 3rd next coordinate moves the X motors up again, until it reaches the top of the machine, where the product is delivered.

  • Once the tube reaches the top, a loop makes an ultrasonic sensor read constantly the proximity of the tube. While this reading is smaller or equal to 5 cm, the program waits. If the distance increases, meaning that the product has been removed from the compartment, a new function is called and a 4th and final coordinate is sent, telling all motors to go to their 0, which makes the X motors go back to the initial position (and further on wait for a new command) and the Y motor to move back 90 degrees, “closing” the shelf.

  • In order to prevent the other tubes lined up on the shelf to fall shortly after the first is released, I planned to have a “blocking system”, composed by a 4th motor, which will hold a barrier piece (just like the one on the front of the shelf) that holds the other products in the line. After the front of the shelf is closed by the barrier piece connected to the front motor, this 4th motor will swiftly turn 360 degrees in a speed adjusted to let only one tube pass and be back on the blocking position to hold the others in the line. The 3D printed piece attached to the motor/pulley, has sharp edges, to make sure it “cuts through” the base of the tube, preventing any clogging. This hasn’t been assembled on the prototype yet, but follows the same concepts used for the rest of the operation: receives a G-code (as a Z axis, for an instance) within a series of commands sent from the code in the “KITANDRE” to the slave “ARDUINO”.

I had also to program the sensor, which is basically defining the Trig and Echo pins and adding a long variable, named “duration” for storing the travel time that you will get from the sensor and an integer variable for the distance.

I’ve setup trigPin as an output and the echoPin as an input.

Here’s the current code. The reading of the HC-SR04 ultrasonic on this sketch was based on a sketch by Dejan Nedelkovski, for

I know the hole code it’s not very elegant yet, but it served its purpose : ) and will soon be improved:


   The reading of the HC-SR04 ultrasonic on this sketch was based on a sketch by Dejan Nedelkovski, for

    //Setup the variables for the HC-SR04

    const int trigPin = 9;

    const int echoPin = 10;

    void setup() {

     // initialise serial communication:






    void loop(){



     void goShelf1(){

       Serial.print("G0 X5\r\n"); //send the string "hello" and return the length of the string.
       Serial.print("G0 Y1.5\r\n"); //send the string "hello" and return the length of the string.
       Serial.print("G4 P1.0\r\n"); //send the string "hello" and return the length of the string.
       Serial.print("G0 x126\r\n"); //send the string "hello" and return the length of the string.

    void goShelf2(){

       Serial.print("G0 X20\r\n"); //send the string "hello" and return the length of the string.
       Serial.print("G0 Y1.5\r\n"); //send the string "hello" and return the length of the string.
       Serial.print("G4 P1.0\r\n"); //send the string "hello" and return the length of the string.
       Serial.print("G0 x115\r\n"); //send the string "hello" and return the length of the string.

    void goHome(){

       Serial.print("G0 Y0\r\n"); //send the string "hello" and return the length of the string.
       Serial.print("G0 X0\r\n"); //send the string "hello" and return the length of the string.

    void readSensor(){

      // establish variables for duration of the ping,
      // and the distance result in inches and centimeters:
      long duration, inches, cm;

      // The sensor is triggered by a HIGH pulse of 10 or
      // more microseconds.
      // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:

      pinMode(trigPin, OUTPUT);
      digitalWrite(trigPin, LOW);
      digitalWrite(trigPin, HIGH);
      digitalWrite(trigPin, LOW);

      // Read the signal from the sensor: a HIGH pulse whose
      // duration is the time (in microseconds) from the sending
      // of the ping to the reception of its echo off of an object.
      pinMode(echoPin, INPUT);
      duration = pulseIn(echoPin, HIGH);

      // convert the time into a distance
      inches = microsecondsToInches(duration);
      cm = microsecondsToCentimeters(duration);

      // This if-else statement tells the Arduino at what distance
      // it should trigger the function,
      // and what it should do if the distance is too far away.

      if (cm >= 5) {
      else  {
      // Tell the Arduino to wait 1 second before pinging the
     // Ultrasonic Sensor again.


    // Converts the microseconds reading to Inches

    long microsecondsToInches(long microseconds)


     // According to Parallax's datasheet for the PING))), there are

     // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per

     // second). This gives the distance travelled by the ping, outbound

     // and return, so we divide by 2 to get the distance of the obstacle.

     // See:

     return microseconds / 74 / 2;


    //Converts the Microseconds Reading to Centimeters

    long microsecondsToCentimeters(long microseconds)


     // The speed of sound is 340 m/s or 29 microseconds per centimeter.

     // The ping travels out and back, so to find the distance of the

     // object we take half of the distance travelled.

     return microseconds / 29 / 2;

Vinyl Cut Parts
Once I had finished the prototype, it looked too minimalist, like a mysterious box ! So, even though I am still developing the company’s brand identity, I have decided to add the temporary logo I had previously created on photoshop (it’s simply a name typed in the chosen font).

Since I don’t have illustrator in my computer, I had to convert the layers into work paths (right-click on the selected layer > Convert to work path), in order to export the paths from photoshop to illustrator (Export > Paths to Illustrator), to generate the .svg file read by Roland’s CutStudio.

After making each layer a work path on photoshop, I have exported them as paths to illustrator individually, generating the .ai files. Then, I joined the layers in a friend’s Illustrator and exported the file as an .svg.

In Inkscape (the same machine that has Inkscape has the Cutstudio here, otherwise it could be done directly from the Illustrator to the CutStudio) I have copied and pasted to CutStudio. The first time I copied the path, the borders looked pixelated, so, a trick to fix this is to resize the path in Inkscape until it’s quite big and only then copy-paste to CutStudio, which solved the problem.

The vinyl cutter we have at the lab is the Roland GS-24 and the steps to cut were:

Put the vinyl in the cutter;
Align and pull the lever down;
Choose “Piece” from the “Select Sheet” menu (the machine measures the length and width of your sheet);
Import or copy the .svg file at Cut Studio;
Go to File> Cutting Setup > Properties > Cutting Area > Get from Machine , which gives you the canvas of the actual piece o vinyl measured by the machine, so that you can position your path according to the sheet size; Press “Cutting”.

Here’s the video of the cutting:

I couldn’t find and actual transfer in the lab, so the solution was to, after carefully removing the material that surrounded my vinyl cut letters, I have used masking tape to transfer it to the top of the prototype.

Complete BOM

Item  Quantity Price Total
Nema 17 Stepper Motor 3 12 36
DRV8825 GRBL Stepper Motor Driver 3 2.4 7.2
CNC Shield v3 1 10 10
Cable AC 1 6 6
24V 15A Power Supply 1 15.5 15.5
6mm Belt (5 meters) 1 10.99 10.99
Arduino Uno Board Rev. 3 1 25 25
8mm Calibrated Steel Rods 4 7.5 30
Dented Pulleys 4 1.8 7.2
Right Angle 30x30mm Brackets 2 1 2
TXRX ESP8266 Wifi Module 1 6 6
HC-SR04 Ultrasonic Sensor 1 2.95 2.95
8mm Bearings 4 0.75 3
Screws, Nuts, Wires 1 10 10
18mm Plywood Board (1250 X 2500) 1 15.11 15.11
    Total: 186.95 Euros

What’s next?

Since this is a first prototype, there are many things that should and will be evolved. I have been keeping track of a list of improvements and adjustments in this Trello List as an issue tracker.

In terms of future opportunities, I believe this project has many potential uses. Automated machines like this can be used for distributing many things, with almost none adaptation. The fact that it is based on a tube, tubes of different sizes could be used, adapting mostly the shelf and enclosure sizes, without interfering much in the electronics and mechanical parts. FabLabs could use it to sell or distribute electronic components or tools that are recurrently used by students.

And finally, here’s me presenting the project to Neil, at 2 AM (Barcelona Time). You can notice how sleepy I am!

All files used in the fabrication of this project can be found here.

This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.