Project tutorial
Raspberry Pi - Powered Candy Dispenser

Raspberry Pi - Powered Candy Dispenser © GPL3+

Make a candy machine that can give candy with a push of a button or a tweet!

  • 5,648 views
  • 1 comment
  • 12 respects

Components and supplies

Necessary tools and machines

CNC Router
3drag
3D Printer (generic)
09507 01
Soldering iron (generic)

Apps and online services

Ide web
Arduino IDE
Enthought Canopy (Python IDE)
Autodesk fusion 360 logo 4szx21llea
Autodesk Fusion 360

About this project

The aim of this project was to improve on my previous candy dispenser by making a new one that is more interactive and aesthetically pleasing.

Video:

A Little Background

In early May I published a project documenting my building and usage of a candy dispenser that I had built as part of being a beta tester for the Google AIY Projects Kit. It was well received, garnering about 3 thousand views in just 2 weeks, and 4 articles being written on it.

Overall, it was a worthwhile and successful project, but I wasn’t satisfied. The Maker Community can be summed up with this saying: “Have an idea, create the product, and innovate on it.” I decided that a basic box with limited functionality was nowhere near as exciting as it needed to be. So I set out to build a better, smarter, and more connected machine. This time it would be a lot easier, as I had just finished building a new CNC router (the MillRight CNC M3 kit), which would enable me to create much more precise parts with a higher degree of aesthetics and accuracy, rather than using a jigsaw.

Designing the Machine

Up to this point, I have had quite a bit of experience with my favorite CAD program- Fusion 360. It has everything a maker needs in its workflow to go from an idea to a finished part in CAM. I knew I would have to build something sleeker and more modern, along with using fewer parts. I started out with making a simple box, and finding out how I should arrange a button and LCD to allow for user interaction.

Next was finding the right board to use for running it. I decided upon using a Raspberry Pi Zero W due to its small size and wireless capabilities.

I also chose to use a stepper motor to drive a paddle which would dispense wrapped candy from a funnel. Next, I thought to myself: “How do I add an interesting way to interact with this device?” I had already used Google Assistant, so why not use Twitter? The latest tweet shows up on the LCD, along with whom it’s from. Now that I have a design, it’s time to start building it!

Manufacturing the Parts

The first step in creating a part is making sure it will fit. My design fits in a 10.5 inch cube (26.67 cm),which is the maximum size my router can handle. To generate the gcode I used the CAM environment that is built into Fusion 360. I created a setup for each part, setting my stock to be 266.7mm by 266.7mm and 20mm thick. I did this because my material is ¼ inch thick (6.35mm), therefore ensuring that the bit will cut all the way through. After generating a setup, I then configured the path for cutting out the part. I chose a 2d contour and set the speed to 18000 rpm because I was using the DeWalt DWP611 Router. There are more settings as well but I won’t go into that. For more information go to the resources page here: https://www.millrightcnc.com/resources

To get the parts go to: https://gallery.autodesk.com/projects/99462/candy-dispenser-2 to view and download the parts for CNC routing.

I cut out the pieces and sanded them down thoroughly, ensuring I wouldn’t get any splinters and the paint would stick. Next, I coated the outer pieces with 2 coats of sprayable shellac, and then sanded once more to even out the surfaces. Finally, I gave each piece three coats of laquer spray paint. I painted the box part white, and the funnel black.

I also 3D printed a paddle for the stepper motor and a button that slots into the front plate.

You can find those designs here: https://www.thingiverse.com/thing:2426514

Software and Hardware

