Interfacing Arduino MKR1000 with TDC1000 using SPI

Hi,

I’m creating an ultrasonic flow-meter using the TDC1000, TDC7200, and Arduino MKR1000. Since this is my first time working with SPI, I thought I’d start by just reading and writing to and from CONFIG_0 on the TDC1000.

The arduino only reads zeros.
I’ve tried all the arduino’s different SPI modes (0-3).

After a couple weeks I can’t figure out what I’m doing wrong. I would greatly appreciate help in troubleshooting the below code.

Thanks.

#include <SPI.h>

int selectTDC1000 = 5;
int selectTDC7200 = 0;

int enableTDC1000 = 7;
int enableTDC7200 = 1;

int dataReadyPin = 4;
int channelSelect = 3;

byte CONFIG1_address = 0x00;
byte CONFIG1_instruction = 0x00;
unsigned int whatWasRead = 0x00;

unsigned int readRegister(int device, byte address, int bytesToRead);
void writeRegister(int device, byte address, byte data);

void setup()
{
  Serial.begin(9600);
  SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));

  pinMode(selectTDC1000, OUTPUT);
  pinMode(selectTDC7200, OUTPUT);

  pinMode(enableTDC1000, OUTPUT);
  pinMode(enableTDC7200, OUTPUT);

  pinMode(dataReadyPin, INPUT);
  pinMode(channelSelect, OUTPUT);

  digitalWrite(selectTDC1000, HIGH);//active low
  digitalWrite(selectTDC7200, HIGH);//active low

  digitalWrite(enableTDC1000, LOW);
  digitalWrite(enableTDC7200, LOW);
  
}

void loop()
{  
  digitalWrite(enableTDC1000, HIGH);
  delayMicroseconds(350);
  
  //***Read and print register***********************************  
  whatWasRead = readRegister(1000, CONFIG1_address, 1);

  Serial.print("Before write: ");
  Serial.println(whatWasRead, BIN);
  //*************************************************************
  
  //***Write new byte to register, read byte from register*******
  writeRegister(1000, CONFIG1_address, 0x02);
    
  whatWasRead = readRegister(1000, CONFIG1_address, 1);
  
  Serial.print("After write: ");
  Serial.println(whatWasRead, BIN);
  Serial.print("\n");
  //*************************************************************
  
  digitalWrite(enableTDC1000, LOW);
  
}

void writeRegister(int device, byte address, byte data)
{

  if(device == 1000)
  {
    digitalWrite(selectTDC1000, LOW);//low active
  }
  else if(device == 7200)
  {
    digitalWrite(selectTDC7200, LOW);//low active
  }
  
  address |= 1000000;
  
  SPI.transfer(address);
  SPI.transfer(data);

  if(device == 1000)
  {
    digitalWrite(selectTDC1000, HIGH);//low active
  }
  else if(device == 7200)
  {
    digitalWrite(selectTDC7200, HIGH);//low active
  }
  
}

unsigned int readRegister(int device, byte address, int bytesToRead)
/* device: 1000 or 7200.
 * address: register address on specified device.
 * how many bytes long is the data we're reading?
 */
{

  byte inByte = 0;           // incoming byte from the SPI
  unsigned int result = 0;   // result to return
  Serial.print("Address we're reading from: ");
  Serial.print(address, BIN);
  Serial.print("\n");

  if(device == 1000)
  {
    digitalWrite(selectTDC1000, LOW);//low active
  }
  else if(device == 7200)
  {
    digitalWrite(selectTDC7200, LOW);//low active
  }
  
  byte readFromThisRegister = address;//read bit comes before address (MSBF) so 0b000000 = 0b0000000

  SPI.transfer(readFromThisRegister);
  result = SPI.transfer(0x00);

  bytesToRead --;
  
  while(bytesToRead > 0)
  {

    result = result << 8;
    inByte = SPI.transfer(0x00);    
    result = result | inByte;
    bytesToRead --;
    
  }

  if(device == 1000)
  {
    digitalWrite(selectTDC1000, HIGH);//low active
  }
  else if(device == 7200)
  {
    digitalWrite(selectTDC7200, HIGH);//low active
  }
  
  return result; 
}

