Friday, 10 April 2015

Testing TLC5916 LED driver with a PIC 16F1825 microcontroller

Combining the benefits of the MAX7219 (namely, constant current, non-dimming LEDs) with the ability to cascade ICs in a "chain" (like the 74HC595 shift register) has opened up some interesting possibilities for interactive, light-up sci-fi terrain.


Using them is really as simple as treating them as cascading shift registers. The only other thing to take care of is the current limiting resistor (from pin 14 to ground). We're using a 1.5K resistor with a 3.3V power supply and the LEDs are nice and vibrant, without being eye-burningly bright.

Here's some sample code which just displays a recognisable pattern on our cascading chips, to demonstrate that they work as expected:

Define CONFIG1 = 0x0804
Define CONFIG2 = 0x1dff
Define CLOCK_FREQUENCY = 32
AllDigital

declarations:
     Symbol tx = PORTC.7
     Symbol rx = PORTC.6
     Symbol data_out = PORTC.3
     Symbol clock_out = PORTC.5
     Symbol led_out = PORTA.2
     Symbol latch_out = PORTC.4
     
     ConfigPin tx = Output
     ConfigPin rx = Input
     ConfigPin clock_out = Output
     ConfigPin data_out = Output
     ConfigPin latch_out = Output
     ConfigPin led_out = Output
     
     Dim wall_pieces As Byte
     Dim g As Byte
     Dim h As Byte
     Dim i As Byte
     Dim j As Byte
     Dim k As Byte
     Dim data(128) As Byte
     
initialise_chip:
     OSCCON = 11110000b 'oscillator = 32mhz
     WaitMs 10
     APFCON0 = 01000000b 'APFCON

     wall_pieces = 2
     
initialise:

     Low data_out
     Low clock_out
     Low led_out
     Low latch_out
     
     data(1) = 11100111b
     data(2) = 00011000b
     data(3) = 10100101b
     data(4) = 01011010b
     data(5) = 00001111b
     data(6) = 11110000b
     
     g = 1
     WaitMs 500
               
loop:
     
     Gosub send_data
     High led_out
     WaitMs 500
     Low led_out
     WaitMs 500
     
Goto loop
End

send_data:
     
     Low latch_out
     
     'send as many bytes as we have wall pieces
     For i = 1 To wall_pieces
          k = data(g)
          
          'we can only send 7 bits
          For j = 0 To 7
               h = k And 00000001b
               If h = 0 Then
                    'send a zero bit
                    Low data_out
               Else
                    'send a one bit
                    High data_out
               Endif
               
               'the led driver can run at 30Mhz, our PIC is running at 32Mhz
               'in truth, it shouldn't be a problem, but just in case, let's
               'add a tiny delay on the clock line.
               High clock_out
               WaitUs 1
               Low clock_out
               
               k = ShiftRight(k, 1)
          Next j

          'now give it a sec just to let everything settle
          WaitMs 1

          g = g + 1
          If g > 6 Then g = 1
                    
     Next i

     'now latch everything with a falling edge
     High latch_out
     WaitUs 10
     Low latch_out
     
                    
Return



It's important to note that the LED driver chip sinks rather than sources current, so you need to connect your LEDs with a common anode (all the long legs connected to the power rail) and as each output on the driver chip is activated, the appropriate pin is pulled to ground, causing the LED to light up.



After proving that the chips work in the way we expected them to, it was back to our favourite PCB editor, ExpressPCB, to design a double-sided board with up to eight LEDs on it.

In our original design, we spaced fewer LEDs around, so that combinations of different colours could be used. In practice, it's probably quite likely - given the small distances between the LEDs - that the player would rather have one area of the game board one colour (rather than a combination of lots of different colours).

So our PCB layout (above) places eight LEDs in relatively close proximity to each other. The ones in the top corners, for example, might both be red, with the lower row of six being a combination of, say, blue, green and, perhaps, yellow. This would mean the player might switch on only the blue LEDs, to make that particular section of the board glow blue, or only green, or perhaps flash red (as some kind of Star-Trek-alike red alert). It's unlikely to be useful to be able to light up more than two colours at any one time, which is why we've placed them relatively close together, instead of spreading them across the entire surface of each wall section.

With the PCB designed, and the circuit tested and proved to be working, all that remains is to etch a couple of double-sided boards and try the idea out! Luckily the weekend will soon be upon us, to give us chance to pop down to the Nerd Unit and laser-etch a few boards...