LED Gumball Machine

Pages
Contributors: Nate
Favorited Favorite 2

Software

We want the gumball machine to dispense LEDs when the button is pressed, that’s straightforward enough. But we want to avoid dispensing all the LEDs. Also, we don’t want someone to stand in front of the free machine and continually hit the ‘gimme’ button. We implement a timeout of 15 seconds that prevents users from activating the servo constantly. You can get the software here.

Dispensing with PWM

Almost all servos operate on PWM. Before installing the continuous servo in our machine we found the servo responded in the follow ways:

  • gumballServo.write(95); - Stops movement of continous servo
  • gumballServo.write(200); - Servo turns CCW rapidly
  • gumballServo.write(10); - Servo turns CW rapidly (but not used)

Our gumball dispenser was designed to operate clock wise so we only operate our servo counter clockwise.

Handful of LEDs

The dispenser was designed for gumballs obviously so when dispensing LEDs the number of LEDs that actually come out varies wildly. In general the user gets 1 to 5 LEDs when the servo is activated for 1 second. This works well. In the eventual case that LEDs fail to dispense, the user just has to wait 15 seconds to try again. Since we're not charging anything this is an acceptable outcome.

language:c
gumballServo.detach(); //Be sure the servo won't move

After dispensing we detach the servo. This turns off the PWM signal going to the servo guaranteeing the servo won't move. We noticed the servo jittered or moved very slowly at 90 (when it shouldn't be moving) so this extra step insures the LED Gumball Machine won't slowly disgorge itself onto the carpet overnight.

Along those same lines of concern, we noticed that the dispensing mechanism will sometimes bind up causing the servo to draw significantly more current for a short period of time. This can cause the power supply to shut down, causing the Arduino to reset. You'll see at the beginning of setup()

language:c
gumballServo.attach(GUMBALL_SERVO); //Be sure the servo won't move
gumballServo.write(95); //Stop movement on continous servo
gumballServo.detach(); //Be sure the servo won't move

The above code is the first thing the Arduino runs and insures any previous servo movement is stopped. This helps prevent weird rolling reset situations where the servo causes a brownout and as the Arduino comes back on line the servo begins moving, causing a brownout, etc...

Button Monitoring

The button shorts to ground when pressed so we use the internal pullups to pull the button pin high when the button is not pressed.

The button has a built in LED so we connect the +/- pins on the back of the button directly to a PWM enabled pin and Ground. The LED measured 12mA at 5V, well below the 20mA max so we didn't need a resistor.

language:c
//Check if we are allowed to dispense
else if (millis() - lastDispenseTime < minTimeBetweenPresses)
{
    Serial.println("Uh-huh Mr. Eager. Wait your turn.");
    while (digitalRead(BUTTON) == LOW) delay(10); //Wait for user to stop pressing button
    return; //No soup for you!
}

In the code above, we check to see if enough time has passed since the last button press for us to vend again.

language:c
unsigned long minTimeBetweenPresses = 15 * 1000; //Make users wait this amount of ms between dispenses

We found 15 seconds (15,000 milliseconds) between vends was enough time to dissuade students from taking all the LEDs.