Project tutorial

Candy Dispenser with Google Assistant © GPL3+

By using IFTTT, the Google Assistant API, and a Particle Photon, you can make a machine that gives out candy upon your request!

  • 8,716 views
  • 0 comments
  • 33 respects

Components and supplies

Necessary tools and machines

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

Apps and online services

Ide web
Arduino IDE
IFTTT Assistant Service
Particle Photon Build IDE
Logo assistant kvfq4j72g6 yciz8pmvwr
Google Assistant SDK

About this project

The Project

This is a comprehensive guide for building and using my Google Assistant Powered Candy Machine. It can be split up into these parts:

  • Making and Using the Raspberry Pi with Google Assistant
  • Coding and Setting up the Particle Photon
  • Making an IFTTT Applet
  • Creating the Wooden Box and the Mechanical Parts
  • Coding the Arduino Mega 2560
  • Installing the Electronics
  • Testing and Usage

Here is a short demonstration video:

Making and Using the Raspberry Pi with Google Assistant

First, I had to set up my Google Assistant. I don't have a fancy new Android phone that comes with it, nor do I want to go online to query the API. Thankfully, the wonderful people at Google have engineered a solution. They created an SDK in Python that can run as a service on the Raspberry Pi. Bundled with the Voice HAT and a mic array, along with a speaker and button, it is now possible to either clap or push the button to speak to the Google Assistant. I have been beta testing this device for about 2 months now, and it works very well. All you need to do is plug in the microphone sensor and button, as shown here:

After that, load the python files and run the service after adding your API credentials and the API to a new project in the Google Developers Cloud. Now, whenever you push the button or clap (with the right setup) you should be able to say "hello" and it will respond.

Coding and Setting Up the Particle Photon

The first step to making your Particle Photon talk is creating a new project in the Particle build IDE. After it is created, copy and paste the provided code into the IDE. Save it and then flash it to your Photon. Now in the Particle Console you should be able to call the function and make the light blink. If that works, you are ready to create the IFTTT applet.

Making an IFTTT Applet

The first step is to head on over to ifttt.com and sign in.

Then, click on "My Applets" and make a new applet. Go ahead and select the "this" part.

Now, select the Google Assistant service and choose "Say a simple phrase". Put whatever you want in the fields. I chose "Give me some candy", "I want some candy", and "Can I have some candy?" for my queries. For the response I set it to say "Follow the on screen instructions to receive your treat."

Now for the "that" portion of your applet. Choose the Particle service and make it call a function. Choose the "give_candy" function on your device and set 200 for the input.

That should be it for the applet. To test it, say your phrase into Google Assistant and see if the light blinks on your Photon. If it does, well done!

Creating the Box and Mechanical Parts

This is the longest part of the project. It took me about 2 days to create, but it should be shorter for you because everything has been figured out by myself already.

First, 3D print all of the parts. You will need 1 auger (the 2 halves glued together), and then 2 of each- the button holder, the button, and the switch holder. After printing, assemble the buttons with the tact switches and make sure they work. Solder on wires with 10k pulldown resistors to complete the button assembly.

Lay Out Components

I laid out my components and the cardboard prototype for reference.

Create Dispenser

Now for the difficult part- creating the actual dispenser. I used about one piece of 2'x2'x.5" plywood for the structure. Here are some of the parts drawn out:

Build

I then cut the wooden pieces out and screwed them together to form a basic box. The front wall had an LCD cutout and two places for the buttons.

I attached the auger to the servo, slipped the 1.5" PVC pipe T joint on it, and then screwed the servo onto the wall. I also attached a hinge and a door to the side so that everything in the back can be easily accessed.

I took a protein shake mixing bottle and cut a 1.25" hole into the bottom so it would line up with the top of the PVC pipe. It is also removable.

I then spray painted the dispenser black.

To keep it from scratching tables I added four rubber feet on the bottom of it.

That is the actual box finished.

Coding the Arduino Mega 2560

You can just copy and paste the provided code into the Arduino IDE and upload it to the board.

Installing the Electronics

Installation is fairly easy. I just hot glued the two perf board pieces and each component in place. In my build the electronics look very messy, but it is not a big deal, as the back panel covers it all up. Make sure the Particle Photon isn't blocked by any metal, as the metal can act as an RF shield, blocking the WiFi signal.

Testing and Usage

Now that the dispenser is completed, the Photon works, and the Google Assistant responds, it's time to test it. Just say your command, select an option from the LCD, and watch the auger turn.

Lastly, here is a quick video that explains each part.

Custom parts and enclosures

This is from Thingiverse for the Automated Cat Feeder: http://www.thingiverse.com/thing:27854 You will need a 1.5" T-joint PVC pipe as well.
Button Holder
This holds the actual button in place.
Button
This slides into the button holder piece. It is what the user presses. Make sure it can slide freely.
Switch Holder
It attaches on the side of the button holder and the tact switch is mounted on it.

Schematics

Schematic
Connect as-is. Sorry if it's messy.
Schematic bb 2ok5rjtgon

Code

Arduino Mega CodeC/C++
Copy and Paste for the Arduino Mega.
#include <Wire.h>
#include <SparkFun_APDS9960.h>
#include <LiquidCrystal.h>
#include <Servo.h>

#define LARGE_AMOUNT 4000 //time to dispense candy in ms
#define SMALL_AMOUNT 2500

LiquidCrystal lcd(12,11,5,4,3,2);

Servo auger;

SparkFun_APDS9960 apds = SparkFun_APDS9960();

uint8_t proximity_data = 0;
int LB = 6;
int RB = 7;
bool LBS = false;
bool RBS = false;
int candy_amount = 0;

