Strange results from the TLC4541 on a MKRZERO

I want to record ultrasonics up to 80 kHz so I need a fast ADC like the TLC4541 and I found a way to get good data from the it using ‘System’ code lifted from this excellent [Forum][(https://forum.arduino.cc/t/using-a-16bit-adc-with-mega2560/163077/15). As shown the code gives FF00 for each update which is only correct for the first read, indicating the ADC initialized correctly. However the ADC spec says subsequent reads are “terminated early” even though lots of delay is added.

In order to get good results I must first run this code with pinMode(adcCKL, OUTPUT) included at line 23. The results show all FFFF on subsequent reads; but, strangely, if I delete that line, recompile and run again then the ADC reads correctly. Since the ADC was kept powered it apparently retained the correct initialization. I can’t find a work around for this strange behavior, since I need my recorder to work on first power up, standing alone. I’ve tried delays and other statements instead of pinMode(adcCKL, OUTPUT) but nothing initializes and records in one program. I found no library, so are there any suggestions?

#include <SPI.h>
//
// Using a MKRZERO
//with FS tied high (Vdd)


#define adcCS 12     //49 Chip select output. Controls the slave device
#define adcCLK 9     //52 system clock.  We're taking control.
#define MISO_ADC 10  //50 VDO output from ADC, to the Ardiuno.
//#define MOSI_ADC 51//

byte upperByte;  //Most significant BIT
byte lowerByte;  //Least significant BIT
unsigned int adcValue = 0;


void setup() {
  //pinMode(53, OUTPUT);
  SPI.begin();                 //Enables the SPI interface
  SPI.setDataMode(SPI_MODE1);  //Per datasheet for the TLC4541 ADC chip, the SPI interface
                               //is programmed for CPOL=0, CPHA=1.
  pinMode(adcCS, OUTPUT);
  //pinMode(adcCLK, OUTPUT);


  Serial.begin(9600);



  //Reset cycle for the ADC. Initializes the chip on power up. Occurs only 1 time.
  digitalWrite(adcCS, LOW);    // lower the chip select
  digitalWrite(adcCLK, LOW);   // clock low
  digitalWrite(adcCLK, HIGH);  // clock high
  digitalWrite(adcCLK, LOW);   // clock low
  digitalWrite(adcCLK, HIGH);  // clock high
  digitalWrite(adcCS, HIGH);   // rase chip select
}

void loop() {
  // read out data from prior conversion, provide clocks for next conversion

  digitalWrite(adcCS, LOW);  //Enables ADC
  delayMicroseconds(500);
  digitalWrite(adcCLK, LOW);    //clock low
  upperByte = SPI.transfer(0);  // read one byte of result back
  lowerByte = SPI.transfer(0);  // read one byte of result back
  delayMicroseconds(500);
  digitalWrite(adcCLK, HIGH);  //clock high
  delayMicroseconds(500);
  digitalWrite(adcCS, HIGH);  //disables ADC

  adcValue = (upperByte << 8) + lowerByte;  // Moves the upperByte to the left, then adds
                                            //the lowerByte.  Combining the two equals the adcValue.

  digitalWrite(adcCS, HIGH);  //Disables SPI




  Serial.println(adcValue, BIN);  //Prints the ADC Value to Serial port.
                                  //Converts from binary to decimal.

  delay(250);
}

Yes, I know about the noise problem. I do plan an analog filter and some averaging. I just found the Arduino-Pico Docs and it looks like my problem is solved. Thanks for all your help

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.