Using Teensy4.1 with external ADC (ADS8681)

Ruksitakam

New member
In this project, I used a Teensy 4.1 microcontroller to interface with the ADS8681 analog-to-digital converter (ADC) via SPI to perform high-speed data acquisition and log the results to an SD card. The objective was to collect 1000 samples within 1 millisecond, aiming for a sampling rate of 1 MSPS (1 million samples per second). The analog input signal was generated using a function generator producing a 1 Vpp sine wave, and the frequency of the signal was varied through 1 kHz, 2 kHz, 5 kHz, and 20 kHz during testing. The SPI bus was configured at 30 MHz, and the sampled data was stored in a file named adc_dataAOEIEIAR.txt on the Teensy’s built-in SD card. Each 16-bit ADC reading was converted into a voltage using the formula ((adc_value / 65535.0) * 25.0) - 12.5, assuming the ADS8681 was configured in ±12.5 V input range mode. From the results, the plotted sine waves were smooth and accurate at 1 kHz and 2 kHz. However, as the input frequency increased to 5 kHz and especially 20 kHz, the waveform started to appear less smooth and the amplitude measured began to drop below 0.5 V, despite the function generator maintaining 1 Vpp output. This suggests that at higher frequencies, the ADC may not be capturing enough points per cycle, possibly due to SPI limitations, overhead from writing to the SD card, or insufficient processing time between reads. Future improvements may include using DMA, ring buffers, or offloading SD writes to ensure consistent high-speed sampling without data loss or distortion.
#include <Arduino.h>
#include <SPI.h>
#include <SD.h>

#define CS_ADC 10
#define VREF 5.0
#define ADC_RESOLUTION 65535.0
#define NUM_SAMPLES 1000

File dataFile;

uint16_t read_ads8681() {
digitalWrite(CS_ADC, LOW);
uint16_t data = SPI.transfer16(0x0000);
digitalWrite(CS_ADC, HIGH);
return data;
}

void setup() {
Serial.begin(1000000);
while (!Serial);

pinMode(CS_ADC, OUTPUT);
digitalWrite(CS_ADC, HIGH);

SPI.begin();
SPI.beginTransaction(SPISettings(30000000, MSBFIRST, SPI_MODE0));

if (!SD.begin(BUILTIN_SDCARD)) {
Serial.println("SD Card initialization failed!");
while (true);
}
Serial.println("SD Card initialized.");

dataFile = SD.open("adc_dataAOEIEIAR.txt", FILE_WRITE);
if (!dataFile) {
Serial.println("Failed to open file on SD card.");
while (true);
}

dataFile.println("Voltage (V)");
}

void loop() {
unsigned long startTime = micros();
uint16_t adcValues[NUM_SAMPLES];
int sampleCount = 0;

while (micros() - startTime < 1000 && sampleCount < NUM_SAMPLES) {
adcValues[sampleCount] = read_ads8681();
sampleCount++;
}

for (int i = 0; i < sampleCount; i++) {
float voltage = ((adcValues / ADC_RESOLUTION) * 25.0) - 12.5;
dataFile.println(voltage, 4);
}

dataFile.close();

Serial.println("Data saved to adc_data300Khz.txt");

while (true);
}
1743840256738.png

Graph provide 1kHz
1743841674634.png

Graph provide 5kHz
1743841706317.png

Graph provide 20kHz

How should I set the input range or modify the Arduino code to match the signal characteristics when using the ADS8681 with a 1 Vpp sine wave to receive all input correctly?
 
If you look at the chip's datasheet you'll see its input bandwidth is 15kHz for -3dB drop. Section 6.5 electrical characteristics, so what you see is correct. You can see the low pass filter in the chip's block diagram too.

If you want an un-filtered SAR ADC I've used the ADS8881 in the past with good results.
 
If you look at the chip's datasheet you'll see its input bandwidth is 15kHz for -3dB drop. Section 6.5 electrical characteristics, so what you see is correct. You can see the low pass filter in the chip's block diagram too.

If you want an un-filtered SAR ADC I've used the ADS8881 in the past with good results.
I am planning to use an external ADC with the Teensy 4.1 for my Acoustic Emission project, where I need to detect crack frequencies around 150kHz. According to the Nyquist theorem, this requires a sampling rate of at least 300kHz. With the ADS8681 would it still be suitable for detecting frequencies in the 150kHz range, or would it be insufficient? Could you suggest me the new external ADC for this project? Thank you for your answer.
 
Back
Top