HELP...Ghostbusters proton pack
Hello everyone,
I need some help. I'm new to the Propeller chip and programming. I'm trying to program the lights for a buddys Proton Pack. A few years ago I did the lights and sound fx for it using a 555 and a 4017 for the lights and a small sound chip for all the fx, but I'm wanting lower the amount of batterys he has to use, plus the propeller is much more cooler! It uses less power and you have more control over the project. You can see it on YouTube if you search "brettfields", it's labeled "My ghostbusters proton pack with lights and sound" so you can have an idea as to what I'm trying to do.
I have the code writen, but I have a feeling that its too long and a bit messy because it keeps freezing up on me. It will start back up on it's own, but I know that it shouln't be doing that.
I was hoping that someone here could give me a hand on cleaning it up. I'm new to this and don't know what I need to do.
I have attached the file if anyone has the time to help me out. I would be forever thankful. I would also like for the first part of "Routine_3" to be interupted when the button is pressed. Right now it finishes it's cycle before changing and I have no idea how to get it to do that.
Thank you again!!!
I need some help. I'm new to the Propeller chip and programming. I'm trying to program the lights for a buddys Proton Pack. A few years ago I did the lights and sound fx for it using a 555 and a 4017 for the lights and a small sound chip for all the fx, but I'm wanting lower the amount of batterys he has to use, plus the propeller is much more cooler! It uses less power and you have more control over the project. You can see it on YouTube if you search "brettfields", it's labeled "My ghostbusters proton pack with lights and sound" so you can have an idea as to what I'm trying to do.
I have the code writen, but I have a feeling that its too long and a bit messy because it keeps freezing up on me. It will start back up on it's own, but I know that it shouln't be doing that.
I was hoping that someone here could give me a hand on cleaning it up. I'm new to this and don't know what I need to do.
I have attached the file if anyone has the time to help me out. I would be forever thankful. I would also like for the first part of "Routine_3" to be interupted when the button is pressed. Right now it finishes it's cycle before changing and I have no idea how to get it to do that.
Thank you again!!!


