Delay in reading channels through the adc of the arduino due

Hello, I created a code to monitor 3 CD74HC4067 multiplexers connected to 20 AD620 for an EEG prototype but when taking the readings they take time to take since I programmed them at 250Hz (3960 microseconds) but the taking takes about 28000 microseconds.

#include <DueAdcFast.h> 
#include <SPI.h>
#include <SD.h>

const int chipSelect = 10;  

const int muxSIG[] = {A10, A9, A8}; 
const int muxS0[] = {26, 36, 46};   
const int muxS1[] = {28, 38, 48};   
const int muxS2[] = {30, 40, 50};  
const int muxS3[] = {32, 42, 52};   


const int FIR_ORDER = 20;
float firCoeffs[FIR_ORDER] = {-0.0026732205, -0.0002657975, 0.0061694570, 0.0099500723, -0.0068196105, -0.0419967441, -0.0467231195,
0.0371154881, 0.1969794762, 0.3296046869, 0.3296046869, 0.1969794762, 0.0371154881, -0.0467231195, -0.0419967441, -0.0068196105,
0.0099500723, 0.0061694570, -0.0002657975, -0.0026732205};

float firBuffer[20][FIR_ORDER] = {0};  

DueAdcFast DueAdcF(1024); 

float applyFIR(float newValue, int channelIndex) {
  for (int i = FIR_ORDER - 1; i > 0; i--) {
    firBuffer[channelIndex][i] = firBuffer[channelIndex][i - 1];
  }

  firBuffer[channelIndex][0] = newValue;
  float filteredValue = 0;
  for (int i = 0; i < FIR_ORDER; i++) {
    filteredValue += firBuffer[channelIndex][i] * firCoeffs[i];
  }
  
  return filteredValue;
}

void setupADCAndTimer() {
  analogReadResolution(12);   
  DueAdcF.EnablePin(A10);
  DueAdcF.EnablePin(A9);
  DueAdcF.EnablePin(A8);
  DueAdcF.Start1Mhz();  
}

void SetMuxChannel(int muxIndex, byte channel) {
  digitalWrite(muxS0[muxIndex], bitRead(channel, 0));
  digitalWrite(muxS1[muxIndex], bitRead(channel, 1));
  digitalWrite(muxS2[muxIndex], bitRead(channel, 2));
  digitalWrite(muxS3[muxIndex], bitRead(channel, 3));
  delayMicroseconds(1);  
}

void setup() {
  Serial.begin(115200);

  for (int i = 0; i < 3; i++) {
    pinMode(muxS0[i], OUTPUT);
    pinMode(muxS1[i], OUTPUT);
    pinMode(muxS2[i], OUTPUT);
    pinMode(muxS3[i], OUTPUT);
    pinMode(muxSIG[i], INPUT);  
  }

  setupADCAndTimer();
  
  if (!SD.begin(chipSelect)) {
    Serial.println("Fallo la inicialización de la tarjeta SD!");
    while (1);  
  }
  Serial.println("Tarjeta SD lista para usar.");
  
  File dataFile = SD.open("EEG_data.csv", FILE_WRITE);
}

void loop() {
  unsigned long startTime = micros();  
  float sensorValues[20]; 
  String output = "";     

  // Leer canales del multiplexor 1 (A10)
  for (byte i = 8; i <= 15; i++) {
    SetMuxChannel(0, i);
    float rawValue = DueAdcF.ReadAnalogPin(A10);
    sensorValues[i - 8] = applyFIR(rawValue, i - 8);  
    output += String(sensorValues[i - 8], 3) + ", ";
  }

  // Leer canales del multiplexor 2 (A9)
  for (byte i = 8; i <= 15; i++) {
    SetMuxChannel(1, i);
    float rawValue = DueAdcF.ReadAnalogPin(A9);
    sensorValues[8 + (i - 8)] = applyFIR(rawValue, 8 + (i - 8));  
    output += String(sensorValues[8 + (i - 8)], 3) + ", ";
  }

  // Leer canales del multiplexor 3 (A8)
  for (byte i = 12; i <= 15; i++) {
    SetMuxChannel(2, i);
    float rawValue = DueAdcF.ReadAnalogPin(A8);
    sensorValues[16 + (i - 12)] = applyFIR(rawValue, 16 + (i - 12)); 
    output += String(sensorValues[16 + (i - 12)], 3);
    if (i < 15) output += ", ";  
  }

  File dataFile = SD.open("EEG_data.csv", FILE_WRITE);
  if (dataFile) {
    dataFile.println(output);  
    dataFile.close();
  }

  unsigned long loopTime = micros() - startTime;
  Serial.print("Loop time: ");
  Serial.println(loopTime);

  if (loopTime < 3960) {
    delayMicroseconds(3960 - loopTime);  
  }
}

void ADC_Handler() {
  DueAdcF.adcHandler();
}

I wanted to know if anyone has already had any type of similar problem. I appreciate any help. Have a good day.

this might be costly. Closing the file triggers a dump of the buffer onto the SD card and depending on the state of the SD you might have extra delays too.

How many samples do you need? may be you can keep them in RAM and dump when they are all received? or alternatively you could open the file only once and close it later, letting the library manage the buffering and writing to the SD card. Do expect some lag at the point though.

Have you considered how often you need to measure each channel to get a valid representation of the signal?

We really need a schematic

Hi, @luis_em24

Have you looked at the read time required of the DUE ADC to get a valid reading of the analog channel it is connected too?

If you read too quickly the ADC input may not have reached the input voltage that it has been switched too?

Tom... :smiley: :+1: :coffee: :australia:

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