
As a designer, I spend a lot of time coming up with ideas. And let’s be honest—sometimes they’re just shitty and trashy. So for Halloween, I’m literally wrapped in a trash bag, and on my head is a lightbulb, symbolizing those ‘aha’ moments… except this one’s got a glowing poop inside.


Material list:
Clear Ball Ornaments, 160mm/6.3inch
3D printed poop shaped shell (12x12x12cm, transparent PETG)
3D printed bulb holder (12x12x12cm, black PLA, spray painted in copper color)
XL trash bag (realized it’s still too small)
black leggings
Adafruit NeoPixel Digital RGB LED Strip
Gemma M0 board
button
Idea Sketches:


3D modeling:


Circuit Diagram:

Arduino code:
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define BUTTON_PIN 2
#define PIXEL_PIN 1
#define PIXEL_COUNT 78
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
boolean oldState = HIGH;
int mode = 0;
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
strip.begin();
strip.show();
}
void colorWipe(uint32_t color, int wait) {
for(int i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, color);
strip.show();
delay(wait);
}
}
//mode3: offset orange blink
void orangeblink(int wait) {
for (int offset = 0; offset < 3; offset++) { // offset each 3 pixels
strip.clear(); // clear all pixels
for (int i = offset; i < strip.numPixels(); i += 3) {
strip.setPixelColor(i, strip.Color(255, 165, 0)); // orange
}
strip.show(); //
delay(wait); //
}
}
// Mode 4: Theater chase effect
void theaterChase(uint32_t color, int wait) {
for (int a=0; a<10; a++) { // Repeat the chase effect
for (int b=0; b<3; b++) { // 3 pixels lit per cycle
strip.clear(); // Clear the pixels
for (int c=0; c < strip.numPixels(); c+=3) {
strip.setPixelColor(c+b, color); // Set every third pixel to the given color
}
strip.show(); // Update the strip
delay(wait); // Wait before the next step
}
}
}
// mode5: rainbow
void rainbow(int wait) {
for (long firstPixelHue = 0; firstPixelHue < 3*65536; firstPixelHue += 256) {
for (int i = 0; i < strip.numPixels(); i++) {
int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
}
strip.show();
delay(wait);
}
}
void loop() {
boolean newState = digitalRead(BUTTON_PIN);
// Check if state changed from high to low (button press).
if((newState == LOW) && (oldState == HIGH)) {
// Short delay to debounce button.
delay(20);
// Check if button is still low after debounce.
newState = digitalRead(BUTTON_PIN);
if(newState == LOW) { // Yes, still low
if(++mode > 10) mode = 0; // Advance to next mode, wrap around after #8
switch(mode) { // Start the new animation...
case 0:
colorWipe(strip.Color( 0, 0, 0), 50); // Black/off
break;
case 1:
orangeTheaterChase();
break;
case 2:
fade(20);
break;
case 3:
theaterChase(strip.Color(255, 0, 0), 50); // red
break;
case 4:
theaterChase(strip.Color(255, 255, 0), 50); // yellow
break;
case 5:
theaterChase(strip.Color(0, 255, 0), 50); // green
break;
case 6:
theaterChase(strip.Color(0, 0, 255), 50); // blue
break;
case 7:
theaterChase(strip.Color(128, 0, 128), 50); // purple
break;
case 8:
rainbow(10);
break;
}
}
}
oldState = newState;
}
//mode2: poop up, poop down
void orangeTheaterChase() {
for (int repeat = 0; repeat < 2; repeat++) { // Repeat the effect twice
// Gradually light up from the first to the last pixel
for (int a = 0; a < strip.numPixels(); a++) {
strip.clear();
for (int b = 0; b <= a; b++) {
strip.setPixelColor(b, strip.Color(255, 60, 0)); // Set color to orange
}
strip.show();
delay(50); // Delay between each pixel lighting up
}
// Gradually turn off from the last to the first pixel
for (int a = strip.numPixels() - 1; a >= 0; a--) {
strip.clear();
for (int b = 0; b <= a; b++) {
strip.setPixelColor(b, strip.Color(255, 60, 0)); // Keep color orange
}
strip.show();
delay(50); // Delay between each pixel turning off
}
}
}
// //mode3: fade 3 times with dif leds
void fade(int wait) {
// int fadeTimes = 3;
// for (int t = 0; t < fadeTimes; t++) {
// light up
for (int brightness = 0; brightness <= 255; brightness += 5) {
strip.clear();
for (int i = 0; i < strip.numPixels(); i += 3) {
strip.setPixelColor(i, strip.Color((brightness * 255) / 255, (brightness * 80) / 255, 0));
}
strip.show();
delay(wait);
}
// turn down
for (int brightness = 255; brightness >= 0; brightness -= 5) {
strip.clear();
for (int i = 0; i < strip.numPixels(); i += 3) {
strip.setPixelColor(i, strip.Color((brightness * 255) / 255, (brightness * 80) / 255, 0));
}
strip.show();
delay(wait);
}
for (int brightness = 0; brightness <= 255; brightness += 5) {
strip.clear();
for (int i = 1; i < strip.numPixels(); i += 3) {
strip.setPixelColor(i, strip.Color((brightness * 255) / 255, (brightness * 80) / 255, 0));
}
strip.show();
delay(wait);
}
// turn down
for (int brightness = 255; brightness >= 0; brightness -= 5) {
strip.clear();
for (int i = 1; i < strip.numPixels(); i += 3) {
strip.setPixelColor(i, strip.Color((brightness * 255) / 255, (brightness * 80) / 255, 0));
}
strip.show();
delay(wait);
}
for (int brightness = 0; brightness <= 255; brightness += 5) {
strip.clear();
for (int i = 2; i < strip.numPixels(); i += 3) {
strip.setPixelColor(i, strip.Color((brightness * 255) / 255, (brightness * 80) / 255, 0));
}
strip.show();
delay(wait);
}
// turn down
for (int brightness = 255; brightness >= 0; brightness -= 5) {
strip.clear();
for (int i = 2; i < strip.numPixels(); i += 3) {
strip.setPixelColor(i, strip.Color((brightness * 255) / 255, (brightness * 80) / 255, 0));
}
strip.show();
delay(wait);
}
}
Light Result!