2

So I have a project where I will be using an Arduino Leonardo and an external ADC (AD7980) to run a 16-bit (18bit) conversion and transmit it to the Arduino and then out on USB as fast as possible.

The AD7980 can run up to 1 MSPS, and I know I cannot reach that with the ATmega32U4 - but I want to know how to optimize my code for running it as fast as possible and how to measure it.

Right now my code is:

#include <SPI.h>
int CNV= 11; //Convert on pin 11
int Slaveselect=8;
int adcValue;
byte highByte;
byte lowByte;
void setup() {
 Serial.begin(115200);
 SPI.begin();
 SPI.setClockDivider(SPI_CLOCK_DIV2 ); // 8 MHz rate
 SPI.setBitOrder(MSBFIRST);
 pinMode(Slaveselect, OUTPUT);
 pinMode(CNV, OUTPUT);
}
void loop() {
 digitalWrite(Slaveselect,HIGH);
 // SS always high to use 3 Wire mode without busy indicator
 digitalWrite(CNV,LOW);
 digitalWrite(13,LOW);
 digitalWrite(CNV,HIGH);//starts conversion
 digitalWrite(13, HIGH);
 digitalWrite(CNV,LOW); //starts to transmit MSB on data line
 digitalWrite(13,LOW);
 highByte = SPI.transfer(0x00);
 lowByte = SPI.transfer(0x00);
 adcValue = highByte << 8;
 adcValue = adcValue | lowByte;
 Serial.print("analog value =");
 Serial.println(adcValue);
 Serial.print('\n'); 
}

The datasheet for the ADC can be found here: Datasheet

dda
1,5951 gold badge12 silver badges17 bronze badges
asked Jun 15, 2017 at 9:04

2 Answers 2

1
  1. Don't use digitalWrite().
  2. Don't use delay().
  3. Don't flood your Serial connection with useless junk ("analog value =")

You may also consider using lower level SPI operations instead of the SPI library, which is completely blocking and slows you down. At least consider the use of SPI.transfer16(...) which is more efficient than two SPI.transfer(...) calls.

answered Jun 15, 2017 at 9:30
6
  • "1. Don't use digitalWrite()" What should i use then? Commented Jun 15, 2017 at 9:52
  • @Martin.E Direct port manipulation. arduino.cc/en/Reference/PortManipulation Commented Jun 15, 2017 at 10:00
  • Either write on GPIO registers directly (arduino.cc/en/Reference/PortManipulation, stackabuse.com/speeding-up-arduino) or use at least github.com/NicksonYap/digitalWriteFast . Commented Jun 15, 2017 at 10:01
  • Also - changed my code to not use delay() and changed to SPI.transfer16 - now I have a sample periode of 44 micros - #Edit - With digital write fast, i am now down to 8 Micros Commented Jun 15, 2017 at 10:01
  • But by useing this, It looks like i lost some precision - Before this change, my max ADC value was 32000 - now its around 19000, and my minimum was 0 now it is 10000 Commented Jun 15, 2017 at 10:09
0

For fast possible speed, use spi transmission buffer and spi interrupt. The concept is that once there is at least free space in the buffer, it interrupts and you load the next byte into the buffer.

That's assuming that dma isn't available.

Short of that, don't use arduino GPIO functions - they are like 100x slower than that's possible. And use a usartt isr to manage transmission.

answered Jun 16, 2017 at 11:40

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.