Comments
below is the code how I would do it
CON 'Set up the clock mode _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 '5 MHz clock * 16x PLL = 80 MHz system clock speed 'you should use constants instead of hardcoded digits 'this means a little bit more typing at the beginning and much less typing 'if you want to change numbers. And you can't forget any place because 'the constant is already in each place you use it LED_0 = 0 'use self-explaining names LED_9 = 9 LED_10 = 10 LED_13 = 13 LED_19 = 19 LED_28 = 28 Speed_1 = 8 Speed_2 = 1 Speed_3 = 15 Button = 15 'use selfexplainig names VAR 'Globally accessible variables long cogStack1[100] long cogStack2[100] long cogStack3[100] long cogStack4[100] long routine1_cog, routine2_cog, routine3_cog, routine4_cog OBJ led: "Power Cell.spin" led2: "4 red leds" led3: "4 red leds" led4: "4 red leds" PUB Main ' First public method in the top .spin file starts execution, runs in cog 0 'Start parallel routines routine1_cog := cognew(MySelfExplainingMethodname, @cogStack1) + 1 { you shouldn't use the same longs for different cog-stacks! routine2_cog := cognew(Parallel_Routine_2, @cogStack[50]) + 1 routine3_cog := cognew(Parallel_Routine_3, @cogStack[50]) + 1 routine4_cog := cognew(Parallel_Routine_4, @cogStack[50]) + 1 } routine2_cog := cognew(Parallel_Routine_2, @cogStack2) + 1 routine3_cog := cognew(Parallel_Routine_3, @cogStack3) + 1 routine4_cog := cognew(Parallel_Routine_4, @cogStack4) + 1 repeat 'main loop - repeats forever 'names of methods should be selfexplaining 'use constants for pin-numbers PUB MySelfExplainingMethodname | BitPattern 'dira[0..19]~~ 'you shouldn't setup IO-pins that aren't used by the code dira[LED_0..LED_9]~~ repeat BitPattern := 1 repeat LED_9 - LED_0 + 1 outa[LED_0..LED_9] := BitPattern 'set Output-Pins BitPattern <<= 1 'shift one bits to the left BitPattern := BitPattern + 1 'add 1 to set bit 0 high again waitcnt(clkfreq / Speed_1 + cnt) { repeat outa[0..9] := 00000000 waitcnt(clkfreq/8 + cnt) outa[0..9] := 00000001 waitcnt(clkfreq/8 + cnt) outa[0..9] := 00000011 waitcnt(clkfreq/8 + cnt) outa[0..9] := 00000111 waitcnt(clkfreq/8 + cnt) outa[0..9] := 00001111 waitcnt(clkfreq/8 + cnt) outa[0..9] := 00011111 waitcnt(clkfreq/8 + cnt) outa[0..9] := 00111111 waitcnt(clkfreq/8 + cnt) outa[0..9] := 01111111 waitcnt(clkfreq/8 + cnt) outa[0..9] := 11111111 waitcnt(clkfreq/8 + cnt) outa[0..9] := 11111111 waitcnt(clkfreq/8 + cnt) outa[0..9] := 11111111 waitcnt(clkfreq/8 + cnt) } PUB Parallel_Routine_2 | BitPattern dira[LED_10..LED_13]~~ repeat BitPattern := 1 repeat LED_13 - LED_10 + 1 outa[LED_10..LED_13] := BitPattern 'set Output-Pins BitPattern <<= 1 'shift bits one to the left BitPattern := BitPattern + 1 'add 1 to set bit 0 high again waitcnt(clkfreq / Speed_2 + cnt) { repeat outa[10..13] := 01 waitcnt(clkfreq + cnt) outa[10..13] := 10 waitcnt(clkfreq + cnt) outa[10..13] := 00 waitcnt(clkfreq + cnt) outa[10..13] := 00 waitcnt(clkfreq + cnt) } PUB Parallel_Routine_3 | BitPattern dira[LED_19..LED_28]~~ repeat BitPattern := 1 repeat LED_28 - LED_19 + 1 outa[LED_19..LED_28] := BitPattern 'set Output-Pins BitPattern <<= 1 'shift bits one to the left BitPattern := BitPattern + 1 'add 1 to set bit 0 high again waitcnt(clkfreq / Speed_3 + cnt) { repeat until ina[15] == 1 outa[19..28] := 00000000 waitcnt(clkfreq/15 + cnt) outa[19..28] := 00000001 waitcnt(clkfreq/15 + cnt) outa[19..28] := 00000011 waitcnt(clkfreq/15 + cnt) outa[19..28] := 00000111 waitcnt(clkfreq/15 + cnt) outa[19..28] := 00001111 waitcnt(clkfreq/15 + cnt) outa[19..28] := 00011111 waitcnt(clkfreq/15 + cnt) outa[19..28] := 00111111 waitcnt(clkfreq/15 + cnt) outa[19..28] := 01111111 waitcnt(clkfreq/15 + cnt) outa[19..28] := 11111111 waitcnt(clkfreq/15 + cnt) outa[19..28] := 11111111 waitcnt(clkfreq/15 + cnt) outa[19..28] := 11111111 waitcnt(clkfreq/15 + cnt) outa[19..28] := 11111111 waitcnt(clkfreq/15 + cnt) outa[19..28] := 11111111 waitcnt(clkfreq/15 + cnt) outa[19..28] := 01111111 waitcnt(clkfreq/15 + cnt) outa[19..28] := 00111111 waitcnt(clkfreq/15 + cnt) outa[19..28] := 00011111 waitcnt(clkfreq/15 + cnt) outa[19..28] := 00001111 waitcnt(clkfreq/15 + cnt) outa[19..28] := 00000111 waitcnt(clkfreq/15 + cnt) outa[19..28] := 00000011 waitcnt(clkfreq/15 + cnt) 'this part of the code executes as long as ina[15] == 0 'the code above will only be executed again if ina[15] <> 0 repeat until ina[15] == 0 outa[19..28] := 00110000 waitcnt(clkfreq/15 + cnt) outa[19..28] := 01001000 waitcnt(clkfreq/15 + cnt) outa[19..28] := 10000100 waitcnt(clkfreq/15 + cnt) outa[19..28] := 00000010 waitcnt(clkfreq/15 + cnt) outa[19..28] := 00000001 waitcnt(clkfreq/15 + cnt) outa[19..28] := 00000010 waitcnt(clkfreq/15 + cnt) outa[19..28] := 10000100 waitcnt(clkfreq/15 + cnt) outa[19..28] := 01001000 waitcnt(clkfreq/15 + cnt) } PUB Parallel_Routine_4 | local_var1, local_var3, local_var_etc dira[10..13]~~ 'this code runs through and then stops outa[10..13] := 01 waitcnt(clkfreq/15 + cnt) outa[10..13] := 10 waitcnt(clkfreq/15 + cnt) outa[10..13] := 00 waitcnt(clkfreq/15 + cnt) outa[10..13] := 10 waitcnt(clkfreq/15 + cnt) outa[10..13] := 01 waitcnt(clkfreq/15 + cnt) outa[10..13] := 00 waitcnt(clkfreq/15 + cnt) outa[10..13] := 10 waitcnt(clkfreq/15 + cnt) outa[10..13] := 01 waitcnt(clkfreq/15 + cnt)if everything is cleaned up it looks like this
CON 'Set up the clock mode _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 '5 MHz clock * 16x PLL = 80 MHz system clock speed 'you should use constants instead of hardcoded digits 'this means a little bit more typing at the beginning and much less typing 'if you want to change numbers. And you can't forget any place because 'the constant is already in each place you use it LED_0 = 0 'use self-explaining names LED_9 = 9 LED_10 = 10 LED_13 = 13 LED_19 = 19 LED_28 = 28 Speed_1 = 8 Speed_2 = 1 Speed_3 = 15 Button = 15 VAR 'Globally accessible variables long cogStack1[100] long cogStack2[100] long cogStack3[100] long routine1_cog, routine2_cog, routine3_cog long BitPatternArray[8] PUB Main ' First public method in the top .spin file starts execution, runs in cog 0 routine2_cog := cognew(FourRedLEDs_1, @cogStack2) + 1 routine3_cog := cognew(Parallel_Routine_3, @cogStack3) + 1 PowerCell PUB PowerCell | BitPattern dira[LED_0..LED_9]~~ repeat BitPattern := 1 repeat LED_9 - LED_0 + 1 outa[LED_0..LED_9] := BitPattern 'set Output-Pins BitPattern <<= 1 'shift one bits to the left BitPattern := BitPattern + 1 'add 1 to set bit 0 high again waitcnt(clkfreq / Speed_1 + cnt) PUB FourRedLEDs_1 | BitPattern dira[LED_10..LED_13]~~ repeat BitPattern := 1 repeat LED_13 - LED_10 + 1 outa[LED_10..LED_13] := BitPattern 'set Output-Pins BitPattern <<= 1 'shift bits one to the left BitPattern := BitPattern + 1 'add 1 to set bit 0 high again waitcnt(clkfreq / Speed_2 + cnt) PUB Parallel_Routine_3 | BitPattern, Idx dira[LED_19..LED_28]~~ 'initialise BitPatternArray BitPatternArray[0] := 00110000 BitPatternArray[1] := 01001000 BitPatternArray[2] := 10000100 BitPatternArray[3] := 00000010 BitPatternArray[4] := 00000001 BitPatternArray[5] := 00000010 BitPatternArray[6] := 10000100 BitPatternArray[7] := 01001000 repeat if ina[Button] == 0 'if button is NOT pressed LED-bar up / down BitPattern := 0 repeat LED_28 - LED_19 + 1 outa[LED_19..LED_28] := BitPattern 'set Output-Pins BitPattern <<= 1 'shift bits one to the left BitPattern := BitPattern + 1 'add 1 to set bit 0 high again waitcnt(clkfreq / Speed_3 + cnt) repeat LED_28 - LED_19 + 1 outa[LED_19..LED_28] := BitPattern 'set Output-Pins BitPattern >>= 1 'shift bits one to the right waitcnt(clkfreq / Speed_3 + cnt) if ina[Button] == 1 'if button is pressed LED-bar middle / left/right repeat Idx from 0 to 7 outa[LED_19..LED_28] := BitPatternArray[Idx] 'set Output-Pins waitcnt(clkfreq / Speed_3 + cnt)best regards
Stefan
You might also take a look at Kye's LED object as it has a few more features you could probably take advantage of for this project.
How about posting a picture of your project? Here's mine. I haven't added the LEDs yet. (Shame on me)
Jeff
way cool design ! If you aren't a puristic retro-man how about adding sound?
Especially a voice in robotic style saying "cage-energy down at 10% breakdown in 30 seconds"
or "he slimed me!" or any other famous sentence from the film (don't remember them. 1985 is too long ago)
best regards
Stefan
P.S.: Edit:OMG these guys spoke a detailed description of the proton-pack into a STARTREK replicator beamed it back through time into history
and voila: there it is the original proton-pack. http://www.youtube.com/watch?v=0Mzs023Lcbw
I wasn't in a hurry to get the audio done as it needs to be uncomfortably loud where this prop is used. (An outdoor parade). I've got the .wav file of the proton pack startup. If I can find a way to get it loud enough to "feel real" and still walk the parade route, it'll be added by next year.
Jeff
pub four_red_leds | idx dira[16..19] := %1111 repeat repeat idx from 0 to 3 outa[16..19] := 1 << idx waitcnt((clkfreq >> 1) + cnt)I do a lot of LED lighting control for high-end projects built by Hollywood FX and creature creator, Steve Wang. Have a look in these threads
-- http://forums.parallax.com/showthread.php?126553-Propeller-Powered-Starcraft-II-Marine
-- http://forums.parallax.com/showthread.php?134092-Hollywood-Fun-With-Propeller-powered-LEDs
-- http://forums.parallax.com/showthread.php?142149-Big-Hollywood-Fun-with-LEDs
What I tend to do is use a PWM controller for so I can have brightness levels (Steve likes undulating lights). The main loop launches the animations I want to run and then blends them together as required. We do the blending so that if we want to mix two animations on the same set of lights we can (for example, lightning simulation running over the top of a normal undulating pattern). I've attached fairly simple demo (will run on a Demo or QuickStart board) to show you the structure I use in my LED animation programs.
I found one problem....I'm an idiot....I uploaded the wrong file, I forgot to save the one I was working on before I uploaded it so it uploaded an older file.
I did make a few chnges that Stefan said need done, Thanks!!!
And JonnyMac, I think I'll use you code for the 4 red leds, Thanks!!!!
Here is link to the pack I did the lights and sounds for.
http://www.youtube.com/watch?v=imCLmomCoqw
Here is right code....
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 VAR long cogStack1[100] long cogStack2[100] long cogStack3[100] long cogStack4[100] long routine1_cog, routine2_cog, routine3_cog, routine4_cog OBJ led: "Power Cell.spin" led2: "4 red leds" led3: "4 red leds" led4: "4 red leds" PUB Main routine1_cog := cognew(Parallel_Routine_1, @cogStack1) + 1 routine2_cog := cognew(Parallel_Routine_2, @cogStack2) + 1 routine3_cog := cognew(Parallel_Routine_3, @cogStack3) + 1 routine4_cog := cognew(Parallel_Routine_4, @cogStack4) + 1 repeat PUB Parallel_Routine_1 dira[0..9]~~ repeat outa[0..9] := %0000000000 waitcnt(clkfreq/8 + cnt) outa[0..9] := %0000000001 waitcnt(clkfreq/8 + cnt) outa[0..9] := %0000000011 waitcnt(clkfreq/8 + cnt) outa[0..9] := %0000000111 waitcnt(clkfreq/8 + cnt) outa[0..9] := %0000001111 waitcnt(clkfreq/8 + cnt) outa[0..9] := %0000011111 waitcnt(clkfreq/8 + cnt) outa[0..9] := %0000111111 waitcnt(clkfreq/8 + cnt) outa[0..9] := %0001111111 waitcnt(clkfreq/8 + cnt) outa[0..9] := %0011111111 waitcnt(clkfreq/8 + cnt) outa[0..9] := %0111111111 waitcnt(clkfreq/8 + cnt) outa[0..9] := %1111111111 waitcnt(clkfreq/8 + cnt) PUB Parallel_Routine_2 dira[10..13]~~ repeat outa[10..13] := %0001 waitcnt(clkfreq/2*2 + cnt) outa[10..13] := %0010 waitcnt(clkfreq/2*2 + cnt) outa[10..13] := %0100 waitcnt(clkfreq/2*2 + cnt) outa[10..13] := %1000 waitcnt(clkfreq/2*2 + cnt) PUB Parallel_Routine_3 dira[19..28]~~ repeat until ina[14] == 1 outa[19..28] := %0000000000 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0000000001 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0000000011 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0000000111 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0000001111 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0000011111 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0000111111 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0001111111 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0011111111 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0111111111 waitcnt(clkfreq/15 + cnt) outa[19..28] := %1111111111 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0111111111 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0011111111 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0001111111 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0000111111 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0000011111 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0000001111 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0000000111 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0000000011 waitcnt(clkfreq/15 + cnt) repeat until ina[14] == 0 outa[19..28] := %0000110000 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0001001000 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0010000100 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0100000010 waitcnt(clkfreq/15 + cnt) outa[19..28] := %1000000001 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0100000010 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0010000100 waitcnt(clkfreq/15 + cnt) outa[19..28] := %0001001000 waitcnt(clkfreq/15 + cnt) PUB Parallel_Routine_4 dira[15..18]~~ repeat until ina[14] == 1 outa[15..18] := %0000 waitcnt(clkfreq/15 + cnt) outa[15..18] := %0000 waitcnt(clkfreq/15 + cnt) outa[15..18] := %0000 waitcnt(clkfreq/15 + cnt) outa[15..18] := %0000 waitcnt(clkfreq/15 + cnt) outa[15..18] := %0000 waitcnt(clkfreq/15 + cnt) outa[15..18] := %0000 waitcnt(clkfreq/15 + cnt) outa[15..18] := %0000 waitcnt(clkfreq/15 + cnt) outa[15..18] := %0000 waitcnt(clkfreq/15 + cnt) repeat until ina[14] == 0 outa[15..18] := %0101 waitcnt(clkfreq/15 + cnt) outa[15..18] := %0010 waitcnt(clkfreq/15 + cnt) outa[15..18] := %1100 waitcnt(clkfreq/15 + cnt) outa[15..18] := %0010 waitcnt(clkfreq/15 + cnt) outa[15..18] := %1001 waitcnt(clkfreq/15 + cnt) outa[15..18] := %0100 waitcnt(clkfreq/15 + cnt) outa[15..18] := %1010 waitcnt(clkfreq/15 + cnt) outa[15..18] := %0001 waitcnt(clkfreq/15 + cnt)Thanks again guys!!!!!pri routine_1 | idx ' launc with cognew dira[0..9] := %11_1111_1111 ' outputs repeat ' run forever repeat idx from 10 to 0 outa[0..9] := %11_1111_1111 >> idx waitcnt((clkfreq >> 3) + cnt) pri routine_2 | idx ' launch with cognew dira[10..13] := %1111 ' set outputs repeat ' run forever repeat idx from 0 to 3 outa[10..13] := 1 << idx waitcnt(clkfreq + cnt) pri routine_3 | idx ' launch with cognew dira[19..28] := %11_1111_1111 ' set outputs repeat ' run forever repeat idx from 10 to 1 outa[19..28] := %11_1111_1111 >> idx waitcnt((clkfreq / 15) + cnt) repeat idx from 0 to 9 outa[19..28] := %11_1111_1111 >> idx waitcnt((clkfreq / 15) + cnt) repeat until (ina[14] == 0) repeat idx from 0 to 7 outa[19..28] := R3bits[idx] waitcnt((clkfreq / 15) + cnt) dat word ' force alignment R3bits word %0000110000, %0001001000, %0010000100, %0100000010 word %1000000001, %0100000010, %0010000100, %0001001000 pri routine_4 | idx ' launch with cognew dira[15..18] := %1111 repeat ' run forever repeat until (ina[14] == 1) repeat 8 ' sync? outa[15..18] := %0000 waitcnt((clkfreq / 15) + cnt) repeat until (ina[14] == 0) repeat idx from 0 to 7 outa[15..18] := R4bits[idx] waitcnt((clkfreq / 15) + cnt) dat byte ' force alignment R4bits byte %0101, %0010, %1100, %0010 byte %1001, %0100, %1010, %0001BTW... you don't need such big stacks as your routines do not call others -- 16 longs for each will be plenty.
Another tip: When multiplying or dividing by powers of two (2, 4, 8, 16, etc.) using shift operators is faster/more efficient. Instead of:
...I would do this:
I'm just learning this coding stuff, I always just used hardware to get things to do what wanted. This is much more fun and uses less space!
Thank you to everyone that help!