Because I had chosen to use the Raspberry Pi Zero W in my project, I had to set it up first. To accomplish that, I wrote the latest Raspbian Jessie with PIXEL (https://www.raspberrypi.org/downloads/) onto a 16GB SD card. Then I booted up the Raspberry Pi and waited for the green light to go solid (all files had been written). I shut down the board and removed the SD card, inserting it into a computer running Linux (so I could see all of the files on the ext4 filesystem). To enable SSH I made a blank file (NO extensions) and named it “ssh”, and I also created a new text file called “wpa_supplican.conf”. In it I put:

network={ssid="SSID"     psk="PASSWORD"     key_mgmt=WPA-PSK }

Now, reboot the Raspberry Pi Zero W and SSH into it. Enter:

sudo raspi-config

and enable VNC and UART. Exit and reboot it again. Now, SSH and enter vncserver then sudo startx . Exit out of that session and open VNC Viewer on your PC. You are now completely set up and ready to run some code!

Start by downloading the files I included, which includes the “main.py” file. Run

sudo apt-get update

and then

sudo apt-get install build-essential python-dev python-smbus python-pip git

Make sure RPi.GPIO is installed with

sudo python2 -m pip install 

Next install the LCD library by running:

cd ~
git clone https://github.com/adafruit/Adafruit_Python_CharLCD.git
cd Adafruit_Python_CharLCD
sudo python2 setup.py install

Then, go to https://apps.twitter.com and create a new app. Put in the name, description, and a phony website. Next, go to the “Keys and Access Tokens” section, and generate the oauth access tokens. Paste those into in the order of: Consumer Key, Consumer Secret, Access Token, and finally Access Token Secret.

Now that the software side is done, it is time to wire everything together. Start by connecting the LCD to the Pi.

Pi (BCM Pin Mapping)  |   LCD
27  |  RS
22  |  EN
25  |  D4
24  |  D5
23  |  D6
18  |  D7
4   |  Backlight (not used) 
Potentiometer Wiper (middle pin)  |  V0 (contrast)
+5v  |  VDD, Backlight +, Potentiometer +
GND  |  VSS, R/W, Backlight -, Potentiometer -

Connect a pushbutton (tact switch) to Pi pin 5 and GND, along with a common cathode RGB LED. Red: 16, Green: 20, Blue: 21. Also attach an Arduino Nano’s GND to the Pi’s GND, along with a jumper going from Pi UART Tx (pin 14) to the Nano’s Rx.

For the stepper motor, connect coil pair A to l293d outputs 1 and 2. Connect pair B to outputs 3 and 4. Attach inputs 1,2,3,4 to the Nano’s pins 8,9,10,11, along with connecting their GNDs. Get a 12v power supply (I used a 12v adapter with a DC barrel jack) and connect it to both the l293d and VIn, along with its GND going to the Nano and the driver. That’s it! Now the wiring is now complete.

Putting It All Together

Go ahead and assemble the parts together. I used screws and wooden blocks to secure the parts together, and it enables for the machine to be taken apart easily.

Now, you can tweet at it: “@(your Twitter app handle) (a phrase with ‘color’ and ‘red’, ‘green’ or ‘blue’)” to change the color of the LED, or just tweet anything!

Push the button to rotate the inside paddle to dispense candy. Have fun with your new Raspberry Pi Powered Candy Dispenser.

Code

Arduino Nano codeArduino
#include <Stepper.h>

const int stepsPerRevolution = 200;

Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);

void setup() {
myStepper.setSpeed(30);
Serial.begin(115200);
}

void loop() {
  if(Serial.available()>0){
    char data = Serial.read();
    if (data == 'c'){
      Serial.println("Giving candy!");
      myStepper.step(50);
    }
  }

}
Raspberry Pi CodePython
Copy and paste your Twitter app credentials
#import libraries
from twython import Twython
from time import sleep
import math
import time
import serial
import Adafruit_CharLCD as LCD
import RPi.GPIO as GPIO

#setup pin numbers
lcd_rs        = 27
lcd_en        = 22
lcd_d4        = 25
lcd_d5        = 24
lcd_d6        = 23
lcd_d7        = 18
lcd_backlight = 4

#LCD dimensions
lcd_columns = 20
lcd_rows    = 4

#make an LCD object with our pin variables
lcd = LCD.Adafruit_CharLCD(lcd_rs, lcd_en, lcd_d4, lcd_d5, lcd_d6, lcd_d7, 
                           lcd_columns, lcd_rows, lcd_backlight)
                           
#RGB LED pin numbers                         
redP = 16
greenP = 20
blueP = 21
buttonP = 5 #Tact switch pin number
ser = serial.Serial(port='/dev/ttyS0',baudrate=115200,timeout=1) #create a serial object for UART communication
pin_list = [redP,greenP,blueP] #put RGB LED pins in an array (simpler to control)
GPIO.setmode(GPIO.BCM) #BCM pin numbering for GPIO
GPIO.setwarnings(False) #Don't give a warning on startup about GPIO
for pin in pin_list: #Make every pin an output
    GPIO.setup(pin, GPIO.OUT)
    
GPIO.setup(buttonP, GPIO.IN, pull_up_down=GPIO.PUD_UP) #make button pin detect a FALLING edge (pull up resistor)

prev_message = "" #make a previous message variable to detect duplicate tweets

def reset_lcd(): #make a function that will clear the LCD
    lcd.clear()
    lcd.home()
    
