16 LED Christmas Tree With Shift Registers And Motion Detection

I’m lucky that Christmas has such a wide array of acceptable aesthetics. There are two things in life that I can cut out with a jigsaw and the ol’ lady still dig it and I haven’t found the second. The first is the Christmas tree.

The wife has a birthday in November, which means I get an excuse to partake in a deadline-based, obligatory project. Deadlines are hyper important for any project as they prevent self-defeating logic that results in projects that never finished. The obligatory part means I’m a scumbag if I don’t finish it. This trait allows me to work on the project when I should probably be working on Calc3 integrals.

With every project I try to do something new. In this case, I wanted to learn shift registers. I used two 74HC50N shift register in DIP package form. The Arduino code makes the shift register thing a breeze, but I don’t love their examples. The examples remind me of the way text books teach for some reason.

Here’s the gist on shift registers.

digitalWrite(latchPin, 0); // Puts the shift register into "read mode" to acquire the new value you are cramming in.
shiftOut(dataPin, clockPin,MSBFIRST, x); // does the damage. x is the integer which will ulltimately be converted to binary in this case. 255 is 1111111 in binary and would turn 8 LEDs on.
digitalWrite(latchPin, 1); // Turn off "read mode".

That’s about it.

If you want to blink all LED’s, you could turn them all off by setting x = 0 and looping through the same code above with a delay(1000) after each one.

In my case, I had 2 shift registers. The only thing different was I had 2 shiftOut statements like this:
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin,MSBFIRST, x);
shiftOut(dataPin, clockPin,MSBFIRST, x);
digitalWrite(latchPin, 1);

Put Arduino To Sleep

I’m using unethical Ebay Arduino Mini Pro clones that I paid $1.80 for. (Sue me! You won’t get anything. I’m in school.) I always forget whether I have the 3.3V or 5V version. I have no idea how to tell the difference. Maybe I should do my homework before writing this. I gouged out the on LED with a soldering iron to prevent it using the few mA it likes to devour. For this one I didn’t go too bonkers with power reduction. I just wanted the Arduino to go to sleep, wake up when it detected RISING from the PIR motion detector pin, run through the blinking sequence for 20 second or so (I can’t remember what value I through in there) and then go back to sleep when the sequence was over.

Too Bright LEDs

I believe I tossed in 330 ohm, current-limiting resistors for the LEDs. In my dungeon/lab, this looked about right. When viewed directly on axis, this was painful to look at on the Christmas tree. So, I toyed around with a function that blinked the LEDs off and on. I can’t say if this was a good way to achieve the goal, but I turned on the lights, delay(1) and then turned them off for delay(5). This knocked down the pain factor when looking at the Christmas tree head on. I’ve got a feeling this isn’t right, but my power supply tells me I’m barely pulling any current – about 10mA. I probably did something wrong there, too. I don’t trust that number. Oh well, I’m using a big ass 18650 battery and it only needs to last for a month. We’ll be alright.

Arduino Code


#include "LowPower.h"

volatile boolean motionState = 0;
//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 11;  //flipped
////Pin connected to DS of 74HC595
int dataPin = 12;  // flipped
long lasttime = 0;
int i = 0;
void setup()
{
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode (13, OUTPUT);
  attachInterrupt(0, thing, RISING);
  Serial.begin(9600);
 
}


void loop ()
{
  attachInterrupt(0, thing, RISING);
  LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); 
  detachInterrupt(0); 
  motionDetected2(0);  // The value passed to this function resets i to zero.
}


void thing()
{
motionState = 1;
}
void motionDetected2(int i){

// LOOP THROUGH 20 RANDOMLY GENERATED NUMBERS
// EACH NUMBER GETS brantotime MILLISECONDS.
  while ( i < 20){
      int thingtime = 1;
      int brandotime = 1000;
      int dimness = 10000;  
      int x = random(1,256);    
      lasttime = millis();
  
      // BLINK CURRENT VALUE OF x FOR brandotime MS.  THIS IS TO REDUCE BRIGHTNESS
      while (millis() - lasttime < brandotime) {
        digitalWrite(latchPin, 0);
        shiftOut(dataPin, clockPin,MSBFIRST, x); 
        shiftOut(dataPin, clockPin,MSBFIRST, x); 
        digitalWrite(latchPin, 1);
        delay(thingtime);
        
        digitalWrite(latchPin, 0);
        shiftOut(dataPin, clockPin,MSBFIRST, 0); 
        shiftOut(dataPin, clockPin,MSBFIRST, 0); 
        digitalWrite(latchPin, 1);
        delay(thingtime * 5);   
      }
      
      digitalWrite(latchPin, 0);
      shiftOut(dataPin, clockPin,MSBFIRST, 0); 
      shiftOut(dataPin, clockPin,MSBFIRST, 0); 
      digitalWrite(latchPin, 1);
      delay(1);
      i++;
  }  
  
  
}

Tennis Ball Gun


Date: May 2017
I had big plans of putting a lidar detector in this thing to allow for fully-automated kinematics. Real life stinks. Someday I will go back and make this tennis ball cannon automatically adjust its angle to accommodate different distances. In the mean time, I’ll have to let this idea ferment on the back burner and learn my Taylor series like a good boy. Oh the joys of being an engineering student!

Just a tip or two for people building tennis ball guns for an engineering class (or otherwisee).

1) We used a 4″ PVC Schedule 40 pipe for the air tank. I forget the length. Feel free to look at our AutoCAD design. After a shot, there was always about 15 PSI left in the tank. I don’t know “air physics”, but my hunch is that we had an excessive air supply at 80 PSI but not that excessive.

2) There is quite a bit talk online about the speed of the switch. We used a sprinkler valve to kick this booger on. The story on the streets is you need a valve that will open insanely fast to allow a full-on attack on the tennis ball. This makes some sense. If the trickle were spread out over 30 seconds, the tennis ball may fall out the other side…..at best. With that said, there were other humans in the competition that used a hand valve and they had absolutely no problem applying monstrous force to their tennis balls. In short, you dont’t necessarily need a sprinkler valve for high transient pressure.

3) When it came to the actual competition, our professor was a little ticked that a few teams (ours included) did not use the required parabolic trajectory. (You don’t get to type “parabolic trajectory” with your clothes on very often.) We want with a fixed-pressure design which meant we varied the angle to hit our targets. For extremely-low-angle shots, this meant we basically shot the cone as if we were shooting a bad guy in a Clint Eastwood movie. If we missed by a inch, we actually missed by a mile as we were judged by the distance from the cone to where our tennis ball hit the ground. You may want to test variable-pressure designs.

Download: AutoCAD PDF Export Files

Battleship In Python 2.7

Battleship Python
December 2016

Python 2.7 – vPython Graphics Library

While all the knuckleheads learning C++ were just getting around to for loops, our Python class had final projects of making a “video game”. Video game should probable be nested in 7 or 8 quotes here, but all us scraped some kind of interactive, graphically-dominated time waster. My team chose Battleship, the ultimate game of chance in which skill is almost totally unnecessary. The rest of team handled graphical elements. I wrote the “game engine” (again 7 or 8 quotes may be necessary).

It was fun busting up the human behavior elements of Battleship and getting the “computer” to behave in mostly-similar ways. Basically, the plan was to randomly select coordinates from the grid. When a hit was made,a person switches to “plus sign mode” where they figure out the orientation of the ship. Once that’s done, the person switches to “linear mode” and goes down the line until the ship sinks or they miss. That was fun to implement.

Source Code: Battleship_Final