Man's best friend, the humble dog.
Creepy clown's best friend, the $8 skeleton dog from dollar general.
https://www.dollargeneral.com/skeleton-dog-halloween-decor-1-count.html#
Let's see what we can do to make this pup a bit more scary for halloween.........
I'll be using an Arduino Micro for this project to control head movement and eye color.
A motion sensor will detect a visitor, and animate the scary puppy.
First cut it's head off and add a RC servo.
Then epoxy the servo horn into the neck of the beast.
Then we'll add some programmable RGB LEDS for eyes.
These are cut from a strip of 48 with LPD8806 control ICs.
Here's the schematic: The power is from a 5VDC wall supply.
Then hot-glue some ping-pong ball half spheres to cover up the RGB LEDS
There's a RGB control library for this IC on the Adafruit Github site:
https://github.com/adafruit/LPD8806
//Skelly the animatronics dog
//October 2019 R. Scott Coppersmith
#include "LPD8806.h"
#include "SPI.h"
#ifdef __AVR_ATtiny85__
#include <avr/power.h>
#endif
// Based on Adafruit Example to control LPD8806-based RGB LED Modules in a strip
/*****************************************************************************/
// Number of RGB LEDs in strand:
int nLEDs = 4;
// Choose pins for output:
int dataPin = 2;
int clockPin = 3;
const int MotionPin = 4; // Motion detect circuit
const int ServoPin = 5; // PWM servo pin
int MotionState = 1; // Motion detect active low
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int pos = 0; // variable to store the servo position
// First parameter is the number of LEDs in the strand. The LED strips
// are 32 LEDs per meter but you can extend or cut the strip. Next two
// parameters are SPI data and clock pins:
LPD8806 strip = LPD8806(nLEDs, dataPin, clockPin);
void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000L)
clock_prescale_set(clock_div_1); // Enable 16 MHz on Trinket
#endif
pinMode(MotionPin, INPUT);
myservo.attach(5); // attaches the servo on pin 5 to the servo object
// Start up the LED strip
strip.begin();
// Update the strip, to start they are all 'off'
strip.show();
}
void loop() {
colorWipe(strip.Color(0, 0, 0), 50); // off
// read the input pin:
// print out the state of the button:
Serial.println("Waiting for Motion Trigger");
while (MotionState == 1){
MotionState = digitalRead(MotionPin);
}
// print out the state of the button:
Serial.println("Motion Detected");
MotionState = 1;
theaterChase(strip.Color(127, 0, 127), 50); // Violet
// Fill the entire strip with...
colorWipe(strip.Color(127, 0, 0), 50); // Red
colorWipe(strip.Color( 0, 127, 0), 50); // Green
colorWipe(strip.Color( 0, 0, 127), 50); // Blue
rainbow(10);
// Move the dogs head back and forth using the servo
for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
rainbowCycle(0); // make it go through the cycle fairly fast
}
void rainbow(uint8_t wait) {
int i, j;
for (j=0; j < 384; j++) { // 3 cycles of all 384 colors in the wheel
for (i=0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel( (i + j) % 384));
}
strip.show(); // write all the pixels out
delay(wait);
}
}
// Slightly different, this one makes the rainbow wheel equally distributed
// along the chain
void rainbowCycle(uint8_t wait) {
uint16_t i, j;
for (j=0; j < 384 * 5; j++) { // 5 cycles of all 384 colors in the wheel
for (i=0; i < strip.numPixels(); i++) {
// tricky math! we use each pixel as a fraction of the full 384-color wheel
// (thats the i / strip.numPixels() part)
// Then add in j which makes the colors go around per pixel
// the % 384 is to make the wheel cycle around
strip.setPixelColor(i, Wheel( ((i * 384 / strip.numPixels()) + j) % 384) );
}
strip.show(); // write all the pixels out
delay(wait);
}
}
// Fill the dots progressively along the strip.
void colorWipe(uint32_t c, uint8_t wait) {
int i;
for (i=0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
// Chase one dot down the full strip.
void colorChase(uint32_t c, uint8_t wait) {
int i;
// Start by turning all pixels off:
for(i=0; i<strip.numPixels(); i++) strip.setPixelColor(i, 0);
// Then display one pixel at a time:
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c); // Set new pixel 'on'
strip.show(); // Refresh LED states
strip.setPixelColor(i, 0); // Erase pixel, but don't refresh!
delay(wait);
}
strip.show(); // Refresh to turn off last pixel
}
//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
for (int j=0; j<10; j++) { //do 10 cycles of chasing
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, c); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
for (int j=0; j < 384; j++) { // cycle all 384 colors in the wheel
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, Wheel( (i+j) % 384)); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
/* Helper functions */
//Input a value 0 to 384 to get a color value.
//The colours are a transition r - g -b - back to r
uint32_t Wheel(uint16_t WheelPos)
{
byte r, g, b;
switch(WheelPos / 128)
{
case 0:
r = 127 - WheelPos % 128; //Red down
g = WheelPos % 128; // Green up
b = 0; //blue off
break;
case 1:
g = 127 - WheelPos % 128; //green down
b = WheelPos % 128; //blue up
r = 0; //red off
break;
case 2:
b = 127 - WheelPos % 128; //blue down
r = WheelPos % 128; //red up
g = 0; //green off
break;
}
return(strip.Color(r,g,b));
}








Top Comments