Shop OBEX P1 Docs P2 Docs Learn Events
Generating Serial Output with set Period & Duty Cycle for RGB LED's — Parallax Forums

Generating Serial Output with set Period & Duty Cycle for RGB LED's

randonroserandonrose Posts: 5
edited 2012-05-01 11:39 in Propeller 1
Hi All,

I am new to parallax.com and spin. I am using a Gadget Gangster Propeller development board and am trying to interface a RGB LED strip controlled by a TM1803 control circuit to it.

The TM1803 uses a 1-wire interface to communicate with the propeller. From the TM1803's data sheet, I need to create a series of pulses to represent a High, Low and Reset signal.

To represent a High signal the TM1803 expects to see a signal with a period of 2.04uS and a duty cycle of 66%

To represent a Low signal the TM1803 expects to see a signal with a period of 2.04uS and a duty cycle of 33%

To represent a Reset signal the TM1803 expects to see a Low for 24uS

How I understand the TM1803 works is that it waits for 24 bits (8 bits per LED) consisting of the High and Low signals followed by the Reset signal at which point the output is set to the LED's.

I have been able to create the timing need via a PWM object but I dont believe this is the correct way of doing it.

Ideally I would like a function that I could send a 24 bit value to that would create the correct timing need for the controller chip.

Any help and advice would be very much appreciated!

Attached is the data sheet for the TM1803

