Introduction: Random Honey Dispenser for Sun Bears

Honey Dispenser for Sun Bears

We wanted to create something stimulating for the sun bears that would also allow the zookeepers to play with them. That’s what the Honey Pumper does: using their long tongues and keen sense of smell, they’ll search for the correct pipe and be rewarded with a flow of delicious, golden honey!

Attached is the pdf version of this guide!

Step 1: Materials for the Electronic

Make sure you have everything you need for the build. There is nothing more annoying than stopping your project because you have to wait for some small part being delivered.

For the electronic part, you need:

  • 1 x Arduino
  • 1 x L298N Motor Controller
  • 1 x Perf board
  • 1 x Breadboard
  • 3 x Buttons
  • 4 x Peristaltic Pumps
  • 1 x Addressable RGB LED strip

Step 2: Connecting the Pumps

You need:

  • Arduino Motor Controller
  • Breadboard
  • Peristaltic Pumps

The steps:

  1. Connect the yellow power cable of the pump 1 and pump 2 to OUT1 and OUT2 in the motor controller respectively (Pic 2)
  2. Connect the red ground cable of both pumps to the breadboard. Make sure they are in the same row. Complete the circuit by connecting GND pin in the Arduino to the same ground row (Pic 3)
  3. Supply power to the motor controller by connecting Vin in the Arduino to 12+ Power Supply pin in the motor controller. Don’t forget to complete the circuit by connecting GND pin in the motor controller to the ground rows in the breadboard (Pic 4)
  4. Allow the Arduino to control the movement of the pumps by connecting IN1 and IN2 in the motor controller to pin 12 and 11 respectively. Pin 12 will control Pump 1 while pin 11 will control Pump 2 (Pic 5)

Step 3: Making the Control Buttons

You need:

  • 3 x Buttons
  • Perfboard Solder

The steps:

  1. Solder the buttons to the perfboard. The first button is [C]onstant Button. The second button is [M]anual Button. The last button is [A]uto Button. The function of each button will be discussed in further steps
  2. You can combine all the ground together in one cable (pic 2)
  3. Connect the black input cables for C, M and A button to pin 2, 3, 4 respectively. Also, complete the circuit by connecting the white ground cable to the ground row in the breadboard

Step 4: Acrylic Pipe and Tubing

Here’s what you will need:

  • 2 x 17 cm Clear Acrylic Tube (3.5 inch diameter)
  • 2 x 12.5 cm Clear Acrylic Tube (3.5 inch diameter)
  • 4 x Plastic Stopper (3D printed to fit the tube)
  • 2 x 1.5m Green rubber/plastic tubing (0.5 cm diameter)
  • 2 x 1.5m Blue rubber/plastic tubing (0.5 cm diameter) Note: any two colours are fine as long as they can be differentiated
  • 4 x 1m Plastic tubing (1 cm diameter)
  • 4 x 1.3m wire
  • 8 x Female Header pins
  • 1 x Roll of Silicon Tape
  • 1 x Roll of Mounting
  • Tape
  • Hot Glue Gun

How to Assemble

1. Start with 1x 17 cm Clear acrylic tube and a plastic stopper

2. Tape a strip of mounting tape the length of the circumference of the tube at both ends of acrylic the tube. Go over the mounting tape with silicon tape to waterproof it.

3. Fit the 1.5m green plastic tubing through the stopper and fit the stopper into the end of the clear acrylic pipe.

4. Solder two male header pins to the end of 1 x 1.3m wire

5. Add hot glue over the soldered connection to prevent any breakage

6. Thread the green plastic tubing and one end of the wire through the bigger 1cm diameter plastic tubing

7. Repeat for the other 17 cm acrylic tube and the 2 x 12.5 cm acrylic tubes (replacing the green plastic tubing with the blue)

Step 5: Attaching the Capacitive Touch Sensor

Here's the items you will need for this step:

1 x PVC T-connector (1.5 inch diameter)

1 x roll of copper tape

1 x wire with male header pin and female header pin

1. Attach a length of copper tape around the end of the T-connector that does not have the clear acrylic pipe attached

2. Using the soldering wire and soldering iron, solder the male header pin to the copper tape from Step 1

3. After the solder has cooled, layer another round copper tape over it, and make it secure by wrapping the tape around the entire circumference of the T-connector as well

4. Connect the female header pin of the capaciti to the male header pin from

5. Repeat for the other T-connectors that are attached to the clear acrylic pipes

Step 6: Building the Mainframe

Here’s what you will need:

  • 2 x PVC T- Connector (1.5 inch diameter)
  • 4 x PVC Elbow Connector (1.5 inch diameter)
  • 2 x 54 cm PVC Pipe (1.5 inch diameter)
  • 4 x 23.5 cm PVC Pipe (1.5 inch diameter)
  • 4 x Acrylic Pipe and Tubing (from part 1)
  • 4x Capacitive touch sensor (from part 2)

How to Assemble:

  1. Assemble the PVC tubes as shown in the diagram, making sure to run the plastic tubings through the pipes.

Step 7: Integrating LED Strips

You need:

  • Addressable RGB LED strip