#create out Twitter app variables
APP_KEY = "KEY"
APP_SECRET = "SECRET"
OAUTH_TOKEN = "TOKEN"
OAUTH_TOKEN_SECRET = "TOKEN_SECRET"

#make a twitter object with out variables
twitter = Twython(APP_KEY, APP_SECRET,
                  OAUTH_TOKEN, OAUTH_TOKEN_SECRET)

#turn off all LED colors
def all_off():
    for pin in pin_list:
        GPIO.output(pin,GPIO.LOW)
        
all_off() #turn off the LED

def candy_dispense(channel): #This will send the command to the Arduino Nano to dispense candy
    reset_lcd()
    lcd.message("Dispensing candy\nBe sure to say\n'Trick-or-treat'!")
    ser.write('c')
    sleep(5)
    reset_lcd()

GPIO.add_event_detect(buttonP, GPIO.FALLING, callback=candy_dispense,bouncetime=300) #add an interrupt that will call candy_dispense

while 1: #infinite loop
    tweet = twitter.get_mentions_timeline()[0] #get the latest tweet in which you are mentioned
    
    reset_lcd() #clear the LCD
    
    print "Latest tweet: "+tweet['text']+"\n\n" #print latest wteet to console
    text_len = len(tweet['text']) #get the length of the tweet
    #make the text fit in a 20x4 space
    if text_len < 20:
        lcd.message(tweet['text'])
    elif text_len > 20 and text_len < 41:
        lcd.message(tweet['text'][0:20]+'\n'+tweet['text'][20:40])
    elif text_len > 20 and text_len < 61:
        lcd.message(tweet['text'][0:20]+'\n'+tweet['text'][20:40]+'\n'+tweet['text'][40:60])
    elif text_len > 20 and text_len < 81:
        lcd.message(tweet['text'][0:20]+'\n'+tweet['text'][20:40]+'\n'+tweet['text'][40:60] \
       + '\n'+ tweet['text'][60:80])                                                                                                

    if prev_message != tweet['text']:
        #check if "color" and which color were mentioned in tweet (will change           the LED color)
        if "color" in tweet['text'].lower():
            if "red" in tweet['text'].lower():
                all_off()
                GPIO.output(redP,GPIO.HIGH)
            elif "green" in tweet['text'].lower():
                all_off()
                GPIO.output(greenP,GPIO.HIGH)
            elif "blue" in tweet['text'].lower():
                all_off()
                GPIO.output(blueP,GPIO.HIGH)
            if "off" in tweet['text'].lower():
                all_off()
            
    #if the word "candy" appears in the tweet, give out candy
        if "candy" in tweet['text'].lower():
            reset_lcd()
            lcd.message("Dispensing candy\nBe sure to say\n'Trick-or-treat'!")
            ser.write('c')
            sleep(2)
            
            
    sleep(10) #pause for 10 seconds (You can only update the tweet every 20 seconds due to Twitter query limits)
    reset_lcd() #clear the LCD
    #say who it's from and when it will update again
    lcd.message("From user: \n@"+tweet['user']['screen_name']+"\n"+
                "This will update in\n20 seconds.")
    print "From user: \n@"+tweet['user']['screen_name']+"\nThis will update every 20 seconds\n--------------------------------------\n"
    sleep(10) #pause for 10 more seconds
    prev_message = tweet['text'] #make the previous message the current one (to check for a duplicate tweet)
    

Custom parts and enclosures

Rotating Candy Mover
Attach to stepper motor
Button
Slot into front plate

Schematics

Schematic
Schematic bb vals7ynooa

Comments

Similar projects you might like

Candy Dispenser with Google Assistant

Project tutorial by Arduino “having11” Guy

  • 15,482 views
  • 1 comment
  • 51 respects

WW2 Tank Laser Tag Sherman & Panther

Project tutorial by Arduino “having11” Guy

  • 16,352 views
  • 1 comment
  • 57 respects

Laser Pointer Panther Tank

Project tutorial by Arduino “having11” Guy

  • 5,269 views
  • 1 comment
  • 12 respects

Candy Dispenser

Project tutorial by Hada Amira

  • 7,684 views
  • 7 comments
  • 24 respects

DIY 3-Axis CNC VMC

Project tutorial by Amit Nandi (BigWiz)

  • 12,167 views
  • 9 comments
  • 46 respects

Arduino 101 Connects with Raspberry Pi Zero W

Project tutorial by Alexis Santiago Allende

  • 8,419 views
  • 0 comments
  • 17 respects
Add projectSign up / Login