This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TDC7200: TDC7200 - TDC1000

Part Number: TDC7200
Other Parts Discussed in Thread: TDC1000, , MSP430FR6047

Hello, 

I'm working on a project to develop an ultrasonic flowmeter using the time of flight (TOF) method. I'm using 2 transducers (2 MHz), TDC1000 (AFE) and TDC7200. I am also using an Arduino Uno R3 card. The results I get are random values that have no meaning.

Can anyone help me solve this?

Here's my Arduino code:

Libraries:

#include "TDC1000.h"
#include "TDC7200.h"
#include <Adafruit_SI5351.h>
#include <SPI.h>
//---------------------------------//

#define PIN_TDC7200_ENABLE (8)
#define PIN_TDC7200_SPI_CSB (10)
#define PIN_TDC7200_INT (3)
#define TDC_CLKIN_FREQ_HZ 16000000

#define PIN_TDC1000_ERRB (7)
#define PIN_TDC1000_RESET (9)
#define PIN_TDC1000_ENABLE (4)
#define PIN_TDC1000_SPI_CSB (5)
#define TDC1000_CLKIN_FREQ_DIV (TDC1000::TxFreqDivider::Div16)

#define NUM_STOPS 5
//---------------------------------//

Adafruit_SI5351 clockgen = Adafruit_SI5351();
static TDC1000 US_afe(PIN_TDC1000_SPI_CSB, PIN_TDC1000_RESET);
static TDC7200 TOF(PIN_TDC7200_ENABLE, PIN_TDC7200_SPI_CSB, TDC_CLKIN_FREQ_HZ);
static bool dataRdy;

void setup() {
  Serial.begin(9600);
  /* Initialise the sensor */
  if (clockgen.begin() != ERROR_NONE) {
    /* There was a problem detecting the IC ... check your connections */
    Serial.print("No Si5351 detected ... Check wiring or I2C ADDR!");
    while (1)
      ;
  }
  Serial.println(" ");
  Serial.println("ClkGen_OK!");
  //Serial.println("Set PLLA to 400MHz");
  clockgen.setupPLLInt(SI5351_PLL_A, 16);
  //Serial.println("Set Output #2 to 400/(25+(0/1)) = 16MHz");
  clockgen.setupMultisynth(2, SI5351_PLL_A, 25, 0, 1);
  clockgen.enableOutputs(true);

  // Initialiser le TDC1000
  if (not US_afe.begin()) {
    Serial.println("Failed to initialize TDC1000");
    while (1)
      ;  // Arrêter l'exécution si l'initialisation échoue
  }

  // Initialiser le TDC7200
  if (not TOF.begin()) {
    Serial.println("Failed to initialize TDC7200");

    while (1)
      ;
  }

  // Arrêter l'exécution si l'initialisation échoue
  if (TOF.begin() && US_afe.begin()) {
    Serial.println("TDC1000 and TDC7200 initialized");
  }

  bool TDC1000_REGok = true;
  TDC1000_REGok &= US_afe.setTriggerEdge(true);
  TDC1000_REGok &= US_afe.setTx(TDC1000_CLKIN_FREQ_DIV, 6 /*pulses*/, 31 /*shift*/, true /*damping*/);
  TDC1000_REGok &= US_afe.setRx(false /*multiEcho*/);
  TDC1000_REGok &= US_afe.setRxSensitivity(TDC1000::RxDacEchoThreshold::m220mV, TDC1000::RxPgaGain::g21dB, TDC1000::RxLnaFbMode::resistive);
  TDC1000_REGok &= US_afe.setRepeat(TDC1000::TxRxCycles::x1, 0 /*expected pulses*/);
  TDC1000_REGok &= US_afe.setTofMeasuementShort(TDC1000::T0::ClkInDiv1, TDC1000::TxAutoZeroPeriod::T0x64, TDC1000::TxBlankPeriod::T0x16, TDC1000::TxEchoTimeoutPeriod::disabled);
  // TDC1000_REGok &= US_afe.setMeasureTOF(TDC1000::TxRxChannel::Channel1, TDC1000::TofMode::Mode2);
  TDC1000_REGok &= US_afe.setMeasureTOF(TDC1000::TxRxChannel::Channel1, TDC1000::TofMode::Mode2);

  if (not TOF.setupMeasurement(10, /*cal2Periods*/ 1, /* avgCycles*/ NUM_STOPS, /* numStops */ 2)) {
    Serial.println(F("Failed to setup measurement"));
    while (1)
      ;
  }

  US_afe.dumpSettings(TDC_CLKIN_FREQ_HZ);
  pinMode(PIN_TDC1000_ERRB, INPUT_PULLUP);  //active low
  pinMode(PIN_TDC7200_INT, INPUT_PULLUP);   // active low
  pinMode(PIN_TDC1000_ENABLE, OUTPUT);
  US_afe.clearErrorFlags();
  US_afe.resetStatemachine();

  attachInterrupt(digitalPinToInterrupt(PIN_TDC7200_INT), onDataRdy, RISING);
  /*
  //Configurer le masque d'arrêt pour supprimer les arrêts pendant la période de synchronisation initiale.
  TOF.setupStopMask(121000000ull);

  //Configure le dépassement de délai si tof prend plus de temps que le délai.
  TOF.setupOverflow(130000000ull);*/
}

void onDataRdy() {
  dataRdy = true;
  return;
}

static void ui64toa(uint64_t v, char* buffer, uint8_t base) {
  int idx = 0;
  uint64_t w = 0;
  while (v > 0) {
    w = v / base;
    buffer[idx++] = (v - w * base) + '0';
    v = w;
  }
  buffer[idx] = 0;
  // reverse char array
  for (int i = 0, j = idx - 1; i < idx / 2; i++, j--) {
    char c = buffer[i];
    buffer[i] = buffer[j];
    buffer[j] = c;
  }
}

void loop() {

  TOF.startMeasurement();

  while (1) {
    if (dataRdy) {
      //measure gathering

      for (uint8_t stop = 1; stop <= NUM_STOPS; stop++) {
        uint64_t time=0;
        if (TOF.readMeasurement(stop, time)) {
          char buff[40];
          ui64toa(time, buff, 8);
          //Serial.println(stop);
          Serial.println(buff);
          delay(1000);
        }
      }
      //delay(100);
    }
  }
}
  • Hello Billal,

    Thanks for positing to the sensors forum! The TDC1000 is no longer recommended for flow meter applications due to a bug mentioned in this FAQ that causes issues with the accuracy of measurements that mainly impacts flow measurements. 

    We typically recommend the MSP430FR6047 or similar device for flow meter applications. I did not review your code but can you explain what you are doing to see if I can help you identify the problem with the measurements.

    Best,

    Isaac

  • Hello Billal,

    I did find some code for the TDC7200 for Aruduino in case you would like to compare with yours to ensure that it was implemented appropriately: github.com/.../TDC7200_v1.5_4Stops.ino

    Best,

    Isaac

  • Thanks for replying, 
    I am working on developing an ultrasonic flow sensor with time of flight measurement method. I use the TDC1000 as the AFE of the transducers and the TDC7200 as the digital-time converter. all this controlled by the Arduino microcontroller (ATMEGA328),