Go Down

Topic: TLC5940 and Ethernet Shield using SPI (Read 8388 times) previous topic - next topic


Hi, for a project of mine, I would like functionality of the Ethernet Shield and a TLC5940 chip.  However, both of these devices use the SPI functionality on the atmega.  Is it possible to use both, because as it stands now with my code, they don't seem to be playing nicely together.


Is it possible to use both


because as it stands now with my code, they don't seem to be playing nicely together.

Posting code in 0 point font wasn't a good idea, was it?
The art of getting good answers lies in asking good questions.


haha good point! i was wondering why nobody was responding.  I was unsure if the two devices would be able to work together because they both use SPI.  Posted below now is my code:
Code: [Select]
#include <Tlc5940.h>
#include <tlc_animations.h>
#include <tlc_config.h>
#include <tlc_fades.h>
#include <tlc_progmem_utils.h>
#include <tlc_servos.h>
#include <tlc_shifts.h>
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 200);
unsigned int localPort = 8888;  // local port to listen on
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
EthernetUDP Udp;
int packetSize;

char Buffer[9];

char handshake;
char command_type;
char command_pin0;
char command_pin1;
char terminator;
int digit1;
int digit2;
int digit3;
int digit4;
int in_value;
int pin;
int val;

void setup()
  for (int i = 0; i<16; i = i+1)

void loop()
  if (Serial.available()==9)
    for (int m = 0; m<=8; m = m+1)
      Buffer[m] = Serial.read();
  else if(Serial.available()<9 || Serial.available()>9)
  packetSize = Udp.parsePacket();
    IPAddress remote = Udp.remoteIP();

void command_udp()
  handshake = packetBuffer[0];
  command_type = packetBuffer[1];
  command_pin0 = packetBuffer[2];
  command_pin1 = packetBuffer[3];
  digit1 = packetBuffer[4];
  digit2 = packetBuffer[5];
  digit3 = packetBuffer[6];
  digit4 = packetBuffer[7];
  terminator = packetBuffer[8];

void command_serial()
  handshake = Buffer[0];
  command_type = Buffer[1];
  command_pin0 = Buffer[2];
  command_pin1 = Buffer[3];
  digit1 = Buffer[4];
  digit2 = Buffer[5];
  digit3 = Buffer[6];
  digit4 = Buffer[7];
  terminator = Buffer[8];

void parsing()
  digit1 = digit1-48;
  digit1 = digit1*1000;
  digit2 = digit2-48;
  digit2 = digit2*100;
  digit3 = digit3-48;
  digit3 = digit3*10;
  digit4 = digit4-48;
  in_value = digit1+digit2+digit3+digit4;
  command_pin0 = command_pin0 - 48;
  command_pin1 = command_pin1 - 48;
  command_pin0 = command_pin0 * 10;
  pin = command_pin0+command_pin1;
  if (handshake == '!' && terminator == '@' && in_value <= 4095)
    switch (command_type)
      case 'A':
      case 'a':
        val = analogRead(pin);
      case 'D':
        if (in_value == 4095) { digitalWrite(pin, HIGH);}
        if (in_value ==0)    { digitalWrite(pin, LOW);}
      case 'd':
        val = digitalRead(pin);
      case 'P':
      case 'p':


How is the TLC5940 connected to the Arduino?


