APA102 experience

edmunds

Senior Member
Dear all,

I did some work with APA102 based LED strip with 144 LEDs per meter version. All went rather smooth with both HSPI and bit-banged versions after I figured the required end frame is not 4 bytes of $FF, but 8. So 64 set bits. This is true for whatever number of LEDs you use - 1 or 30. Did not try more as my application only needs 10. So, obviously, one needs to be prepared to experiment with these poorly data-sheeted devices :).

Bit banged code, optimised for speed, not code space in the attached file, intended to switch small boat navigation tri-state and anchor masthead light. The code takes ~1800KB and switches the LEDs with small, but noticeable delay at 16MHz. As the code is intended for M2 device, at 32MHz there should be no delay to see. It could be optimised for code space instead, reducing the code to some 400KB or even less, but then LEDs change colours in noticeably one-by-one fashion.


Cheers,

Edmunds

View attachment APA102WorkingSampleMacro.bas
 

markusall

New member
With only a few lines of code you can make an arbitrarily long string of APA102s dance!

There are several fine posts describing driving the APA102 with PICAXE:
https://picaxeforum.co.uk/threads/apa102-rgb-led-strip-examples.30680/
https://picaxeforum.co.uk/threads/apa102-5050-rgb-led-with-integrated-driver.27509/
https://picaxeforum.co.uk/threads/controling-addressable-leds.29327/#post-302643

I am using the 18m2 and do not have the luxury of HSPIOUT. Because of this I have not been able to drive the LEDs very fast using the wonderful examples provided in the above threads. I want fast.

Edmunds' example above, while the fastest I've tried, did not scale well for a string of 72 LEDs. Adding a required loop still took 0.25 - 0.5s to fill the string. This method also does not allow for very complex color / pattern mixing due to the speed optimization method requiring so much space.

I wondered: How fast can I fill a string of LEDSs with *anything*? What if I sacrifice intention for speed? I have not seen this discussed before.

The first idea was simple: PWMOUT is the fastest way to wiggle a pin on the 18m2. Use this to wiggle the APA102 CLOCK line while holding the DATA line HIGH. This should fill the string with brightest white.

That worked. DATA LOW at the start of wiggling sends an effective "init header" and when DATA goes HIGH, Voila!

Surprisingly (to me), clocking out a continuous LOW after the strip was illuminated, does NOT turn off any of the LEDs. So I now could turn them on *fast* but not off at all.

Since I can't wiggle the DATA line fast enough to create intentional patterns with this fast PWMOUT CLOCK, I got to thinking...what if I PWMOUT the DATA line using the second timer? By playing with the frequencies between them, some interesting effects should occur.

They do. :)

The basic idea:
I set the CLOCK PWM to a certain arbitrary frequency (~230kHz)(Correction: 40kHz) and then vary the DATA PWM frequency to search for interesting patterns. Once a pattern is found, stopping the DATA PWM, holding it LOW (sends new APA102 init), and restarting the PWM (at the same frequency) rewrites the string causing phase shift effects in the frequencies between the two PWMs that add motion to the pattern.

In my initial search I found ~40 "interesting" patterns. Heavily commented code posted here is to demonstrate these patterns. (I'll try posting this next, I'm hitting the 10000 character post limit...)

More of the idea and its limitations are pondered in the comments.

I attach the same file in case that is more convenient.

Any thoughts on ways to improve this would be welcome.

Any interesting patterns you've found?

Anyone want to take a crack at intelligently choosing frequencies to create an intentional effect?

Cheers!
 

Attachments

Last edited:

markusall

New member
Here is the code, identical to attached above:
Rich (BB code):
'LED Strip APA-102
'A faster way to signal the LEDs
'     We will pwmout the clock with one timer, and pwmout the data line with another timer.
'     Phase shifts between the frequencies should result in interesting patterns
'     albeit with poor control of the resulting patterns.
'
'Phase variations in when the timers start and stop may make any particular pattern slightly
'different from one execution to the next.  These same phase changes are what give us motion.
'This motion can vary from one execution to the next
'
'A search for a good pattern is necessary. The EEPROM data contains some of my favorites
'There may be some redundancy.
'
'Differneces between freqs on different chips may completely alter a particular found
'pattern when migrating hardware. I have not tested this.
'
'Developed using APA102 144/meter, 72 LEDs.
'
'Notes:
'The base frequency I've chosen is arbitrary, others should also work.
'When the pattern involves filling the whole string with the same color, I can still see 
'a slight delay from end to end.  This is likely due to the relatively low base freq.  
'A higher base freq should solve this if it bothers you.

#picaxe 18m2
'#no_data


;define the hardware pins
Symbol SCK =            B.6         'need PWM
Symbol SDO =            B.3         'need PWM
Symbol buttonpress =    PinB.4      '|any input will do.
Symbol buttonpin =      B.4         '|This will cycle us through the demos

;Variables
symbol index =    b6
symbol freq =     b4

'Data for the demos.  These are the "freqs" that give some patterns I like
'there are 44 of these
eeprom (14,15,16,19,28,31,32,33,36,41,46,57,59,62,82,83,84,85,86,87,88,91,92,104,106,111,112,113,115,116,117,131,132,133,135,138,142,153,156,158,160,165,165,167)

init:
      high SCK                          'LED clock line idles high
      low SDO
      input buttonpin
        
'Start the clock line PWM     
      pwmout SCK, 24, 69                  '40kHz 70% duty cycle (arbitrary)

'Send the start byte:
      low SDO                             'data line already low from above
      pause 10                            'the PWM is clocking this out during the wait
                                          'for a slow clock, may need to increase the delay

main: 
for index = 0 to 43                 'the number of data we are testing (44 of my favorites)
      read index, freq              'read the next demo example from EEPROM
      do                            'repeat this to get frameshift effects:
                                    'we will start and stop the data PWM so the bit pattern
                                    '"moves" with phase shift / frameshift.
                              
            pwmout SDO, freq, 49    'freq is the frequency. 49 is the duty cycle factor.
                                    'Changing duty cycle also changes the pattern.
                                    'Try 69 instead of 49 for another set of interesting
                                    'patterns.
                                    
            pause 100               'to allow time for the clock to fill the string
                                    'If the string doesn't fill with the pattern, 
                                    'increase this delay.

            pwmout SDO, off         'this opens the data pin for us
            low SDO                 'so we can send zeros for init to rewrite the LED string
            pause 10                'the clock is ticking
            
      loop until buttonpress = 1    'play the current demo till button press
      sertxd (#freq,13,10)          'send to the console the pattern number we just finished

      pause 1000                    'button debouncing
      do:loop until buttonpress = 0
      pause 1000
next

goto main
end
 
Last edited:

premelec

Senior Member
Thanks for sharing your interesting experiments! I have only driven the APA102s with calculated patterns and may give this approach a try. [probably with 14M2 which has 4 PWMOUTs ]
 

markusall

New member
Thanks for sharing your interesting experiments! I have only driven the APA102s with calculated patterns and may give this approach a try. [probably with 14M2 which has 4 PWMOUTs ]
You've posted some great and useful information as well. The patterns using this method are fascinatingly complex and beautiful. I encourage you to play!
 
Top