Introduction: PEPSER

This is a mechanical abstract panther. The pepser whose intention is to change the perception of trash from being disgusting to being cute and creative. It is a sculpture made from discarded soda. My goal is to increase awareness of waste and challenge people to repurpose and upcycle items that they would normally throw away.


1) Arduino Uno

2) Foil Tape

3) Neopixel LEDS

4) Cans / Steel sheets

5) Titanium Bonded Bandage Shears

6) Ultra sound distance sensor HC-SR04

7) Stranded Wires

8) Battery

9) Foil paper

10) Super glue

11) L bracket

12) Screw

13) Wood

14) Acrylic 12''x12'' sheets

15) Hot glue

16) Chipboard

17) Basswood

Step 1: Making the Skeleton

First, you need to cut off both sides of the can. We need to use the soft part in the middle. My personal suggestion is to cut a can a little bit with a knife and then use Metal shears to cut the can along the edge.You have to cut 4-5 cans and make sure you clean up the cans inside when you finish cutting.

Second, you need the metallic wire and bend it. You should draw this shape on the chipboard first to make sure that the dimension of the panther is correct. Then cut two wires follow the length of the panther's back and tail. Comparing with the running panther posture, standing one is the most basic one to test the size and proportion of the whole body of the panther.

Third, the size of the panther's each bone that is one and a half-inch for the back. You need to cut 11 pieces of the metal sheets of the cans. Using the hot glue to stick them to the back wire and each gap of the bones is 1/4 inch. Be careful of the heat temperature. The size of the panther's every bone that is half an inch for the tail. You need to cut 27 pieces. The gap of each bone is 1/4 inch. Leaving 2 inches from the starting side and 1/4 inch from the end.

Step 2: Making the Structure of the Body

You have to cut the panther first, then you have to cut two pieces of wood. Please pay attention! This step you need to change the posture of the panther. We need to transform a static panther into a dynamic panther. We have to use the chipboard panther to make sure of the panther's body structure. We cut two-piece of the woods. One part is a rectangle and another part a right triangle then cut a corner. Then we need to cover the wood with foil paper. Cutting down the chipboard panther's head and spray it to a sliver.

Step 3: Making the Connection Pieces

Adding two connection pieces. These pieces which depends on how the length between the panther‘s head and the panther’s movement angle. When finish the part two, use the trace paper to cope the shape and scan them. The Panther‘s head which can be scanned and we only need to test one side and other sides we can scale up.

The laser cutter has a limitation with the thickness. Thus we have to prepare the basswood. When you finished the cutting, using the wood glue to stick them as the thickness which you wanted. The thickness of the panther is 1 inch. You have to wait for half a day, then you can use wood glue to install the whole body and put it on the space. The part of the head and the neck we need the hot glue to connect with each other.

The joint of two legs we need the L bracket to built a structure and using screws to make these two pieces stable.

Step 4: Installing the Skeleton

Using the drill to make the holes on the panther's body and then put them back and tail into the body. Make sure that the hole is deep or the body can not hold the weight of the tail. When you make holes please remember to maintain the center of gravity of the leopard so that the structure of the leopard does not collapse.

Step 5: Create Circuit & Upload Code

Building the circuit

Once the structure is completed, now lets come to the electronics part.

The above circuit diagram is fairly straightforward. It comprises of three connections. The first one is connecting the neopixel strip in the spine to the Arduino, the Second one is connecting the neopixel strip in the tail to the Arduino and the Third one connects the ultrasound distance sensor to the Arduino.

The number of connections is fairly straightforward, however, making the neopixel strip is a tedious process. Since the desired effect requires neopixels in every rib of the spine, the distance of the wires between each neopixel is important. So we need to carefully cut 3 wires at a time of similar length to ensure that the neopixel stays hidden in the can surface. Also, the distance between the ribs in the tail is extremely small, cutting and soldering such small wires is difficult. Since the distance is less, the temperature rises quickly, often melting the outer layer of the wire. I would recommend using single-core wires for the tail since we can solder them at a lower temperature. Also, holding the wires becomes difficult because of the temperature. I would also recommend following the color coding for wires since we will be soldering a lot of neopixels (34 to be exact).

Start by tinning all the neopixels and the cut wires. Then hold the first neopixel in the helping hand, make sure that the D-IN section is facing outward and bring the tinned wire to the neopixel. We will start by the black wire, connect the black wire to the ground, then yellow to the input, and blue to +5V. Then we will repeat the same process in the D-OUT section of the neopixel. Then connect the first neopixel to the second one, make sure that the D-OUT of the first one connects to the D-IN of the second one. Repeat the steps for all the neopixels.

Since we are using a lot of neopixels, I decided to split the tail and the spine to 2 strips to avoid Voltage drops at the end of the strip.

After finishing soldering, test it for loose connections or poor solders and then apply insulating tape on the back of the neopixel, so that when we put it in the ribs the metal cans do not short the circuits.

The connection to the ultrasound distance sensor is easy. Connect the VCC pin to 5V and GND to Ground, Connect the trigger pin and Echo pin to 9, 10 respectively.

The circuit connections required are complete, In the next section, we will write the code and test it before installation.

Writing the code: The code for this project is made of 2 main logical components. The effect we want is that when the person waves his/her hand near the panther the light should change. So we need to detect when the person waves and then accordingly change the color.

The first block of code in the loop is the logic for measuring distance using the ultrasound distance sensor. It measures the distance by calculating the time difference between sending a sound wave and receiving it. Distance = Speed x time, we already know the speed of sound in air, so once we measure the difference in time, we can approximate the distance.

