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);
}
Graph provide 1kHz
Graph provide 5kHz
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?
#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);
}
Graph provide 1kHz
Graph provide 5kHz
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?