Interrupt to trigger SPI read of external ADC (MCP3464)

Hi everyone,

I have been trying to speed up the sampling rate on a SPI controlled ADC for an ECG device and have been stumping my head against the wall.

I am using an external ADC (MCP3464 datasheet) to read ADC data over 8 channels.

Here is how I am reading the adc:

  // SPI full duplex transfer
  digitalWrite(adcChipSelectPin,LOW); 
  SPI.transfer(readConversionData);
  adcReading = (SPI.transfer(0) << 8);
  adcReading += SPI.transfer(0);
  digitalWrite(adcChipSelectPin, HIGH);

I tried single conversion mode, but this was slow speeds of 3200 samples per second. I believe the ESP32 can flash SPI at 80MHz, so surprised it's that slow.

Instead, I have set the MCP3464 to SCAN mode (see page 89 of datasheet) where it completes continuous conversions and you can set delays between each channel and each cycle (8 channels). That way you don't have to write an additional 2 SPI commands to change the channel and start the next conversion.

From the datasheet:
Each conversion within the SCAN cycle leads to a data ready interrupt and to an update of the ADCDATA register as soon as the current conversion is finished. In SCAN mode, each result has to be read when it is available and before it is overwritten by the next conversion result

Hence the data ready interrupt needs to be detected by the ESP32 to immediately read the latest value from the channel, before a new conversion to the next channel occurs.

I have tried waiting for IRQ to be LOW (I am multi-threading so I can afford to blocking wait) :

// wait for IRQ to trigger active LOW indicating data ready state
while(digitalRead(interruptPin));
 *(packetLocation + ((ch+2) + (ts*(interface.numOfCh + 2)))) = adc.read();
*(unsigned long*)(packetLocation + (ts*(interface.numOfCh + 2))) = micros(); 

However this results in slow speeds of around 2640 samples per second and I am worried the synchronicity of reading the correct channel will collapse if just one active LOW is undetected.

I have also tried attaching an interrupt:
attachInterrupt(interruptPin, packageADC, FALLING);
but I am unable to link a non-static method to an IRQ.

Any ideas how to either get the interrupt to work quickly and reliably in SCAN mode or speed up the ESP32 SPI communication in Single shot mode?

Sorry, quite a lot to take in but any suggestions much appreciated!
Thanks in advance,
Will

Your thread may be blocked for some dispatcher time-slices by other threads. I'd try to wait for an event. I have no idea of the ESP firmware, no specific suggestions.

They are on separate cores so it is real parallel computing rather than virtual. Do you know if it's possible to tirgger an event other than a function to get around passing a non static method to attachInterrupt()?

I think that attachInterrupt() is not implemented for your controller. Adding a static method to a class requires a derived class - easy only if you can find the base class.