Cylon Project
Greetings,
Is it possible to blink LED's and play tones at the same time with the BS2? I am trying to come up with a satisfactory project wherein the LED's chase back and forth with the 'Cylon' sound playing. So far I've written separate code for each function, but can't figure out how to have them combined. I do have a file written by someone else that does work - but I am unhappy with the frequency used. I think mine is much closer to the actual Cylon/Knight Rider sound.
I'll attach the three separate codes as well as a photo of the circuit. Any help will be much appreciated.
Post Edited (servello) : 11/11/2009 8:23:38 AM GMT
Is it possible to blink LED's and play tones at the same time with the BS2? I am trying to come up with a satisfactory project wherein the LED's chase back and forth with the 'Cylon' sound playing. So far I've written separate code for each function, but can't figure out how to have them combined. I do have a file written by someone else that does work - but I am unhappy with the frequency used. I think mine is much closer to the actual Cylon/Knight Rider sound.
I'll attach the three separate codes as well as a photo of the circuit. Any help will be much appreciated.
Post Edited (servello) : 11/11/2009 8:23:38 AM GMT
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·"If you build it, they will come."
To go into some more detail that Erco was stating and that you are running into, is that the BASIC Stamp in a single thread operator; which means it can only do a single task as a time. So you will not able to toggle and LED while playing some music at the same time. However, what you can so is put the sound that you want to create in the middle of the routines you have blinking the LEDS.
For example:
· TOGGLE LED
· Generate·a Sound
· TOGGLE LED
· Generate·a Sound
· and so on
So you will have to break up the program and perhaps use the frequency in the same manor you have now where that value is the tone you want to use, but you will have to increment that value other than a FOR...NEXT loop. I hope that helps
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Respectfully,
Joshua Donelson
www.parallax.com
*** Begin Rant ***
I take great care in posting forum messages. I am always polite, I obey the forum rules, and I am always extremely descriptive and usually include code and images. On top of that, I search high and low both on the forum and on the internet in general - for the answers I seek.
I mention this because most of my posts seem to be either ignored or passed off with a quick retort. I once asked a question and reminded a forum member that he had forgotten to include an attachment from a previous post - only to have the original poster reply to everyone in the thread except me!
I have seen many posters that are rude, type terribly, ignore the rules ask questions that have been answered Ad Nauseum without bothering to do a simple search - for instance, this one comes up all the time - - "Basic Stamp Not Found" - -
Yet these same posters quite often get:
a) Many replies
b) Quick replies
c) Verbose answers
Forgive me, but I just don't understand why this is. I have even asked if I had done something wrong, or offended someone or broke a forum rule. And yet, nothing.
*** End Rant ***
Again, thanks for the reply. It will be helpful.
Dominic
Dominic,
This does happen from time to time, but do not feel you are the only one to have posts which get quick short replies, or none at all. Many times it deals with subject matter, which other people are not interested in. It is in human nature to group around things you enjoy and distance yourself from items you do not.
There will always be a percentage of people who do not respond to posts well, and possibly leave a person out. I do not let this affect me. I am who I am, and will help where I can no matter how others do me.
There are many here who help plenty. Others come to get information and leave as fast as they get the answer.
Most active participants expect a hierarchy which should work but sometimes doesn't. The upper level people help the middle, the middle help the lower, so on and so forth. Unfortunately it doesn't always work this way.
When the previous breaks down, the answers sometimes get specific with verbage. Have you ever talked to someone too educated in a specific subject matter. When I do, my eye's are crossed within the first two minutes of conversation. This happens when the upper guys help the lower guys directly. They forget that their terminology may be over the helpie's head. This is not point at you in this case, just the way it happens much of the time.
You just have to get in here and roll around in the mud with the rest of us.
I hope the situation doesn't run you away. We can always use more active members of the forum.
You will find.......many people here are tinkerers. They want to figure out a solution for themselves, and can't understand why someone couldn't or wouldn't want to. They try to inspire you to try different things, for you to be the same. There are many things here because of diversity, and people finding new ways of doing things.
James L
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
James L
Partner/Designer
Lil Brother SMT Assembly Services
Are you addicted to technology or Micro-controllers..... then checkout the forums at Savage Circuits. Learn to build your own Gizmos!
Thank you for your reply. Your post was both thoughtful and instructive.
I guess because *I* think and act a certain way, I expected *everyone else* to do the same. Which is of course, absurd. This forum consists of people who *volunteer* their time and know-how to provide help and direction; which they do very well. We are indeed lucky to have this great community.
Anyway . . .
I hope a few more people will post some suggestions as this is a fundamental issue with the BS2 (ability to only do one thing at a time), and would be very helpful to all newbies.
Take care,
Dominic
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Deus tantum me iudicabit
' musical notes -- word/byte pairs -- word is freq, byte is ms duration IN 10MS UNITS (to save space) ' song "ends" with a full Word $FFFF (opposite of Z terminated) ' a 0 for the note means no volume, but a pause instead (rest) ' note that if you want to do servo control interleaved with sounds, you couldn't ' have duration of much more than 15ms or so speaker PIN 1 left CON 0 right CON 1 Song0 DATA Word 1500, 100, Word 0, 100, Word 2000, 100, Word 3000, 100, Word $FFFF Song1 DATA Word 1000, 50, Word 0, 50, Word 1200, 50, Word 1400, 50, Word $FFFF Song2 DATA Word 1000, 50, Word 0, 50, Word 1200, 50, Word 1400, 50, Word $FFFF Song3 DATA Word 1000, 200, Word $FFFF 'etc... leds VAR OUTH ' 8 leds on pins 8-15 work VAR Word ' work var addr VAR work ' alias for clarity freq VAR Word ' for freqout dur VAR Word ' for freqout songIdx VAR Byte ' index offset for current word/byte pair of song song VAR Nib ' which song currently playing ledDir VAR Bit ' direction of cylon lights leds = $00 ' all off DIRH = $FF ' make outputs Start: song = 2 songIdx = 0 leds = %00000001 Main: ' first play current note... LOOKUP song, [noparse][[/noparse] Song0, Song1, Song2, Song3 ], addr READ addr+songIdx, Word freq, dur ' get freq and dur IF freq <> $FFFF THEN ' not end of song? songIdx = songIdx + 3 ' prep for next pair IF freq = 0 THEN ' pause? PAUSE dur ELSE freq = freq */ frAdj ' see stamp manual for conversion for different flavors of stamps dur = ( dur * 10 ) */ durAdj ' conv to ms, then to this stamp's duration flavor FREQOUT speaker, freq, dur ENDIF ELSE song = song + 1 ' next song song = song & %11 ' limit to songs 0-3 ENDIF IF ledDir = left THEN leds = leds << 1 ledDir = leds.BIT7 ' if last led is lit, change direction to right ELSE leds = leds >> 1 ledDir = ~leds.BIT0 ' if first led is lit, change direction again ENDIF GOTO Main
The probem is that your led animation will never be smooth -- the time to play sounds will vary, so to make it more interesting, we'll have a padding pause that will be adjusted after each sound (or not) to make things *reasonably* consistent. You won't get fast animation though, you need to pick a time for the padding that is a little more than your longest sound:
' musical notes -- word/byte pairs -- word is freq, byte is ms duration IN 10MS UNITS (to save space) ' song "ends" with a full Word $FFFF (opposite of Z terminated) ' a 0 for the note means no volume, but a pause instead (rest) ' note that if you want to do servo control interleaved with sounds, you couldn't ' have duration of much more than 15ms or so speaker PIN 1 left CON 0 right CON 1 maxPad CON 2000 ' 2 seconds between frames, way too long, but you get the idea Song0 DATA Word 1500, 100, Word 0, 100, Word 1900, 100, Word 1900, 100, Word $FFFF Song1 DATA Word 1000, 50, Word 0, 50, Word 1200, 50, Word 1400, 50, Word $FFFF Song2 DATA Word 1000, 50, Word 0, 50, Word 1200, 50, Word 1400, 50, Word $FFFF Song3 DATA Word 1000, 200, Word $FFFF 'etc... leds VAR OUTH ' 8 leds on pins 8-15 work VAR Word ' work var addr VAR work ' alias for clarity freq VAR Word ' for freqout dur VAR Word ' for freqout songIdx VAR Byte ' index offset for current word/byte pair of song song VAR Nib ' which song currently playing pausePad VAR Word ledDir VAR Bit ' direction of cylon lights leds = $00 ' all off DIRH = $FF ' make outputs Start: song = 2 songIdx = 0 leds = %00000001 Main: pausePad = maxPad ' reset for this frame ' first play current note... LOOKUP song, [noparse][[/noparse] Song0, Song1, Song2, Song3 ], addr READ addr+songIdx, Word freq, dur ' get freq and dur IF freq <> $FFFF THEN ' not end of song? songIdx = songIdx + 3 ' prep for next pair pausePad = pausePad - dur '[b]this is the crucial part[/b] IF freq = 0 THEN ' pause? PAUSE dur ELSE freq = freq */ frAdj ' see stamp manual for conversion for different flavors of stamps dur = ( dur * 10 ) */ durAdj ' conv to ms, then to this stamp's duration flavor FREQOUT speaker, freq, dur ENDIF ELSE song = song + 1 ' next song song = song & %11 ' limit to songs 0-3 ENDIF PAUSE pausePad ' [b]the other crucial part[/b] IF ledDir = left THEN leds = leds << 1 ledDir = leds.BIT7 ' if last led is lit, change direction to right ELSE leds = leds >> 1 ledDir = ~leds.BIT0 ' if first led is lit, change direction again ENDIF GOTO Main
So in the second example, you should get approx. 2 secs between each shift of the leds, with time between for sound of varying length. Of course, this also has a problem, which is that you will have varying space between sounds. Really depends on the kind of sounds/speed you want. There are other tricks for interleaving, but this may help get you started. Of course, other micros are better suited to tasks like this which appear to run concurrently (e.g. Prop, SX, AVR, etc).
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Thanks, Zoot.
I've either got alot of research and work ahead of me or I might just try to accomplish this with an Arduino. I have no parts for Propeller or SX chips (I also have no idea of how to program them). I do have an Arduino and can maybe find some pre-written code already done.
Best,
Dominic
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Deus tantum me iudicabit
use one to generate sound and send a pulse to the other controller to start the led cycle?
ie basic stamp is coded to play sounds and arduino is coded to control led's
Dominic,
That is one draw back to a processor like the Basic Stamp. Because the LED's and the sound are active concurrently, it is hard to control both with a Stamp. That is why many us the more experienced guys have moved up to the Propeller or the SX.
I personally think the Propeller is the better choice of the two, but you are correct about the programming. The propeller's programming can be intimidating.
But, I will say, if you ever start with a Propeller, you will be reluctant to use anything else. Having 8 independent processes going on at once is great. Each clicking along, playing nice with each other (but still doing their own thing)..........it's really hard to go back to a linear type process.
I'll just about use a propeller to blink a simple LED....even though is is like killing a fly with a sledgehammer. I like it's raw power, and rather use it, unless the process is just too simple not to (or I can't justify it's price for the project).
Sorry the Stamp isn't working out for your task, but you have found a reason to dive deeper in to the addictive realm of micro-processor electronics.
James L
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
James L
Partner/Designer
Lil Brother SMT Assembly Services
Are you addicted to technology or Micro-controllers..... then checkout the forums at Savage Circuits. Learn to build your own Gizmos!
That's a idea I hadn't thought of. Thanks, modkil.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Deus tantum me iudicabit
The BASIC Stamp is my Microcontroller of choice and I'll never stop playing with it. And I just might delve into the Propeller one day.
Until then, do you think I could offload the sound to a ISD_25120P and run it through the BS2?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Deus tantum me iudicabit
Dominic,
That sounds like a great idea. Although you would only be controlling the ISD25120p with the stamp for syncing the sound with the lights. The stamp will be controlling the lights, and queuing the ISD25120P for synced sound.
I think that should work. Getting all the bits to play in the right time frame may be a task, but I think it can be done.
James L
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
James L
Partner/Designer
Lil Brother SMT Assembly Services
Are you addicted to technology or Micro-controllers..... then checkout the forums at Savage Circuits. Learn to build your own Gizmos!
I had a thought -- here's a variation of my code -- in this case it checks for a maximum duration on sound data and compares to the maximum frame -- this lets as many sounds play in a row as "will fit" within the LED frame:
' musical notes -- word/byte pairs -- word is freq, byte is ms duration IN 10MS UNITS (to save space) ' song "ends" with a full Word $FFFF (opposite of Z terminated) ' a 0 for the note means no volume, but a pause instead (rest) ' note that if you want to do servo control interleaved with sounds, you couldn't ' have duration of much more than 15ms or so speaker PIN 1 left CON 0 right CON 1 maxPad CON 75 ' 75 ms between frames, pretty short, but leads to nicer LED animation ' technically you could also make this a VARIABLE which would give you LED speed changing ability, while ' still fitting sounds in as best they can ' max allowed duration length is 70ms, anything larger won't get played (error checking) Song0 DATA Word 1500, 70, Word 0, 40, Word 1900, 33, Word 1900, 67, Word $FFFF Song1 DATA Word 1000, 50, Word 0, 50, Word 1200, 50, Word 1400, 50, Word $FFFF Song2 DATA Word 1000, 50, Word 0, 50, Word 1200, 50, Word 1400, 50, Word $FFFF Song3 DATA Word 1000, 65, Word $FFFF 'etc... leds VAR OUTH ' 8 leds on pins 8-15 work VAR Word ' work var addr VAR work ' alias for clarity freq VAR Word ' for freqout dur VAR Word ' for freqout songIdx VAR Byte ' index offset for current word/byte pair of song song VAR Nib ' which song currently playing pausePad VAR Word ledDir VAR Bit ' direction of cylon lights leds = $00 ' all off DIRH = $FF ' make outputs Start: song = 2 songIdx = 0 leds = %00000001 Main: pausePad = maxPad ' reset for this frame Play_Note: ' first play current note... LOOKUP song, [noparse][[/noparse] Song0, Song1, Song2, Song3 ], Word addr READ addr+songIdx, Word freq, dur ' get freq and dur IF freq <> $FFFF THEN ' not end of song? '[b]error check duration [/b] IF dur > maxPad THEN Play_Note ' bad duration, try next note '[b]check dur against current padding value to see if you can fit it in this frame[/b] IF dur <= pausePad THEN pausePad = pausePad - dur '[b]this is the crucial part[/b] IF freq = 0 THEN ' pause? PAUSE dur ELSE freq = freq */ frAdj ' see stamp manual for conversion for different flavors of stamps dur = ( dur * 10 ) */ durAdj ' conv to ms, then to this stamp's duration flavor FREQOUT speaker, freq, dur ENDIF songIdx = songIdx + 3 ' prep for next pair GOTO Play_Note ' try next note ENDIF ELSE song = song + 1 ' next song song = song & %11 ' limit to songs 0-3 ENDIF PAUSE pausePad ' [b]the other crucial part[/b] IF ledDir = left THEN leds = leds << 1 ledDir = leds.BIT7 ' if last led is lit, change direction to right ELSE leds = leds >> 1 ledDir = ~leds.BIT0 ' if first led is lit, change direction again ENDIF GOTO Main
This code should do cylon lights on 8 leds at approx 75ms per each, and play "songs" within the frames.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Post Edited (Zoot) : 11/13/2009 6:09:11 AM GMT
Still, it sounds a bit silly to think that nobody out there has done this before. The LED Chaser is one of the foundational circuits that almost every newcomer attempts. I should think that the accompanying sound effect would be the next logical step.
Thanks for everyone's input.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Deus tantum me iudicabit
Damn, Zoot you're programming skills are impressive!
I am in no way capable of writing code like that; I'm going to have to spend some time with this. I'll try to see what you've got going on there.
Dominic
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Deus tantum me iudicabit
The short version is something like this:
Main: counter = counter + 1 ' the master "frame" counter -- everything else scales from this Sensors: IF counter & %0111= 0 THEN ' every 8 frames do the pings if they're ready IF leftRight = 0 THEN 'read left hand ping leftRight = 1 ELSE 'read right hand ping leftRight = 0 ENDIF ENDIF Behaviors: ' these run only every 32 frames, which means sound, display, motor updates happen very quickly, and sensors are probably updated IF counter & %11111 <> 0 THEN Behaviors_Done IF leftSonar < 100 THEN 'turn right ELSEIF rightSonar < 100 THEN 'turn left ENDIF 'etc Behaviors_Done: Display: LOOKUP counter & %01, [noparse][[/noparse] LEDs << 1 ], LEDs ' every other "frame" and shift the leds LOOKUP LEDs, [noparse][[/noparse] %1 ], LEDs ' if they roll off the left, start from right again Sound: IF counter & %1111 = 0 THEN ' only ever 16 frames update sound stuff ' make a sound or play "part" of a song ENDIF Motors: IF counter & %11 = 0 THEN ' motors updated every 4 frames SEROUT lotsOfDataToMotorController ENDIF GOTO Main
I'm way simplifying here, but hopefully it gives an idea. Ideally, everything that can be should be LOOKUPS rather than IF/THEN/ELSE/ENDIF --- lookups always take about the same time to evaluate *regardless of the outcome* which means the the loop will run more consistently in speed -- which leads to a smoother appearance. IF/THEN is notorious for taking wildly different execution times depending on the results of the various evaluations.
In my actual implementations I usually have separate variable set up for the frame speeds for each module -- and I use modulo for varying speeds (esp. with Words which don't roll over as quickly), i.e. a speed controlled led flash in the same context as above:
Main: counter = counter + 1 Display: IF counter // speed = 0 THEN ' change LEDs ENDIF GOTO Main
Where "speed" lets the leds change after 1 tick, 2 ticks, 3 ticks, etc.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Post Edited (Zoot) : 11/13/2009 6:45:07 AM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Deus tantum me iudicabit
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
LEDs VAR OUTA ' leds on pins 0-3 DIRA = %1111 counter VAR Word speeds VAR Byte(4) idx VAR Nib Start: DEBUG CLS DEBUG "Speeds may be from 1 to 255. 1 is faster; 255 is slowest." FOR idx = 0 TO 3 DEBUG CR, "Enter Speed for LED #", DEC1 idx, ":" DEBUGIN DEC speeds(idx) IF speeds(idx) = 0 THEN speeds(idx) = 1 ENDIF NEXT Main: FOR idx = 0 TO 3 LOOKUP counter//speeds(idx) [noparse][[/noparse] ~LEDs.BIT0(idx) ], LEDs.BIT0(idx) NEXT counter = counter + 1 PAUSE 10 ' otherwise may be too fast .... GOTO Main
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Post Edited (Zoot) : 11/13/2009 6:59:39 AM GMT
You should give classes in LED's - with downloadable pdf's - [noparse];)[/noparse]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Deus tantum me iudicabit