Comments

  • JonnyMacJonnyMac Posts: 9,195
    edited 2012-02-29 18:25
    A friend of mine asked me about the chip but I never did anything -- until now. As I don't have the chip I checked the code using a 'scope. This is not intended to be sold as complete, it's just a starting point that may help you.
  • lanternfishlanternfish Posts: 366
    edited 2012-02-29 18:28
    EDIT: Good to see someone responded more positively while I was typing a response.

    Hi randonrose

    You will soon be given excellent advice from th e code gurus here on the Parallax forums. In the meantime, Yes you should have no problem creating a 24-bit serial stream with the periods specified. I am still learning SPIN myself so can't provide any direct help. Have you searched the OBEX yet? There may be a suitable object (for some other device/purpose) that can be adapted to your needs.

    As an aside, I have tried to have a look around the Titanmec website; painfully slow and some interesting chips are not documented yet.

    Cheers
  • randonroserandonrose Posts: 5
    edited 2012-03-02 10:04
    JonnyMac wrote: »
    A friend of mine asked me about the chip but I never did anything -- until now. As I don't have the chip I checked the code using a 'scope. This is not intended to be sold as complete, it's just a starting point that may help you.

    Thank you JonnyMac, the code works great with the chip and this is a very helpful starting point!
  • JonnyMacJonnyMac Posts: 9,195
    edited 2012-03-02 11:27
    Thank you JonnyMac, the code works great with the chip and this is a very helpful starting point!

    That's good news -- thanks for letting me know.

    BTW, I just looked at that code again and found an error in the set_color method; this shift value should be 8, not 1. Here's the correction
    pub set_color(c)
    
    '' Set using 24-bit color value
    '' -- %00000000_rrrrrrrr_gggggggg_bbbbbbbb
    
      rgb := (c << 8) | 1
      repeat until (rgb == 0)
    
  • randonroserandonrose Posts: 5
    edited 2012-03-05 11:08
    JonnyMac wrote: »
    That's good news -- thanks for letting me know.

    BTW, I just looked at that code again and found an error in the set_color method; this shift value should be 8, not 1. Here's the correction
    pub set_color(c)
    
    '' Set using 24-bit color value
    '' -- 000000_rrrrrrrr_gggggggg_bbbbbbbb
    
      rgb := (c << 8) | 1
      repeat until (rgb == 0)
    

    Thanks for the update JonnyMac, that function works fine now as well. However the only problem I am running into now is that only 3 LED's light on the strip. from what I am able to make out from your code the following section setups the timing:
    ' manually fine-tuned with oscilloscope
    
                            or      outa, txmask                    ' tx high
                            add     sync, #62                       ' set for 0 timing - high
            if_c            add     sync, #58                       ' bump for 1 timing               
                            waitcnt sync, #0                        ' wait on timer
    
    
                            andn    outa, txmask                    ' tx low 
                            add     sync, #44                       ' set for 1 timing - low          
            if_nc           add     sync, #54                       ' bump for 0 timing  
                            waitcnt sync, #0                        ' wait on timer                      
    
    
                            djnz    bits, #:loop                    ' all bits done?
                            jmp     #clearcmd                       ' yes, allow new command
    

    The data sheet states that once the first 24 bits are received it will hold the last value until it receives a reset code, which is a low signal for 24 uS. I am unsure about how this needs to be implemented. Dose another timing loop need to be created like the ones above, that a function could call to "reset" the chip and shiftout the data?
  • JonnyMacJonnyMac Posts: 9,195
    edited 2012-03-05 12:21
    I'm a little short on time as I'm in prep for a trade show and have lots of work to do, but try the attached. It uses an array to hold the colors for your modules and than blasts out the data all at once. There is no need to send a manual reset pulse as the Spin interface provides this timing. By passing the array to the PASM code we can get all the bits out before the "built in" reset occurs.
  • JonnyMacJonnyMac Posts: 9,195
    edited 2012-03-05 13:16
    If you'd rather make double-dog sure that reset is happening -- you can add these lines to the end of the PASM code
    rdlong  timer, #0                       ' get ticks/second
                            shr     timer, #15                      ' ~31us
                            add     timer, cnt                      ' sync timer
                            waitcnt timer, #0                       ' hold for reset                        
                            
                            jmp     #clearcmd                       ' allow new command
    
  • randonroserandonrose Posts: 5
    edited 2012-03-07 11:06
    JonnyMac wrote: »
    If you'd rather make double-dog sure that reset is happening -- you can add these lines to the end of the PASM code
    rdlong  timer, #0                       ' get ticks/second
                            shr     timer, #15                      ' ~31us
                            add     timer, cnt                      ' sync timer
                            waitcnt timer, #0                       ' hold for reset                        
                            
                            jmp     #clearcmd                       ' allow new command
    

    Thought I would update this tread to make you aware I have found out I explained how this chip operates incorrectly and that your code worked fine from the beginning based off of what I told you.

    Turns out, this chip looks for a constant stream of bits and once it receives 24-bits, it pushes them out into the next chip. I was able to get this to work by editing the last line of the PASM code so that it avoids the clearcmd routine:
    org     0
    
    entry                   rdlong  t1, par                         ' get pin #
                            mov     txmask, #1                      ' convert to pin mask
                            shl     txmask, t1
                            mov     outa, #0                        ' make low
                            mov     dira, txmask                    ' make output
    
    
    clearcmd                wrlong  zero, par                       ' clear pin, ready for command
    
    
    getcmd                  rdlong  rgbcmd, par                     ' new command?
                            test    rgbcmd, #$FF            wz      ' low byte must be > 0
            if_z            jmp     #getcmd
    
    
                            mov     bits, #24                       ' set bits to send
                            mov     sync, cnt                       ' start bit timer
    :loop                   rcl     rgbcmd, #1              wc
    
    
                            ' manually fine-tuned with oscilloscope
    
    
                            or      outa, txmask                    ' tx high
                            add     sync, #62                       ' set for 0 timing - high
            if_c            add     sync, #58                       ' bump for 1 timing               
                            waitcnt sync, #0                        ' wait on timer
    
    
                            andn    outa, txmask                    ' tx low 
                            add     sync, #44                       ' set for 1 timing - low          
            if_nc           add     sync, #54                       ' bump for 0 timing  
                            waitcnt sync, #0                        ' wait on timer                      
    
    
                            djnz    bits, #:loop                    ' all bits done?
                            jmp     #getcmd '#clearcmd                       ' yes, allow new command
    

    At this point I am trying to figure out how to write a Reset Function that can be called to send the reset low pulse for 24uS so that a new color can be updated.

    Thanks again for all your help!

    Randon
  • randonroserandonrose Posts: 5
    edited 2012-05-01 11:39
    randonrose wrote: »
    Thought I would update this tread to make you aware I have found out I explained how this chip operates incorrectly and that your code worked fine from the beginning based off of what I told you.

    Turns out, this chip looks for a constant stream of bits and once it receives 24-bits, it pushes them out into the next chip. I was able to get this to work by editing the last line of the PASM code so that it avoids the clearcmd routine:
    org     0
    
    entry                   rdlong  t1, par                         ' get pin #
                            mov     txmask, #1                      ' convert to pin mask
                            shl     txmask, t1
                            mov     outa, #0                        ' make low
                            mov     dira, txmask                    ' make output
    
    
    clearcmd                wrlong  zero, par                       ' clear pin, ready for command
    
    
    getcmd                  rdlong  rgbcmd, par                     ' new command?
                            test    rgbcmd, #$FF            wz      ' low byte must be > 0
            if_z            jmp     #getcmd
    
    
                            mov     bits, #24                       ' set bits to send
                            mov     sync, cnt                       ' start bit timer
    :loop                   rcl     rgbcmd, #1              wc
    
    
                            ' manually fine-tuned with oscilloscope
    
    
                            or      outa, txmask                    ' tx high
                            add     sync, #62                       ' set for 0 timing - high
            if_c            add     sync, #58                       ' bump for 1 timing               
                            waitcnt sync, #0                        ' wait on timer
    
    
                            andn    outa, txmask                    ' tx low 
                            add     sync, #44                       ' set for 1 timing - low          
            if_nc           add     sync, #54                       ' bump for 0 timing  
                            waitcnt sync, #0                        ' wait on timer                      
    
    
                            djnz    bits, #:loop                    ' all bits done?
                            jmp     #getcmd '#clearcmd                       ' yes, allow new command
    

    At this point I am trying to figure out how to write a Reset Function that can be called to send the reset low pulse for 24uS so that a new color can be updated.

    Thanks again for all your help!

    Randon

    Johnny Mac would you have any further suggestions on why the above commented code allowed all the LED's to light up? Also I seem to be unable to update to a new color using the above commented code.
Sign In or Register to comment.