void setup(){
	if ( apds.init() ) {
    Serial.println(F("APDS-9960 initialization complete"));
  } else {
    Serial.println(F("Something went wrong during APDS-9960 init!"));
  }
  if ( !apds.setProximityGain(PGAIN_2X) ) {
    Serial.println(F("Something went wrong trying to set PGAIN"));
  }
  if ( apds.enableProximitySensor(false) ) {
    Serial.println(F("Proximity sensor is now running"));
  } else {
    Serial.println(F("Something went wrong during sensor init!"));
  }
  lcd.begin(16,2);
  lcd_reset();
  lcd.print("Initializing");
  auger.attach(9);
  pinMode(LB, INPUT);
  pinMode(RB, INPUT);
  Serial.begin(9600);
  delay(5000);
  lcd_reset();
  lcd.print("Running");
  delay(4000);
  lcd_reset();
	lcd.print("Google Powered");
  lcd.setCursor(0,1);
  lcd.print("Candy Dispenser");
  auger.write(90);
  auger.detach();
}

void loop(){
  int state = analogRead(A0);
  LBS = digitalRead(LB);
  RBS = digitalRead(RB);
  
	if (state > 60 || LBS == true || RBS == true){
  Serial.println("active");
  Serial.print(LBS);
  Serial.print(",");
  Serial.println(RBS);
  LBS = false;
  RBS = false;
  delay(1000);
  lcd_reset();
    lcd.print("How much candy?");
    lcd.setCursor(0,1);
    lcd.print("A Little   A LOT");
    while(LBS == false && RBS == false){
      LBS = digitalRead(LB);
      RBS = digitalRead(RB);
    }
    if(LBS){
      candy_amount = SMALL_AMOUNT;
    }
    else if(RBS){
      candy_amount = LARGE_AMOUNT;
    }
  while(proximity_data != 255){
  if ( !apds.readProximity(proximity_data) ) {
    Serial.println("Error reading proximity value");
  } else {
    
    lcd_reset();
    lcd.print("Waiting for cup");
    lcd.setCursor(0,1);
    lcd.print("Distance: ");
    lcd.print(proximity_data);
  }
  delay(400);
  }
  lcd_reset();
  lcd.print("Cup found!");
  delay(1000);
  
  for(int x=5;x>0;x--){
    if ( !apds.readProximity(proximity_data) ) {
    Serial.println("Error reading proximity value");
  } else {}
    if(proximity_data != 255){
      lcd_reset();
      lcd.print("Please replace");
      lcd.setCursor(0,1);
      lcd.print("the cup");
      delay(2000);
      while(proximity_data != 255){
  if ( !apds.readProximity(proximity_data) ) {
    Serial.println("Error reading proximity value");
  } else {
    
    lcd_reset();
    lcd.print("Waiting for cup");
    lcd.setCursor(0,1);
    lcd.print("Distance: ");
    lcd.print(proximity_data);
  }
  delay(400);
  }
  lcd_reset();
  lcd.print("Thanks for");
  lcd.setCursor(0,1);
  lcd.print("replacing it");
  delay(1000);
    }
    else{
    lcd_reset();
  lcd.print("Pouring in: ");
  lcd.print(x);
  delay(1000);
    }
  }
  lcd_reset();
  lcd.print("Pouring candy...");
    delay(1000);
    auger.attach(9);
		auger.write(20);
		delay(candy_amount);
		auger.write(90);
    auger.detach();
		
   lcd_reset();
   lcd.print("Enjoy!");
   delay(4000);
   lcd_reset();
 lcd.print("Google Powered");
  lcd.setCursor(0,1);
  lcd.print("Candy Dispenser");
  proximity_data = 8;
	}
}

void lcd_reset(){
	lcd.clear();
	lcd.setCursor(0,0);
}
Particle Photon CodeC/C++
Copy and Paste
#include "application.h""

int pin = 7;
char charBuf[50];
int out_pin = 5;

void setup() {
    pinMode(out_pin,OUTPUT);
    pinMode(pin, OUTPUT);
    Particle.function("give_candy", candy);
    Serial.begin(9600);
}

void loop() {

}

int candy(String command){
    command.toCharArray(charBuf, 49);
    char number[6];
    sprintf(number, "%c" "%c" "%c", charBuf[0],charBuf[1],charBuf[2]);
    int length1 = (int)number[0] - 48;
    int length2 = (int)number[1] - 48;
    int length3 = (int)number[2] - 48;
    
    int length = length1 * 100 + length2 * 10 + length3;
    digitalWrite(out_pin,HIGH);
    delay(100);
    digitalWrite(out_pin,LOW);
    
    for(int x=0; x<5; x++){
        digitalWrite(pin,HIGH);
        delay(length);
        digitalWrite(pin, LOW);
        delay(length);
    }
    return 0;
}

Comments

Similar projects you might like

Arduinomated Car Parking with Voice Assistance in Smartphone

Project tutorial by Techduino

  • 318 views
  • 0 comments
  • 9 respects

Traffic Monitor- Monitors traffic on the Go

Project tutorial by Patel Darshil

  • 35 views
  • 0 comments
  • 2 respects

Sigfox Forest Fire Detector

Project tutorial by Louis Moreau

  • 2,716 views
  • 2 comments
  • 16 respects

Remote Lamp

Project tutorial by Kutluhan Aktar

  • 319 views
  • 0 comments
  • 4 respects

Magic VR Hat

Project showcase by Ron Dagdag and Johnathan Hottell

  • 675 views
  • 3 comments
  • 8 respects
Add projectSign up / Login