The steps:

  1. Connect the power pin of the LED, the ground pin and the data pin to pin 5V, GND and pin 5 respectively. The LED only needs 5V so do not use Vin as it will burn up the LEDs.

By now you should have completed the electronics part! Your circuit should look like the second pic above. Do take note that we only have 2 pumps and 1 LEDs while the diagram shows full product with 4 pumps and 2 LEDs!

Step 8: Setting Up the Circuit Box

Here’s what you will need:

1x Airtight box with cover

1 x12V Power Adaptor

1 x Arduino

1 x L298N Motor Controller

1 x Breadboard

1 x Perf board

3 x Buttons

4 x Peristaltic Pumps

4 x 7.5cm Pump Holders (1.5 inch diameter)

8 x Mounting Tape Strips

How to Assemble:

  1. Ensure that the circuitry are connected properly (Pumps, Control Buttons, LED strips) according to the instructions under the Electronics section.
  2. Place each Peristaltic Pump into their respective Pump Holders.
  3. Place 1 x mounting tape strip each to the L298N Motor Controller, Breadboard, 4 x Pump Holders, and 2 x mounting tape strip to the Arduino. Attach the items mentioned above to the airtight box, as shown in the diagram below, with the Breadboard at the base and Motor Controller, Peristaltic Pumps+ Holders, Arduino at the sides of the box.
  4. Drill 4 holes (7.5cm x 4cm) at each corner of the cover of the box.
  5. Connect the Control Buttons and Perfboard to the Arduino.
  6. Connect the Arduino to the 12V power adaptor and power outlet.
  7. Attach the Plastic Tubings from the main frame in Part 3 to the side labelled E(ject) on the Peristaltic Pumps, and the side labelled I to the honey container.

Step 9: Code

The code can be found here!

Explanation of the code

Defining the constants

#define NUM_LEDS 100
CRGBArray leds;

// Delays const int delay_time = 30000; // 30 seconds to allow the bear to enjoy they honey const int pump_time = 10000; // 10 seconds of pumping

// Touch Sensor Sensitivity const int sensitivity = 20; // Threshold of the touch sensors

// Buttons const int buttonConstantPin = 2; const int buttonManualRandomPin = 3; const int buttonAutoRandomPin = 4;

// Pumps const int pump1 = 12; const int pump2 = 11; const int pump3 = 10; const int pump4 = 9;

// LED // Addrressable LEDs work like array. So we assigning which LEDs to which pump const int led = 5; const int pump_1_start = 0; const int pump_1_end = 4; const int pump_2_start = 4; const int pump_2_end = 8; const int pump_3_start = 8; const int pump_3_end = 11; const int pump_4_start = 11; const int pump_4_end = 14;

// State of the buttons: pressed or not int randomPump = 0; int buttonManualRandomState = 0; // variable for reading the pushbutton status int buttonConstantState = 0; // variable for reading the pushbutton status int buttonAutoRandomState = 0;

// State of the touch sensors: touched or not bool autoOn = false; bool touchedPump1 = false; bool touchedPump2 = false; bool touchedPump3 = false; bool touchedPump4 = false;

// Reference value for the touch sensors int refPump1 = 0; int refPump2 = 0; int refPump3 = 0; int refPump4 = 0;

Set Up

