Arduino Due SPI && ADS7883 (How to improve speed?)

Hello guys, I’m trying get a readout of the ADC ADS7883 (48Mhz@12Bit → 3MSPS) with code below. But something must be wrong since I only get a speed of ~250KSPS.

Another problem that i’m getting it has to do with SPI clock (SPI.setClockDivider(10,3);). When I change this line to SPI.setClockDivider(10,2); the clock don’t work properly and i’m missing some data. The clock is also very strange and should be more precise no?!

Can u give me some tips to improve the code (speed of data received) and the experience it self?

I take some pics of clock and circuit used.

Thanks!!

/*-----------*/
/* Librarias */
/*-----------*/

#include <SPI.h>
#include <stdlib.h>

/*--------------------*/
/* Definição de Pinos */
/*--------------------*/

#define MISO 1                 //DOUT  (Não pode ser alterado)
#define SCK 2                  //SCLK  (Não pode ser alterado)
#define MOSI 4                 //DIN   (Não pode ser alterado)
#define CS_ADC_MPPC1 10        //CL do ADC do MPPC 1.

byte EnviarMSB = 0;
byte EnviarLSB = 0;
unsigned short EnviarB = 0;
long  Tempo = 0;
long  Contagens = 0;

unsigned int AContagens[4096];

void setup() {
  Serial.begin(9600);
  SPI.setDataMode(1);
  SPI.begin(CS_ADC_MPPC1);
  SPI.setClockDivider(10,3);
  Tempo = millis();
}

void loop() 
{  
  while((millis()-Tempo) < 1000)ADS7883();
  Serial.println("Canal -> Contagens");
    for(int i = 0; i < 4095; i++)
    {
      Contagens += AContagens[i];
      if (AContagens[i] > 0)
      {
        Serial.print(i);
        Serial.print(" ");
        Serial.println(AContagens[i]);
      }
    }
  Serial.println(Contagens);Contagens = 0; Tempo = millis();
}

void ADS7883(void)
{
  EnviarMSB = SPI.transfer(10, 0xFF, SPI_CONTINUE);EnviarLSB = SPI.transfer(10, 0xFF, SPI_LAST);
  EnviarB = EnviarMSB*256 + EnviarLSB; EnviarB = EnviarB << 2; EnviarB = EnviarB >> 4;
  AContagens[EnviarB]++;
}

Did you wire this on a breadboard? It looks like you have a few bandwith issues. In my experience, breadboards and jumperwires don’t like high clockspeeds.I usually do not go above 8 Mhz, and even 8 MHz can be troublematic. See if things look better at a clock of about 1 MHz, and work your way up.
Also I think that 3 million samples per second might be a bit ambitious. that means reading 6 million bytes per second. That is a lot of bytes for an arduino, even a Due. It takes some serious power to process those bytes. And memory to store it.

Pieter

Oh, and set your scope to dc coupling. That gives a better picture.

Pieter

I take the printscreen’s rushing, sorry for that.

Yes, the circuit was made in a breadboard but seems to work at 26,6 MHz per second without troubles. I want to get at least 1 MSPS (i get it using Raspberry Pi, at 32 MHz/s) with the same experience (in a breadboard). In this case I don’t have much problems.

Relative to the among of bytes used, take a look to the code, i think Arduino can manage in this way.

Thanks for the answer (i will try to make it without breadboard, need to figure out how 1st).

Bellow is a pic of data using Raspberry Pi with ADS7883. The signal was produce by a signal generator and contains a pulse width of 10 microsecond, a lead and trail edge of 1 us.

The problem in speed may be related with some delays in clock. I think that is the big problem :confused:

a raspberry pi is quite something different than an arduino. The cpu is a bit more capable, and runs at allmost ten times the clockspeed. Basically, at the rate of 3msps, you have less than 14 clockcycles to do all those things you are trying to do for each sample. That is not enough. Also, the serial port is set to 9600 bps. that is not exactly fast. not 48 megabit per second fast.

You could try to contlinuesly loop a read action, while checking a break/stop variable. Use a timer to set the break/stop variable.

volatile int continue_loop=1;
...
void setup()
{
    // set the timer and the handler in setup
}
...

while(continue_loop==1)
{
     // only read SPI,do nothing else
}

void timer_handler()
{
    continue_loop=0;
}

calling millis() takes too much time. just the call itself costs precious cpu cycles. at one msps you need a buffer of about 2 Mbyte if you break the loop once every second, so the timer needs to be shorter than that. Output of the samples is going to be a bit tricky. SPI is about the fastest interface on a DUE.

Pieter