Shop OBEX P1 Docs P2 Docs Learn Events
PULSOUT equivalent in SPIN -- translating PBASIC to SPIN — Parallax Forums

PULSOUT equivalent in SPIN -- translating PBASIC to SPIN

hipparchushipparchus Posts: 9
edited 2010-06-17 17:43 in Propeller 1
Hello,
I'm trying to use the propeller chip to control a digital potentiometer to brighten and dim an LED.
I've done this with the BASICStamp but need to use the propeller chip for my project and was trying
to translate the schematic and program to be compatible with the propeller chip. I'm not even sure
if the digital potentiometer works with the propeller, but knowing the capability of these chips, I
would assume so.

Right now I've got almost exactly the same setup as the schematic on page 263 of
http://www.parallax.com/dl/docs/books/edu/wamv2_1.pdf (page 275 of the pdf file) with the
exception of pin 1 of the digital potentiometer being connected to P0 of the propeller chip and pin 2
connected to P1.

The program reads:

' What's a Microcontroller - DigitalPotUpDown.bs2
' Sweep digital pot through values.
' {$STAMP BS2}
' {$PBASIC 2.5}

counter VAR Byte

DO
 LOW 5
 FOR counter = 0 TO 127
  PULSOUT 6, 1
  PAUSE 10
 NEXT

 HIGH 5
 FOR counter = 0 TO 127
  PULSOUT 6, 1
  PAUSE 10
 NEXT
LOOP



My (poor) attempt at making an equivalent program reads:
'Light dimming with digital potentiometer
'

CON

  potClkYel = 0                                         'potentiometer clock pulse pin for yellow light
  potDirYel = 1                                         'potentiometer U/D wiper direction pin for yellow light

PUB MAIN
  dira[noparse][[/noparse]potClkYel] := 1                                  'make yellow potentiometer control pins outputs
  dira[noparse][[/noparse]potDirYel] := 1
  
  outa[noparse][[/noparse]potClkYel] := 0                                  'initialize the clock pulse pin to low

  repeat
    outa[noparse][[/noparse]potDirYel] := 0                                'U/D wiper receives high signal
      repeat 128                                        'pulse 128 times
        PULSOUT(potClkYel)
        
    outa[noparse][[/noparse]potDirYel] := 1                                'U/D wiper receives low signal
      repeat 128                                        'pulse 128 times
        PULSOUT(potClkYel)

PUB PULSOUT(pin)
  outa[noparse][[/noparse]pin] := 0 
  waitcnt(clkfreq*2/1000000)
  outa[noparse][[/noparse]pin] := 1          
  waitcnt(clkfreq*2/1000000)
  outa[noparse][[/noparse]pin] := 0