void setup() {
// initialize the LED pins: FastLED.addLeds(leds, NUM_LEDS);

// initialize the button pins: pinMode(buttonManualRandomPin, INPUT_PULLUP); pinMode(buttonConstantPin, INPUT_PULLUP); pinMode(buttonAutoRandomPin, INPUT_PULLUP);

// initialize the pump pins pinMode(pump1, OUTPUT); pinMode(pump2, OUTPUT); pinMode(pump3, OUTPUT); pinMode(pump4, OUTPUT);

// get the reference value for the touch sensor refPump1 = ADCTouch.read(A0, 500); //create reference values to pump 1 refPump2 = ADCTouch.read(A1, 500); //create reference values to pump 2 refPump3 = ADCTouch.read(A2, 500); //create reference values to pump 3 refPump4 = ADCTouch.read(A3, 500); //create reference values to pump 4 Serial.begin(9600); setup_light(); }

Loop Function

void loop() {
// read the state of the pushbutton value: buttonManualRandomState = digitalRead(buttonManualRandomPin); buttonConstantState = digitalRead(buttonConstantPin); buttonAutoRandomState = digitalRead(buttonAutoRandomPin);

// read the value of the touch sensors int touchValuePump1 = ADCTouch.read(A0); int touchValuePump2 = ADCTouch.read(A1); int touchValuePump3 = ADCTouch.read(A2); int touchValuePump4 = ADCTouch.read(A3);

// Getting the value of the touch sensors touchValuePump1 -= refPump1; touchValuePump2 -= refPump2; touchValuePump3 -= refPump3; touchValuePump4 -= refPump4;

Serial.print("Touch value pump 1: "); Serial.println(touchValuePump1); Serial.print("Touch value pump 2: "); Serial.println(touchValuePump2); Serial.print("Touch value pump 3: "); Serial.println(touchValuePump3); Serial.print("Touch value pump 4: "); Serial.println(touchValuePump4); if(touchValuePump1 > sensitivity){ touchedPump1 = true; }else{ touchedPump1 = false; }

if(touchValuePump2 > sensitivity){ touchedPump2 = true; }else{ touchedPump2 = false; }

if(touchValuePump3 > sensitivity){ touchedPump3 = true; }else{ touchedPump3 = false; }

if(touchValuePump4 > sensitivity){ touchedPump4 = true; }else{ touchedPump4 = false; } if(buttonAutoRandomState == LOW){ if(autoOn == false){ autoOn = true; Serial.println("Auto Mode Activated"); randomizePump(); }else{ autoOn = false; Serial.println("Auto Mode Deactivated"); auto_mode_off_light(); } }

if(autoOn == true){ bool touched; if(randomPump == 0){ touched = touchedPump1; }else if(randomPump == 1){ touched = touchedPump2; }else if(randomPump == 2){ touched = touchedPump3; }else{ touched = touchedPump4; } if(touched == true){ Serial.println("Auto Mode Continued"); randomizePump(); } }

if (buttonConstantState == LOW ) { Serial.println("Constant Mode Activated"); digitalWrite(pump1, HIGH); digitalWrite(pump2, HIGH); digitalWrite(pump3, HIGH); digitalWrite(pump4, HIGH); light_led(0); light_led(1); light_led(2); light_led(3); } else { digitalWrite(pump1, LOW); digitalWrite(pump2, LOW); digitalWrite(pump3, LOW); digitalWrite(pump4, LOW); off_led(0); off_led(1); off_led(2); off_led(3); } // check if the pushbutton is pressed. If it is, the buttonState is HIGH: if (buttonManualRandomState == LOW ) { Serial.println("Single Random Mode Activated"); randomizePump(); } }

Activate Pumps - A function to get a given pump working

void activatePump(int pump){
digitalWrite(pump, HIGH); light_led(randomPump); delay(pump_time); digitalWrite(pump, LOW); off_led(randomPump); }

Randomize Pump - A function that will randomly choose a pump

void randomizePump(){
randomPump = random(3); Serial.print("Pump number: "); Serial.println(randomPump + 1); if (randomPump == 0){ activatePump(pump1); }else if(randomPump == 1){ activatePump(pump2); }else if(randomPump == 2){ activatePump(pump3); }else{ activatePump(pump4); } delay_light(); }

Turn On LED - Turn on the respective LED of a given pump

void light_led(int pump){
if(pump == 0){ for(int i = pump_1_start; i < pump_1_end; i++) { leds[i] = CRGB::Crimson; } FastLED.show(); }else if(pump == 1){ for(int i = pump_2_start; i < pump_2_end; i++) { leds[i] = CRGB::DeepSkyBlue; } FastLED.show(); }else if(pump == 2){ for(int i = pump_3_start; i < pump_3_end; i++) { leds[i] = CRGB::Chocolate; } FastLED.show(); }else{ for(int i = pump_4_start; i < pump_4_end; i++) { leds[i] = CRGB::DeepPink; } FastLED.show(); } }

Turn Off LED - Turn off the respective LED of a given pump

void off_led(int pump){
if(pump == 0){ for(int i = pump_1_start; i < pump_1_end; i++) { leds[i] = CRGB::Black; } FastLED.show(); }else if(pump == 1){ for(int i = pump_2_start; i < pump_2_end; i++) { leds[i] = CRGB::Black; } FastLED.show(); }else if(pump == 2){ for(int i = pump_3_start; i < pump_3_end; i++) { leds[i] = CRGB::Black; } FastLED.show(); }else{ for(int i = pump_4_start; i < pump_4_end; i++) { leds[i] = CRGB::Black; } FastLED.show(); } }

Delay Light - Turn on blinking light during the delay

void delay_light(){
int iteration = delay_time/1000; for(int i = 0; i < iteration; i++){ for(int i = pump_1_start; i < pump_4_end; i++) { leds[i] = CRGB::ForestGreen; } FastLED.show(); delay(500); for(int i = pump_1_start; i < pump_4_end; i++) { leds[i] = CRGB::Black; } FastLED.show(); delay(500); } }

Auto Mode Off Light - To show that Auto mode has been deactivated

void auto_mode_off_light(){
for(int i = 0; i < 3; i++){ for(int i = 0; i < 100; i++) { leds[i] = CRGB::DarkOrange; } FastLED.show(); delay(500); for(int i = 0; i < 100; i++) { leds[i] = CRGB::Black; } FastLED.show(); delay(500); } }

Setup Light - To show that the device is fully initialized

void setup_light(){
for(int i = 0; i < 100; i++) { leds[i] = CRGB::Red; } FastLED.show(); delay(500); for(int i = 0; i < 100; i++) { leds[i] = CRGB::Black; } FastLED.show(); delay(500); for(int i = 0; i < 100; i++) { leds[i] = CRGB::Red; } FastLED.show(); delay(500); for(int i = 0; i < 100; i++) { leds[i] = CRGB::Black; } FastLED.show(); }