its connected exactly as described in the tlc5940 libary demo "BasicUse".  ie:
Code: [Select]
    Basic Pin setup:
    ------------                                  ---u----
    ARDUINO   13|-> SCLK (pin 25)           OUT1 |1     28| OUT channel 0
              12|                           OUT2 |2     27|-> GND (VPRG)
              11|-> SIN (pin 26)            OUT3 |3     26|-> SIN (pin 11)
              10|-> BLANK (pin 23)          OUT4 |4     25|-> SCLK (pin 13)
               9|-> XLAT (pin 24)             .  |5     24|-> XLAT (pin 9)
               8|                             .  |6     23|-> BLANK (pin 10)
               7|                             .  |7     22|-> GND
               6|                             .  |8     21|-> VCC (+5V)
               5|                             .  |9     20|-> 2K Resistor -> GND
               4|                             .  |10    19|-> +5V (DCPRG)
               3|-> GSCLK (pin 18)            .  |11    18|-> GSCLK (pin 3)
               2|                             .  |12    17|-> SOUT
               1|                             .  |13    16|-> XERR
               0|                           OUT14|14    15| OUT channel 15
    ------------                                  --------

    -  Put the longer leg (anode) of the LEDs in the +5V and the shorter leg
         (cathode) in OUT(0-15).
    -  +5V from Arduino -> TLC pin 21 and 19     (VCC and DCPRG)
    -  GND from Arduino -> TLC pin 22 and 27     (GND and VPRG)
    -  digital 3        -> TLC pin 18            (GSCLK)
    -  digital 9        -> TLC pin 24            (XLAT)
    -  digital 10       -> TLC pin 23            (BLANK)
    -  digital 11       -> TLC pin 26            (SIN)
    -  digital 13       -> TLC pin 25            (SCLK)
    -  The 2K resistor between TLC pin 20 and GND will let ~20mA through each
       LED.  To be precise, it's I = 39.06 / R (in ohms).  This doesn't depend
       on the LED driving voltage.
    - (Optional): put a pull-up resistor (~10k) between +5V and BLANK so that
                  all the LEDs will turn off when the Arduino is reset.

    If you are daisy-chaining more than one TLC, connect the SOUT of the first
    TLC to the SIN of the next.  All the other pins should just be connected
        BLANK on Arduino -> BLANK of TLC1 -> BLANK of TLC2 -> ...
        XLAT on Arduino  -> XLAT of TLC1  -> XLAT of TLC2  -> ...
    The one exception is that each TLC needs it's own resistor between pin 20
    and GND.

    This library uses the PWM output ability of digital pins 3, 9, 10, and 11.
    Do not use analogWrite(...) on these pins.

    This sketch does the Knight Rider strobe across a line of LEDs.

    Alex Leone <acleone ~AT~ gmail.com>, 2009-02-03 */


Is D10 used by the TLC5940? If so you need to move it to another pin. D10 is the slave select for the w5100.


yeah it is used by the tlc5940.  it is connected to the blank pin on the tlc although im not sure what that does exactly.
if i move it over to another pin for the tlc5940, wont i have to edit the library or something like that to accommodate for a change like that?


if i move it over to another pin for the tlc5940, wont i have to edit the library or something like that to accommodate for a change like that?



so i just looked through all of the library files and i cant seem to find where to change the BLANK pin number, unless i'm missing somewhere simple...


The library may not change that pin. I am not familiar with the TLC5940, but I am familiar with the ethernet shield, and what will interfere with it. D10 should not be used by any other device. Don't use D4 either, unless you never plan on using a SD card in the shield slot. That is the slave select for the SD card.


so is it out of the question to choose a different pin than D10 for the ethernet slave select?


Not out of the question. I don't do it, but I have seen posts on the forum where it has been done.

If there is no mention of the BLANK pin, you might try disconnecting that connection from the Arduino. Don't connect the TLC5940 to D10.

Do you know which pin is the SPI slave select for the TLC5940? You will need to know that to initialize the SPI devices.


never mind on changing the ethernet slave select as this seems to be somewhat hardwired through the shield and anything different would have to be connected through wires aka not connecting the shield directly to the top of the arduino.

so i guess i will have to figure out how to change the BLANK pin for use by the TLC5940.  According to the playground reference on arduino.cc:
BLANK: this marks the end of a PWM cycle in addition to blanking the output. We will reprogram TIMER1 to generate this signal. That will cost us the native PWMs on digital 9 and digital 10. (Tie a real, physical pull-up resistor on this line to keep things blanked while your Arduino boots. Depending on your hardware, it is possible that the TLC5940 would come up in a configuration that would dissipate too much power.)

So theoretically it should be as simple as finding another timer to use on the arduino


So theoretically it should be as simple as finding another timer to use on the arduino

And this is not possible as the TLC5940 library needs Timer1 and Timer2 to drive the different pins as well as the millis() function which depends on Timer0 being used for it's functionality. But you can use the TLC5940 and the Ethernet shield together if you use another SS pin for the Ethernet shield (you have to modify the shield for that). The only requirement of the shield is that pin 10 is configured as an output and this is the case with the TLC5940 library.
If you want to have it easier, go with an Arduino Mega2560, you have more timer available and more PWM pins, so pin 10 is free for the Ethernet shield.


Im actually going to be using the mega1280 which as i understand, has timers on 5,6,9,11,46.(and timer0 but im not using that)
But i am already using 46 to drive an infrared led as a universal remote (IRremote Library)
TLC and ethernet share pins, 13,11 and 10.  13 and 11 are ok but 10 needs to be changed for the ethernet, and this should be relatively easily done in the library?  And tlc absolutely needs 9 and 3 as timer outputs.

This summarizes what we have been discussing right?  Is everything correct I hope. I really should stop working on this and study for my microwave active circuits class, haha oh well

Go Up