I've tried playing around with the waitcnt command to get a pulse of 2μs (what PULSOUT <pin>, 1 ends up being),
and eliminating the wait altogether I got quite the fancy strobe light (unfortunately, not what I'm trying to do).
I really feel like I have no idea what I'm doing so perhaps you all can help.

Now, I've only been working with the BASICStamp and Propeller chip for maybe a month,
and I'm pretty inexperienced in the grand scheme of things, so I ask of you to please be
forgiving
of any gross misunderstandings I have of the way these parallax products work.
Please help!
Many thanks

Post Edited (hipparchus) : 6/15/2010 10:44:47 PM GMT

Comments

  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-06-15 22:45
    Spin instructions take about 5 microseconds each so you won't be able to do a 2us pulse in Spin; if the pulse timing is not critical then you can simply leave the waitcnt instructions out of your PULSOUT() method.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2010-06-15 23:02
    There are also likely better digipots out there. Ones using SPI are quite handy; no timing issues, just shift out the pot position and done.
    But yes, to do exactly what you did in BASIC you need PASM speeds, but I think you would be able to get away with JonnyMac's suggestion.

    BTW: EVERYTHING is compatible with the Propeller (of course that is an exaggeration), but we have methods to anything from full speed USB v1.1 to digipot ICs!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    April, 2008: when I discovered the answers to all my micro-computational-botherations!

    Some of my objects:
    MCP3X0X ADC Driver - Programmable Schmitt inputs, frequency reading, and more!
    Simple Propeller-based Database - Making life easier and more readable for all your EEPROM storage needs.
    String Manipulation Library - Don't allow strings to be the bane of the Propeller, bend them to your will!
    Fast Inter-Propeller Comm - Fast communication between two propellers (1.37MB/s @100MHz)!
  • lonesocklonesock Posts: 917
    edited 2010-06-15 23:03
    If you have a free counter, you can set the counter up in NCO mode (%00100 << 26), and set the FRQx to 1, so 1 is being added to the PHSx register for each clock. Then, just set PHSx to -N, and the pin will go high for N clocks, then shut itself off. You just need to make sure you refresh the PHSx register to 0 periodically, or the pin will toggle every 2^31.

    Jonathan

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lonesock
    Piranha are people too.
  • hover1hover1 Posts: 1,929
    edited 2010-06-15 23:29
    Welcome to the forums. I admire you diving right into spin for your project.

    Might I suggest a little transitional product. There is an object in the OBEX called BS2 fuctions:

    http://obex.parallax.com/objects/30/

    It has many of the BS2 command that can be used in Spin applications.

    Also there is PropBasic:

    http://forums.parallax.com/showthread.php?p=867134

    yet another avenue to use Basic style programs to yield PASM (Propeller Assembly Code), to get the fastest code to run on the Propeller.

    Both of these might help you make the transition from Stamp to Propeller.

    A lot of help here to make the transition.

    Jim


    hipparchus said...
    Hello,
    I'm trying to use the propeller chip to control a digital potentiometer to brighten and dim an LED.
    I've done this with the BASICStamp but need to use the propeller chip for my project and was trying
    to translate the schematic and program to be compatible with the propeller chip. I'm not even sure
    if the digital potentiometer works with the propeller, but knowing the capability of these chips, I
    would assume so.

    Right now I've got almost exactly the same setup as the schematic on page 263 of
    http://www.parallax.com/dl/docs/books/edu/wamv2_1.pdf (page 275 of the pdf file) with the
    exception of pin 1 of the digital potentiometer being connected to P0 of the propeller chip and pin 2
    connected to P1.

    The program reads:

    ' What's a Microcontroller - DigitalPotUpDown.bs2
    ' Sweep digital pot through values.
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    counter VAR Byte
    
    DO
     LOW 5
     FOR counter = 0 TO 127
      PULSOUT 6, 1
      PAUSE 10
     NEXT
    
     HIGH 5
     FOR counter = 0 TO 127
      PULSOUT 6, 1
      PAUSE 10
     NEXT
    LOOP
    



    My (poor) attempt at making an equivalent program reads:
    'Light dimming with digital potentiometer
    '
    
    CON
    
      potClkYel = 0                                         'potentiometer clock pulse pin for yellow light
      potDirYel = 1                                         'potentiometer U/D wiper direction pin for yellow light
    
    PUB MAIN
      dira[noparse][[/noparse]potClkYel] := 1                                  'make yellow potentiometer control pins outputs
      dira[noparse][[/noparse]potDirYel] := 1
      
      outa[noparse][[/noparse]potClkYel] := 0                                  'initialize the clock pulse pin to low
    
      repeat
        outa[noparse][[/noparse]potDirYel] := 0                                'U/D wiper receives high signal
          repeat 128                                        'pulse 128 times
            PULSOUT(potClkYel)
            
        outa[noparse][[/noparse]potDirYel] := 1                                'U/D wiper receives low signal
          repeat 128                                        'pulse 128 times
            PULSOUT(potClkYel)
    
    PUB PULSOUT(pin)
      outa[noparse][[/noparse]pin] := 0 
      waitcnt(clkfreq*2/1000000)
      outa[noparse][[/noparse]pin] := 1          
      waitcnt(clkfreq*2/1000000)
      outa[noparse][[/noparse]pin] := 0
    
    



    I've tried playing around with the waitcnt command to get a pulse of 2μs (what PULSOUT <pin>, 1 ends up being),
    and eliminating the wait altogether I got quite the fancy strobe light (unfortunately, not what I'm trying to do).
    I really feel like I have no idea what I'm doing so perhaps you all can help.

    Now, I've only been working with the BASICStamp and Propeller chip for maybe a month,
    and I'm pretty inexperienced in the grand scheme of things, so I ask of you to please be
    forgiving
    of any gross misunderstandings I have of the way these parallax products work.
    Please help!
    Many thanks
  • p00ndawgp00ndawg Posts: 70
    edited 2010-06-15 23:37
    code from a project I am doing from a teacher/student

    works great

    pri Pause(duration)
    
      'This function pauses program execution for approximately [noparse][[/noparse]duration] micro seconds
      'so 1_000_000 would be approximately one second.  Doesnt account for instruction
      'execution time overhead.
    
      if duration < 381
        duration := 381             'lower bound limit. anything lower than this, we
                                    'have to wait until the counter comes back around,
                                    'which is MUCH longer than [noparse][[/noparse]duration].
      waitcnt(((clkfreq / 1_000_000) * duration) + cnt)
    
      
    pri PulsOut(pin, duration)
    
      'similar to the BS2 command.  This function pulses the [noparse][[/noparse]pin] for [noparse][[/noparse]duration].
      'This is extremely useful for controlling servos and speed controllers.
      
      dira[noparse][[/noparse]pin]~~      'make pin an output
      outa[noparse][[/noparse]pin]~~      'make pin go high            
      waitcnt(((clkfreq / 1_000_000) * duration) + cnt)  'pause execution
      outa[noparse][[/noparse]pin]~       'make pin go low
    

    Post Edited (p00ndawg) : 6/16/2010 12:24:34 AM GMT
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-06-16 03:26
    Notice that the pulsout() method does not have the same lower bound on duration as pause() -- this could lead to a counter rollover and a pulse of about 58 seconds....

    I think I would do something like this:

    pub pulsout(pin, duration) 
    
      duration := (duration * (clkfreq / 1_000_000)) #> 381
    
      dira[noparse][[/noparse]pin]~~
      !outa[noparse][[/noparse]pin]
      waitcnt(duration)
      !outa[noparse][[/noparse]pin]
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2010-06-16 03:55
    Why are you using a digital potentiometer to bright/dim an LED?·

    In other words, why not use PWM?
  • p00ndawgp00ndawg Posts: 70
    edited 2010-06-16 05:02
    hey thanks johnny will test out that edit and post results.
  • hipparchushipparchus Posts: 9
    edited 2010-06-16 13:08
    I'm not 100% sure if the potentiometer needs 2μs pulses to work, but maybe I'll try the BS2 functions object (thank you, Jim!).
    I think I'll be able to figure something out with what you've all offered. I'll probably give that code a try too, dawg.


    PJ Allen said...
    Why are you using a digital potentiometer to bright/dim an LED?

    In other words, why not use PWM?

    I originally tried this by using PWM and found it difficult to make the transition smooth from dark to light. I'll probably go back to that and compare methods but for now the main reason to try with the digital pot is to see if I can get it to work! All avenues must be explored.


    ---


    EDIT:
    Ahhh, propBASIC works perfectly! Thank you all for the help.

    Post Edited (hipparchus) : 6/16/2010 1:37:55 PM GMT
  • Shawn LoweShawn Lowe Posts: 635
    edited 2010-06-16 13:24
    PJ Allen said...

    Why are you using a digital potentiometer to bright/dim an LED?·

    In other words, why not use PWM?

    That's a good point PJ Allen. PWM a FET driving circuit? Should do the same thing

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Shawn Lowe


    When all else fails.....procrastinate!
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-06-16 13:46
    hipparchus said...
    PJ Allen said...
    Why are you using a digital potentiometer to bright/dim an LED?

    In other words, why not use PWM?

    I originally tried this by using PWM and found it difficult to make the transition smooth from dark to light. I'll probably go back to that and compare methods but for now the main reason to try with the digital pot is to see if I can get it to work! All avenues must be explored.

    If you're just using one or two LEDs you can employ the counters to take care of the PWM for you -- this will run full time and allow smooth transitions (unlike the BS2 and BS2 object PWM which does not run full time). If you want a whole bunch of LEDs you can write a background cog that takes care of it. I recently designed a 16-channel, DMX-controlled LED fixture (for Ethereal FX) that uses the latter strategy.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • hipparchushipparchus Posts: 9
    edited 2010-06-16 13:54
    JonnyMac said...
    hipparchus said...
    PJ Allen said...
    Why are you using a digital potentiometer to bright/dim an LED?

    In other words, why not use PWM?

    I originally tried this by using PWM and found it difficult to make the transition smooth from dark to light. I'll probably go back to that and compare methods but for now the main reason to try with the digital pot is to see if I can get it to work! All avenues must be explored.

    If you're just using one or two LEDs you can employ the counters to take care of the PWM for you -- this will run full time and allow smooth transitions (unlike the BS2 and BS2 object PWM which does not run full time). If you want a whole bunch of LEDs you can write a background cog that takes care of it. I recently designed a 16-channel, DMX-controlled LED fixture (for EFX-TEK) that uses the latter strategy.

    I'm using about 5 LEDs, so I'd have probably have to the latter. Unfortunately, I don't think I'm far enough along yet (skill-wise) to do that...
    I'll have to do more reading. Thank you, though.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-06-16 14:18
    Well, then, let me help you out. Attached is my object (with demo code) that will control eight channels using values 0 (off) to 255 (full bright) using Bit Angle Modulation (to avoid possible RGB LED patent issues). The code works well and has been deployed in a commercial product (www.etherealfx.com). If you don't want to use all eight channels you can easily update the code to adjust it down to five.

    BTW... I explain my implementation of Bit Angle Modulation in this Nuts & Volts article:
    -- www.parallax.com/Portals/0/Downloads/docs/cols/nv/prop/col/nvp3.pdf

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • hipparchushipparchus Posts: 9
    edited 2010-06-16 15:45
    JonnyMac said...
    Well, then, let me help you out. Attached is my object (with demo code) that will control eight channels using values 0 (off) to 255 (full bright) using Bit Angle Modulation (to avoid possible RGB LED patent issues). The code works well and has been deployed in a commercial product (www.etherealfx.com). If you don't want to use all eight channels you can easily update the code to adjust it down to five.

    BTW... I explain my implementation of Bit Angle Modulation in this Nuts & Volts article:
    -- www.parallax.com/Portals/0/Downloads/docs/cols/nv/prop/col/nvp3.pdf

    Oh, cool! Thanks. I'll take a look at it and let you know if I end up using that method.
  • p00ndawgp00ndawg Posts: 70
    edited 2010-06-16 16:13
    hey I tried your edit jonny and the it wouldnt do anything, but thanks for the bug find going to try to fix it.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-06-16 17:49
    That's interesting -- works fine on my demo board. Here's a safer version (does not allow bad values)

    pub pulsout(pin, us)
    
      if (pin => 0) and (pin =< 31) and (us > 0)
        us := (clkfreq / 1_000_000 * us) #> 381
        outa[noparse][[/noparse]pin]~~
        !dira[noparse][[/noparse]pin]
        waitcnt(us + cnt) 
        !dira[noparse][[/noparse]pin]
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • p00ndawgp00ndawg Posts: 70
    edited 2010-06-16 19:41
    I will try that tomorrow. I edited the code you provided earlier in many different ways and it would not do anything, trying to limit the duration to > 381 and anything I did really did not amount to anything.
    I should mention im using it in par with an msr1 and two hb25's.
    Thanks for the help tho its really appreciated and I actually saw the bug in action. My robot got stuck in forward motion and never stopped.
  • p00ndawgp00ndawg Posts: 70
    edited 2010-06-17 17:43
    Hi,

    I tried that as well and the wheels dont move at all with that, it however does move on to other parts of the code.

    EDIT:

    it does not seem to be recognizing the duration I was previously sending, because it is running the code.
    could your code have changed which durations it recognizes? I was sending 1_600 for forward previously.

    Post Edited (p00ndawg) : 6/17/2010 6:23:53 PM GMT
Sign In or Register to comment.