New Member-New Project: 08M2 and the TLC5947

datasmith

Member
Hi all. New forum member here, and working on a new Picaxe project.

I'm working on a piece of animated artwork that has eight multi-color glowing spheres driven by RGB LEDs.
I wanted to keep the electronics as simple as possible, and found this shift-register RGB-LED controller that I hoped would fit the bill.
It's the Texas Instruments TLC5947 on an Adafruit break-out board... cost me about $20 US on Amazon.com, but I just found a clone from Comimark also on Amazon for only $7.50 US which also comes with header pins. A much better deal, so I just picked up two more for future projects.

I took the minimalist approach and wired an 08M2 to the controller with a minimum of parts; two resistors (for the programming interface), two capacitors and a 5V voltage regulator. This allows me to run it with any DC power supply up to the break-out board's max voltage of I think is 24V. I'm using a 9V power supply.
I have attached pics of my schematic and associated breadboard, and I've actually got this thing working.

Here are some caveats.
1. The TLC5947 has12 bits of resolution per color (RGB) per LED. That's 12x3x8=288 bits that must be shifted out to the controller each and every time you want to change a color on any(or all 8) LED(s) connected to the controller.
2. The 08M2 apparently does not support hardware shiftout, so I had to use a modified version of the shiftout sub-procedure provided on page 238 of the picaxe programming manual to get data out to the controller. MSB first.
3. To get any smooth color animation out of the TLC5947 I had to crank the 08M2 clock speed up to 32MHz. This kills any multitasking capabilities and I had to write my program as a single thread.

Regardless, I was able to get it to work at about 15 updates per second. This gives me a relatively smooth animation, given the minimal parts and costs.
Here are pics of my schematic and breadboard in operation.

In my next post I will provide my program concept and base code for sending colors to the TLC5947.
 

Attachments

datasmith

Member
First off, as I mentioned before, the TLC5947 has 12 bits of resolution per color. That's 4095 color steps per color. If I were to try and animate color changes using that fine of a step/resolution given the general speed the 08M2, the overall effect would be extremely slow, and handling 12 bit math in a byte/word environment would cost me more program memory overhead than I could afford. So, I decided to reduce my program resolution to just 8 bits per color. That's just 255 color steps per color. But, that's really all the color resolution I need for this art piece.

I made this resolution correction in my shiftout sub-procedure.
Since the TLC5947 controller requires data to be sent MSB first I was able to set up my shiftout sub-procedure to just repeat the LSB of each byte four additional times. So if my 8-bit color data is 1111 0000, the shiftout procedure sends 1111 0000+0000. If my 8-bit color data is 1111 0001 , the shiftout procedure sends 1111 0001+1111.

I set up an array of 24 bytes called Cur_LED_Array. Each three bytes in the array represents 8-bit R, G and B color values for each of the 8 LEDs. My main animation code manipulates the 8 bit color data values in this array with various algorithms and routines, and when ready to animate the next sequence calls gosub update_LED_Output to send changed values to the LED controller.

Here's the base code for this:
Code:
symbol sdata = C.1 ' a high or low on this pin sets bit data to a 1 or 0
symbol sclk = C.2   ' a pulse on this pin writes the bit data into the shift register MSB first
symbol XLAT = C.4  ' pulse on this pin writes the 288 bits of shited in data from the controller's SR to output latch 

symbol Cur_LED_Array = 28 ' pointer into memory where a 24 byte array represents 8 bit RGB values per each LED

'shiftout variables and counters
symbol sbytecounter = b0
symbol sbitcounter = b1
symbol var_out = b2 ' output byte variable
symbol mask = b3 ' bit masked variable

gosub update_LED_Output ' sends Cur_LED_Array values to the TLC5947 controller

'========================================================================
update_LED_Output:

    bptr = Cur_LED_Array             'points to LED color value array
    for sbytecounter = 1 to 24    ' iterates through all 24 bytes
        var_out = @bptrinc
        for sbitcounter = 1 to 8 ' number of bits
            mask = var_out & 128 ' mask MSB 128 = 1000 0000
            low sdata ' data low
            if mask = 0 then skipMSB
            high sdata ' data high
skipMSB:
            pulsout sclk,1 ' pulse clock for each bit
            var_out = var_out * 2 ' shifts var_out left for the next bit from MSB
        next sbitcounter
        ' on the LSB of the byte repeat it 4 more times to reach 12 bits
        ' simply done by pulsing out four more times on the same sdata value
        pulsout sclk,1
        pulsout sclk,1
        pulsout sclk,1
        pulsout sclk,1
    next sbytecounter
    pulsout XLAT,1    ' when all bytes are shifted out 
                                'this tells the controller to latch the 288 bit SR data to the output
    return

'========================================================================
 

premelec

Senior Member
Good work! Looks like you've got it tamed...I went to APA102s some years ago - easy drive to multicolor...
 

datasmith

Member
OK - I have been working on getting my RGB-LED control prototype into an actual piece of art. Using the 08M2's limited memory I was able to squeeze in five full color animated sequences that run about a minute each with 409 bytes of memory to spare. I also had a spare input pin on the 08M2, so I attached a capacitive touch sensor module to allow for some user interaction. Normally the program will cycle through the five animation sequences in a continuous loop, but touching the sensor once will cause it to keep repeating the current sequence if the viewer likes it. Touching it again will start it cycling through all sequences again. I picked up the HiLetgo TTP223B Capacitive Touch Switch Module in a 10-pack for $7.50 US from Amazon (of course). I have a love/hate relationship with Amazon.com. I'm an old-school guy and used to love browsing around in my local hobby/model shop and radio-shack electronics store. But they have gone the way of the Dodo bird. If I lived in New York, or Atlanta, or Miami maybe I could find one. But in middle America Amazon has eaten them all up. So that's where I go for just about everything now. Scary.
I digress.

So, the Idea is to take these eight RGB LED's and put them into a piece of Art. I've attached a concept image I created with Blender, and an image of my current work in progress getting it into reality...

The concept is to have this tower of spheres glow in a sequence of colors. The "tower" is constructed from 10AWG and 12AWG solid copper wire soldered together into a lattice, and the "spheres" are actually table tennis (ping-pong) balls. Celluloid ping-pong balls make perfect little projection screens and glow quite well with a bright LED inside.
 

Attachments

hippy

Technical Support
Staff member
Here's the base code for this ..
If you add "Symbol sdatapin = pinC.1" you can speed up the code you have with -
Code:
update_LED_Output:
    Low sdata
    bptr = Cur_LED_Array             'points to LED color value array
    for sbytecounter = 1 to 24    ' iterates through all 24 bytes
        var_out = @bptrinc
        sdatapin = bit23 : pulsout sclk,1
        sdatapin = bit22 : pulsout sclk,1
        sdatapin = bit21 : pulsout sclk,1
        sdatapin = bit20 : pulsout sclk,1
        sdatapin = bit19 : pulsout sclk,1
        sdatapin = bit18 : pulsout sclk,1
        sdatapin = bit17 : pulsout sclk,1
        sdatapin = bit16 : pulsout sclk,1
        pulsout sclk,1
        pulsout sclk,1
        pulsout sclk,1
        pulsout sclk,1
    next sbytecounter
    pulsout XLAT,1    ' when all bytes are shifted out 
                                'this tells the controller to latch the 288 bit SR data to the output
    return
 

datasmith

Member
Wow hippy! That change in my output subprogram easily doubled my animation sequence frame rate. I am looking at all my sequence code now. I can double the math precision in my routines and get a lot smoother transitions. Thanks for the tip!
 
Top