A quick order of business - this Friday, November 4th, there will be no orders shipped. We are counting all our stuff (AKA, a full inventory physical count). Apologies for the inconvenience!
In this weeks special Halloween edition of "According to Pete," Pete talks about his Halloween Ray Gun Project. Check it out!
If you are interested in creating your own Halloween Ray Gun project and need the code, check it out below. You can also download the code here.
/*
Raygun. Pillaged from Blink.
Pete Dokter, Halloween, 2011
All this code does is cycle through some LEDs (blue) while the trigger of the raygun is not active,
and cycle through some audio and all the LEDs (red and blue) when the trigger is active. This is bad
C code, optimized for the minimum time I needed to make it work (which is to say "not at all"). It does,
however, compile and load with Arduino 0022, which is what I used. If you use it in something that makes
money, you're crazy. But I invoke Beerware: if you use it , you may buy me a beer and we'll call it good.
*/
int trigger = A3;
int trigger_value = 0;
int a = 0;
int b = 0;
int c = 0;
int d = 0;
int pulse = 0;
int trip = 0;
int up = 1;
void setup() {
pinMode(2, OUTPUT); //blue
pinMode(3, OUTPUT); //blue
pinMode(4, OUTPUT); //blue
pinMode(5, OUTPUT); //blue
pinMode(6, OUTPUT); //red
pinMode(7, OUTPUT); //red
pinMode(8, OUTPUT); //red
pinMode(10, OUTPUT); //sound
}
void loop() {
//This while loop is redundant, given what "loop" is.
//Old habits die hard.
while(1)
{
//Initial read for the trigger
trigger_value = analogRead(trigger);
//If trigger is high, make noise and cycle LEDs. Once through this loop will play
//a varying pitch, low to high, then set the LEDs
while (trigger_value >512)
{
//This is the sound loop, covered by variables "b" and "c" below. The "c" variable
//determines how long to play a given frequency, the "b" variable changes the frequency.
//As "b" increases, the frequency of the pitch increases.
for (b = 0; b <=25; b++)
{
for (c = 0; c <= 6; c++)
{
digitalWrite(10, HIGH);
for (a = 0; a <=50-b; a++);
digitalWrite(10, LOW);
for (a = 0; a <=50-b; a++);
digitalWrite(10, HIGH);
for (a = 0; a <=50-b; a++);
digitalWrite(10, LOW);
for (a = 0; a <=50-b; a++);
digitalWrite(10, HIGH);
for (a = 0; a <=50-b; a++);
digitalWrite(10, LOW);
for (a = 0; a <=50-b; a++);
digitalWrite(10, HIGH);
for (a = 0; a <=50-b; a++);
digitalWrite(10, LOW);
}
}
//After playing the sound, the LEDs, both blue and red, are set to some pattern that I
//chose almost arbitrarily. The "trip" variable is used to determine what the last pattern
//was and what the next one will be.
if (trip == 0)
{
digitalWrite(2, HIGH);
digitalWrite(3, LOW);
digitalWrite(4, HIGH);
digitalWrite(5, LOW);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
digitalWrite(8, LOW);
trip = 1;
}
else if (trip == 1)
{
digitalWrite(2, LOW);
digitalWrite(3, HIGH);
digitalWrite(4, LOW);
digitalWrite(5, HIGH);
digitalWrite(6, LOW);
digitalWrite(7, HIGH);
digitalWrite(8, HIGH);
trip = 2;
}
else if (trip == 2)
{
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, HIGH);
digitalWrite(7, LOW);
digitalWrite(8, HIGH);
trip = 0;
}
//After the LEDs are cycled, we read the trigger value to see if we should stay in the loop
//or bail out.
trigger_value = analogRead(trigger);
//Variables "d" and "pulse" are used in the non-trigger mode for pulsing the blue LEDs on
//the side of the raygun. I set them to zero here so that it begins the pulse sequence
//fresh if it drops out of the loop.
d = 0;
pulse = 0;
}
//Make sure the red LEDs are off, cuz we're not in the trigger loop
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
//The blue LED fade works like this: variable "d" keeps track of how many times we've been through
//the loop, and is compared against the "pulse" variable. Every 50 times through the loop, "pulse"
//is either incremented or decremented depending on whether it's fading up or down, as determined
//by the "up" variable.
if (d <= pulse)
{
digitalWrite(2, HIGH); //Make sure they're on when they need to be...
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
}
else if (d > pulse)
{
digitalWrite(2, LOW); //...and make sure they're off when they need to be.
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
}
d++; //increment the loop count
if (d >= 50) //If we're at the top of the loop count...
{
d = 0; //...reset the loop count...
//...and check to see if we're fading up or down. If we're fading up...
if (up == 1)
{
pulse++; //Increment the pulse width
if (pulse > 50) up = 0; //If we're at the top of the pulse width, change direction and go down
}
//Or if we're fading down...
else if (up == 0)
{
pulse--; //Decrement the pulse width
if (pulse <= 0) up = 1; //If we're at the bottom of the pulse width, change direction and go up
}
}
}
}
Hope you all have a fun and safe Halloween. As always leave any comments or questions below! Cheers!
Pete: I think you made a small mistake in your schematic. Didn't you want to have the resistor on the A3 input connected as a pulldown resistor to ground instead of being in series with the microcontroller input?
The schematic is right, but my thinking may have been wrong. I don't like to tie stuff to VCC directly, so I'd do it through a resistor. But in retrospect, it should prolly have something pulling it down when you're not on the trigger. In practice, it hasn't been a problem, but there you are.
or use the internal pullup and pull the pin low on the trigger and save a part. $0.01 off the BOM! LOL.
LOVE the Top Rope magnet. :D
Should have skipped the resistors & PWMed everything.
Should have skipped the resistors & PWMed everything.
Couldn't you do the same thing with a 556 (dual 555) and a 4017 (cmos counter)?
One 555 could handle the blue flashing. The other could be turned on by the trigger and warble the sound. The counter would divide down the pulses to flash the shooting leds.
Maybe not as simple or configurable as using a small controller though. This looks like a fun project and it would be great to do in a 8 pin micro as well.
I see where are setting pulse, but I don't see how you are using it's value to affect the LEDs. Is pulse a keyword that means something to the compiler?
Propably not. As far as I can see he is not showing us the whole code. Maybe he rigged the timer (that is doing the PWM) overflow interrupt to push the pulse value (it is a global variable, why would it need to be global otherwise?) into the PWM register.
Also, why is it an int (16-bits signed in most AVR compilers AFAIK)?
uint8_t would be enough.
What compiler is used? Doesnt look like code I'd write for avr-gcc.
analogRead()/digitalWrite() is nowhere to be seen, nothing is included, etc.
Also, using the ADC to read the trigger seems a bit excessive...
The PWMs are all bit-banged off the instruction clock in for/while loops. See the line "if d <= pulse" right after the "while trigger" loop. Looks a lot like some my own one-hour-project hack code, don't expect everything to be properly thought out. Pretty neat project even so.
What he said. Like I said before, compiled in Arduino and not optimized for anything. NOT ANYTHING! There are a zillion different ways I could have pulled this off. This was the quickest for me.
I still don't get how setting the variable pulse affects anything. What is the secret sauce there?
Variable d counts 0 - 49 (on >=50 it gets reset and pulse is modified). When d is less than (or equal to) pulse, blue leds are on, when d is more than pulse, blue leds are off. I must be blind to not have noticed that the last time I wrote something here above.... (facepalm)
"I knew of course when I pull the trigger I want everything to go nuts."
Oh, Pete. You and your technical mumbo-jumbo.
AAAAaaaahh!! !@#$^%I$%^&^#$^^^&(^$^#&(***)^()^!@#! You shot a hole in my comment!!!
Wait, why is this at the top? It's 0'd!
You may have discerned a wee bit of a sort-order bug.
Like an unsigned int or something? It's-nice-that-you-fixed-the-going-off-the-page-bug-though-I-wonder-what-caused-it-in-the-first-place...
like an oops-i-forgot-to-initialize-a-value bug, fix will be pushed shortly.
ah the pesky initialization procedure ;)
Hey Pete, Any where I can download all of the epp's. Or podcasts or something?
I LOVE THEM
So will there still be an According to Pete in November?
Oh... I 'spose.
Did I miss it? I was looking forward to it.
They should call you Pistol Pete!!!
Not allowed, it's been trademarked by the University of Wyoming.
I love the lens you shot this in Greg. Gotta love super short focal length, with super wide angle.
Nice hack.
Oh, and could you do something on multiplexing for LED matrixes please? That would help so many people who want to make microcontroller Snake games...
Huh? where did duplicate go??
I zapped it.
Cool. Perhaps a "zap" button for our own comments in the future if we asked a redundant question?
reply | report | edit | zap
lol.
Thanks pete. I enjoy the vids, this is usually the same process I follow to hack stuff apart.. where were you when I was 15 and a budding hacker?
OK, I lied. It is essentially written in Arduino. I tend to shy away from that descriptor since I'm not the most Arduino library savvy guy. But you look at that code... and yeah, that's more-or-less Arduino.
Also, the SKU for the trigger switch is COM-00098 (http://www.sparkfun.com/products/98).
The arduino has a tone command built into the standard library that might have been easier to use.
http://arduino.cc/en/Reference/Tone
You should try delayMicroseconds(uS);
Great Halloween Hack! That's classic!!! One of my favorite things is juicing up cheap toys. There is nothing like a journey to the dollar store to get those creative ideas flowing! Great vid Pete!
Like hooking up an rc car to 5x its rated voltage? (it went fast) :)