The second component is if the distance between obstacle is less than the threshold, we set the color of the neopixels as red, else as blue. The pattern of the lighting sequence is defined in function custom function. You can download the code from the file or copy it. Do not forget to change the pin no if you are following a different configuration of pins.


* Ultrasonic Sensor HC-SR04 and Arduino Tutorial


* by Dejan Nedelkovski,




/ NeoPixel Ring simple sketch (c) 2013 Shae Erisson

// Released under the GPLv3 license to match the rest of the

// Adafruit NeoPixel library


#ifdef __AVR__

#include // Required for 16 MHz Adafruit Trinket


// Which pin on the Arduino is connected to the NeoPixels?

#define PIN 6 // On Trinket or Gemma, suggest changing this to 1

#define PIN2 7 // On Trinket or Gemma, suggest changing this to 1

// How many NeoPixels are attached to the Arduino?

#define NUMPIXELS 11 // Popular NeoPixel ring size

#define NUMPIXELS2 22 // Popular NeoPixel ring size

// When setting up the NeoPixel library, we tell it how many pixels,

// and which pin to use to send signals. Note that for older NeoPixel

// strips you might need to change the third parameter -- see the

// strandtest example for more information on possible values.

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

Adafruit_NeoPixel pixels2(NUMPIXELS2, PIN2, NEO_GRB + NEO_KHZ800);

#define DELAYVAL 500 // Time (in milliseconds) to pause between pixels

// defines pins numbers

const int trigPin = 9;

//const int pingPin = 11;

const int echoPin = 10;

// defines variables

long duration;

int distance;

const int numReadings = 10;

int readings[numReadings];

long timing[numReadings];

int readIndex = 0;

int total = 0;

int average = 0;

//unsigned int duration, inches;


#define BRIGHTNESS 50

// Parameter 1 = number of pixels in strip

// Parameter 2 = pin number (most are valid)

// Parameter 3 = pixel type flags, add together as needed:

// NEO_RGB Pixels are wired for RGB bitstream

// NEO_GRB Pixels are wired for GRB bitstream, correct if colors are swapped upon testing

// NEO_RGBW Pixels are wired for RGBW bitstream

// NEO_KHZ400 400 KHz bitstream (e.g. FLORA pixels)

// NEO_KHZ800 800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick

void setup() {

pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output

//pinMode(pingPin, OUTPUT); // Sets the trigPin as an Output

pinMode(echoPin, INPUT); // Sets the echoPin as an Input


// These lines are specifically to support the Adafruit Trinket 5V 16 MHz.

// Any other board, you can remove this part (but no harm leaving it):

#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)



// END of Trinket-specific code.

pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)


// for (int thisReading = 0; thisReading < numReadings; thisReading++) {

// readings[thisReading] = 0;

// timing[thisReading] = 0;

// }


void loop() {

//pinMode(pingPin, OUTPUT);

/* digitalWrite(pingPin, LOW);


digitalWrite(pingPin, HIGH);


digitalWrite(pingPin, LOW);

pinMode(pingPin, INPUT);

duration = pulseIn(pingPin, HIGH);

inches = duration / 74 / 2;


digitalWrite(trigPin, LOW);


// Sets the trigPin on HIGH state for 10 micro seconds

digitalWrite(trigPin, HIGH);


digitalWrite(trigPin, LOW);

// Reads the echoPin, returns the sound wave travel time in microseconds

duration = pulseIn(echoPin, HIGH);

// Calculating the distance

distance= duration*0.034/2;

// Prints the distance on the Serial Monitor

Serial.print("Distance: ");


//customFunction(pixels.Color(255,0,0), 100);


//customFunction(pixels.Color(0,0,255), 100);


customFunction(pixels.Color(255,0,0), 100);

customFunction2(pixels2.Color(255,0,0), 100);



customFunction(pixels.Color(0,0,255), 100);

customFunction2(pixels2.Color(0,0,255), 100);



//total = total - readings[readIndex];

// read from the sensor:

//readings[readIndex] = distance;

//timing[readIndex] = millis();

// add the reading to the total:

// total = total + readings[readIndex];

// advance to the next position in the array:

//readIndex = readIndex + 1;

// if we're at the end of the array...

// if (readIndex >= numReadings) {

// // ...wrap around to the beginning:

// Serial.println(readings[0]);

// Serial.println(timing[0]);


/ readIndex = 0;

// }

// calculate the average:

// average = total / numReadings;

//customFunction(strip.Color(255,71,61), 100);

//customFunction(strip.Color(127,44,232), 100);

//customFunction(strip.Color(66,206,255), 100);


void customFunction(uint32_t c, uint8_t wait){

pixels.clear(); // Set all pixel colors to 'off'

// The first NeoPixel in a strand is #0, second is 1, all the way up

// to the count of pixels minus one.

for(int i=NUMPIXELS; i>=0; i=i-1) { // For each pixel...

pixels.setPixelColor(i, c);; // Send the updated pixel colors to the hardware.

delay(100); // Pause before next pass through loop

//pixels.setPixelColor(i, pixels.Color(0,0,0));

//; // Send the updated pixel colors to the hardware.



void customFunction2(uint32_t c, uint8_t wait){

pixels2.clear(); // Set all pixel colors to 'off'

// The first NeoPixel in a strand is #0, second is 1, all the way up

// to the count of pixels minus one.

for(int i=0; i


pixels2.setPixelColor(i, c);; // Send the updated pixel colors to the hardware.

delay(100); // Pause before next pass through loop

//pixels.setPixelColor(i, pixels.Color(0,0,0));

//; // Send the updated pixel colors to the hardware.