I've tried all the arduino's different SPI modes (0-3).

According to the datasheet the device is expecting SPI mode 3.

SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));

Does your application really need the highest possible frequency the chip supports? At 16MHz the length of the SPI connections must be very short and well shielded, so a breadboard setup probably won't work. BTW I'm missing a wiring diagram. How did you connect the Arduino to the chip?

The SPI.beginTransaction() call should be in the register read/write routines and in the setup() there should be an SPI.begin() call.

Thanks, pylon.

I’ve attached the wiring diagram.

wiring-diagram.png

Thanks, pylon.

I’ve made the changes you’ve suggested (see below), but I’m still just reading 0’s.

I also simplified the code to just read and not write.

:frowning: :frowning: :frowning:

#include <SPI.h>

int selectTDC1000 = 5;
int selectTDC7200 = 0;

int enableTDC1000 = 7;
int enableTDC7200 = 1;

int dataReadyPin = 4;
int channelSelect = 3;

byte CONFIG_0_address = 0x00;
unsigned int whatWasRead = 0x00;

unsigned int readRegister(int device, byte address, int bytesToRead);
void writeRegister(int device, byte address, byte data);

void setup()
{
  Serial.begin(9600);
  SPI.begin();

  pinMode(selectTDC1000, OUTPUT);
  pinMode(selectTDC7200, OUTPUT);

  pinMode(enableTDC1000, OUTPUT);
  pinMode(enableTDC7200, OUTPUT);

  pinMode(dataReadyPin, INPUT);
  pinMode(channelSelect, OUTPUT);

  digitalWrite(selectTDC1000, HIGH);//active low
  digitalWrite(selectTDC7200, HIGH);//active low

  digitalWrite(enableTDC1000, HIGH);
  digitalWrite(enableTDC7200, LOW);
  
}

void loop()
{  
  delayMicroseconds(350);
  
  //***Read and print register***********************************  
  whatWasRead = readRegister(1000, CONFIG_0_address, 1);

  Serial.print("CONFIG_0: ");
  Serial.println(whatWasRead, BIN);
  //*************************************************************
  
}

unsigned int readRegister(int device, byte address, int bytesToRead)
/* device: 1000 or 7200.
 * address: register address on specified device.
 * how many bytes long is the data we're reading?
 */
{

  byte inByte = 0;           // incoming byte from the SPI
  uint32_t result = 0;   // result to return
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3));

  if(device == 1000)
  {
    digitalWrite(selectTDC1000, LOW);//low active
  }
  else if(device == 7200)
  {
    digitalWrite(selectTDC7200, LOW);//low active
  }

  SPI.transfer(address);
  result = SPI.transfer(address);

  bytesToRead --;
  
  while(bytesToRead > 0)
  {

    result = result << 8;
    inByte = SPI.transfer(0x00);    
    result = result | inByte;
    bytesToRead --;
    
  }

  if(device == 1000)
  {
    digitalWrite(selectTDC1000, HIGH);//low active
  }
  else if(device == 7200)
  {
    digitalWrite(selectTDC7200, HIGH);//low active
  }
  SPI.endTransaction();
  delayMicroseconds(50);
  
  return result; 
}

I currently don't find any error in your code. In the wiring I would remove the connection from CLKIN to pin 9 (not necessary) and connect RESET to GND (to not let it floating).

If that doesn't help I would check with a logic analyzer.

Thanks, pylon. Well, I can read and write from the TDC7200 now, but not the TDC1000, which is weird as the chips are similar and made to work together. :(

Are you sure your TDC1000 is working correctly?

I've tried it with two different TDC1000s, so the fault is probably mine.

Hello, NikBruce

Your code is helpful to me. Have you completed this project? I have some problems that cannot be solved.