TLC5940 + MCP3208 ADC together on SPI

Hello,

for my latest project I have developed a board that incorperates a TLC5940 chip and a MCP3208, both use the SPI bus. I can get both chips to work perfectly separate but together they won’t. Do I have to treat the TLC and MCP as independent slaves or can they be daisy chained? The setup I have now is independent so the MOSI and SCK lines are shared (TLC doesn’t use MISO). I use an Arduino Mega 2560. The code I use to test is:

#include "Tlc5940.h"

#define SELPIN 53 //Selection Pin 
#define DATAOUT 51//MOSI 
#define DATAIN  50//MISO 
#define SPICLOCK  52//Clock 
int readvalue; 

void setup()
{
  Wire.begin();
  Serial.begin(115200);
  Tlc.init();
   //set pin modes 
 pinMode(SELPIN, OUTPUT); 
 pinMode(DATAOUT, OUTPUT); 
 pinMode(DATAIN, INPUT); 
 pinMode(SPICLOCK, OUTPUT); 
 //disable device to start with 
 digitalWrite(SELPIN,HIGH); 
 digitalWrite(DATAOUT,LOW); 
 digitalWrite(SPICLOCK,LOW); 
}

int read_adc(int channel){
  int adcvalue = 0;
  byte commandbits = B11000000; //command bits - start, mode, chn (3), dont care (3)

  //allow channel selection
  commandbits|=((channel-1)<<3);

  digitalWrite(SELPIN,LOW); //Select adc
  // setup bits to be written
  for (int i=7; i>=3; i--){
    digitalWrite(DATAOUT,commandbits&1<<i);
    //cycle clock
    digitalWrite(SPICLOCK,HIGH);
    digitalWrite(SPICLOCK,LOW);    
  }

  digitalWrite(SPICLOCK,HIGH);    //ignores 2 null bits
  digitalWrite(SPICLOCK,LOW);
  digitalWrite(SPICLOCK,HIGH);  
  digitalWrite(SPICLOCK,LOW);

  //read bits from adc
  for (int i=11; i>=0; i--){
    adcvalue+=digitalRead(DATAIN)<<i;
    //cycle clock
    digitalWrite(SPICLOCK,HIGH);
    digitalWrite(SPICLOCK,LOW);
  }
  digitalWrite(SELPIN, HIGH); //turn off device
  return adcvalue;
}

void loop()
{
   Tlc.set(0,0);
   Tlc.update();
   readvalue = read_adc(1); 
   Serial.println(readvalue,DEC); 
   Serial.println(" "); 
   delay(2000);

   Tlc.set(0,4095);
   Tlc.update();
   readvalue = read_adc(1); 
   Serial.println(readvalue,DEC); 
   Serial.println(" "); 
   delay(2000);
}

Regards Edwin

You have to switch the Slave Select lines ON/OFF so the right device is selected when you do a read/write. You cannot select them both => interference

So your board must have a separate SS line per chip and the other SPI lines can be shared.

Can you post a diagram of your board to? (image?)

Hello Rob,

I have drawn a schematic of the connections to the Arduino. See the attached image. I can’t figure out which pin of the TLC is the Slave Select as the TLC is not really “normal” SPI. I hope you can help me out.

Thanks,

Edwin

==> you could add some hardware so that the SIN of the TLC is disconnected from the MEGA if the CS of the MCP3208 is set high. (invertor and an AND port or so)

Furthermore you should monitor the XERP line of the TLC. see datasheet.

Rob

Hello,

I have solved (or better avoided) the problem by putting the TLC5940 in bit bang mode using alternate pins on the Arduino. Has probably some impact on performance but im still in the process of testing that.

Regards Edwin

avoidance is also a solution...

I think you would be better putting the bit banging on the MCP3208 as it has to take less traffic.