Shop OBEX P1 Docs P2 Docs Learn Events
BS2: 2 leds ...one flashing fast to slow and the other going slow to fast. SIMULTANEOUSLY — Parallax Forums

BS2: 2 leds ...one flashing fast to slow and the other going slow to fast. SIMULTANEOUSLY

Hello,

I'm a newbee to the BS2 world. I'm trying to create a code that will run 2 leds simultaneously .
One flashing from slow 1000ms to fast 1ms and the other doing the opposite ....1ms to 1000ms at the SAME TIME. I know it probably has to do with a nested loop or an IF THEN type command but i'm at a loss. Any help would be greatly appreciated.

Thank you,

Comments

  • PublisonPublison Posts: 12,366
    edited 2018-09-04 12:47
    Welcome to the forums!

    Unfortunately, you can not do what you want with the Basic Stamp, as it has to complete the one task before doing the next. It would be easy with the Propeller chip.

    Maybe I don't completely understand the original question.
  • I wonder if Publison misread the OP's requirements. If I properly understand what he is asking, it ought to be easy for BS2.

    OP: can you post what you have so far?
  • kwinnkwinn Posts: 8,697
    edited 2018-09-04 15:53
    adam1971 wrote: »
    Hello,

    I'm a newbee to the BS2 world. I'm trying to create a code that will run 2 leds simultaneously .
    One flashing from slow 1000ms to fast 1ms and the other doing the opposite ....1ms to 1000ms at the SAME TIME. I know it probably has to do with a nested loop or an IF THEN type command but i'm at a loss. Any help would be greatly appreciated.

    Thank you,

    Do you mean that you want led A on for 1000mS then off for 1000mS while led B is on for 1mS then off for 1mS, then have the on/off time for led A decrease while the on/off time for led B increases, and when led A reaches 1mS on/off and led B reaches 1000mS on/off they reverse? Sort of a time/direction see-saw?
  • P'raps I misread the OP. I was thinking A on for 1000ms, then B on for 1 msec, then A on for 999, b on for 2 and so on.

    I wrote a program to do kwinn's interpretation; was able to get the minimum and the step size down to 2.5 msec. Even made the on period and off period equal.

    In any case, as Publison suggests, you can do it better and cheaper with a prop. I think the cheapest BS-2 is a homework board for $40; you can get a flip for $35. And the flip has the leds on board!
  • davejamesdavejames Posts: 4,045
    edited 2018-09-05 05:54
    Hello adam1971 - as Publison said, "welcome".

    One of the first things to understand about the Stamp is that it executes one.line.at.a.time.

    So any code programmed to cause one LED to delay will cause the other to delay at an undesired rate because of this One-Line-At-A-Time operation.

    Now I'm sure the Forum Wizards can comment further.

    Publison made the suggestion of using another Parallax product called the Propeller which contains 8 separate processors that can be doing different things, essentially at the same time.

    Regards,

    Dave
  • You'll have to use a state machine which can be a little tricky in PBASIC, but can be done.
  • Tracy AllenTracy Allen Posts: 6,656
    edited 2018-09-05 23:44
    A numerical oscillator could help, one for each led, running simultaneously.
    Suppose RED is on p0 and GREEN is on p1.
    The Stamp is slow, (~140µs per instruction minimum), so the following loop will itself take on the order of one millisecond, not accurate. It could be sped up by using shifts and periods in powers of two instead of the division.
    FOR idx = 1 to 500
      redFreq = 32768 / idx     ' this is the phase advance per step
      grnFreq = 32768 / (501-idx)
      redCount = redCount + redFreq    ' add to the phase accumulators
      grnCount = grnCount + grnFreq
      out0 = redCount.bit15    ' transfer the most significant bit to the LED.
      out1 = grnCount.bit15
    
    Oh, the Propeller chip mentioned above has 16 dedicated numerical oscillators built into its hardware. They could handle this task easily even at much much higher rates and resolutions.
  • Mr. Allen,

    Would you be so kind as to 'splain what is going on in your code snippet?

    It has stumped me.

    DJ
  • Hi Dave, sure thing. Here is a complete program snippet that does two constant simultaneous frequencies that are each a multiple of the time it takes to execute the loop. I verified the loop time on the 'scope, about 1.7 millisecond.

    Consider what happens if grnFreq=32768/1. Then the value of grnCount will alternate between 32768 and zero, because 32768+32768 rolls over to zero in the 16 bit word. By transferring the most significant bit to the output pin, the green LED flashes at 295 Hz. That is about the maximum frequency that can be achieved with this program due to the speed of the PBASIC interpreter.

    With larger values in the denominator of the division, the rate slows down. With grnFreq=32768/20, it spends 20 periods low and 20 periods high, for an output frequency of about 68Hz.

    With 500 in the denominator, the period is about 1.7 second, 0.6 Hz. In that case, a value of 65 is added to the count each time around the loop (32768/500 = 65), so it takes 1000+ times through the loop to complete a cycle. (65536/65 = 1008) . Note that the integer division is not exact, so there is a bit of bobble in the output frequency.

    This is the same logic as the NCO modes of the Cog counters in the Propeller. On each clock cycle the value of FRQA is added to the phase accumulator PHSA, and the msb is automatically transferred to the assigned pin.

    A program to scan the frequencies simultaneously up and down "simply" needs to update the values of redFreq and grnFreq. I'm not sure what the OP has in mind.
    '{$STAMP BS2pe}
    '{$PBASIC 2.5}
    grnFreq VAR WORD
    redFreq VAR WORD
    grnCount VAR WORD
    redCount VAR WORD
    redLED PIN 0
    grnLED PIN 1
    
    DIR0 = 1
    DIR1 = 1
    DO 
      redFreq = 32768 / 500     ' this is the phase advance per step
      grnFreq = 32768 / 20    
      redCount = redCount + redFreq    ' add to the phase accumulators
      grnCount = grnCount + grnFreq
      redLED = redCount.BIT15    ' transfer the most significant bit to the LED.
      grnLED = grnCount.BIT15
    LOOP  ' from 'scope this loop executes in ~1.69ms
    ' If grnFreq=1, then 1.69ms low and 1.69ms high, frequency 1/3.38E-3 = 295 Hz
    ' when grnFreq=20, 33.8 ms low and 33.8 high, frequency 67.6Hz
    ' When redLED=500, it is 845ms low and 845 high, period = 1.69 second.
    
  • Tracy AllenTracy Allen Posts: 6,656
    edited 2018-09-06 19:20
    Oh, taking the constant division out of the loop, moving the DO down by two lines, speeds up the execution time of the loop to 1.14 milliseconds, fastest output 439 Hz. A program to scan the rates in opposite directions would probably entail two nested loops, with the division in the much slower loop.


  • Mr. Allen - yeow!

    I get what you're saying. Thank you for the description. This is a perfect example of someone who knows the intricate abilities of the BS2.

    When the relocation to Idaho is complete, and I have my lab back, I'll set this up and observe. There is a lot of meat here, methinks.

    Dave
  • kwinnkwinn Posts: 8,697
    Anyone else notice that the OP seems to have disappeared from this discussion?
  • One visit, one post. Hello?

    Dave, it's fun (in Idaho!) to set up a row of LEDs all at somewhat different frequencies so that they drift in and out of sync. People will swear that it is random, mesmerizing.

  • kwinn wrote: »
    Anyone else notice that the OP seems to have disappeared from this discussion?

    Sometimes posters will not wait a day or so to get answers to their homework assignments. :)
  • Indeed. A challenging assignment if so. I wonder if there was an official solution.
  • Indeed. A challenging assignment if so. I wonder if there was an official solution.

    We may never know. He/she has not logging in since the original posting.
  • tomcrawfordtomcrawford Posts: 1,126
    edited 2018-09-08 17:52
    Indeed. A challenging assignment if so. I wonder if there was an official solution.

    that is why I assumed figured red on for 1000, green on for 1, red on for 999, green on for 2, etc.

  • Yes, that would be fair, alternating red and green in one loop using PAUSE idx and PAUSE 1000-idx, or alternating PULSOUTs. But the OP put so much emphasis on SIMULTANEOUSLY, and SAME TIME. Hmm, who's to know?
  • kwinnkwinn Posts: 8,697
    Who indeed. Tom's suggestion is the logical alternative to my interpretation, and either one could be implemented in one loop as long as the code execution was fast enough to meet the 1mS per loop time requirement.
  • Tracy AllenTracy Allen Posts: 6,656
    edited 2018-09-10 20:50
    The BS2sx, p, or px could probably make the 1ms loop time, if that is important.

    The granularity of PAUSE is 1ms, but there is the interpreter overhead, which adds about 230µs of dead space. According to my old database, PULSOUT also adds about 230µs for the interpreter, but with a granularity of 2 microseconds it could be tuned to hit 870µs to make a total of 1ms. Similarly for the 1000ms flash. Then, there may be need to account for the time to execute a GOTO, or DO:LOOP, and that adds another 250µs. Uh...

    I do still love programming the Stamp, but not to the point of splitting hairs!
  • I got the "normal" loop time for two LEDs down to 2.0 msec, increasing to about 3.5 if either LED needed to change. This was on a standard BS-2.

    As Tracy says, we are way into splitting hairs!
Sign In or Register to comment.