Arduino appears to slow during a for loop?

Hello,
Just to preface, I am relatively new to arduino.
I am using an Arduino Due to control a AD9959 DDS - I seem to of hit a bit of a roadblock. In my attempts to get amplitude modulation working, I wound up creating a for loop to continously update the values being sent to the DDS registers via SPI.transfer.
However, when I run my code (which appears to be working fine when I Serial.print debug) and look at the output on a spectrum analyser, the amplitude does not ramp up linearly, instead it begins ramping quickly and then the rate of ramp drops (non linearly by the looks of it) to a crawl, though the rate never goes down to '0' so my loops are completing.
I am not sure if it is an issue with my Arduino SPI.transfer timings, the DDS or even my measuring technique.
When I try and do 'manual' sweeps; not using a for loop, the issue does not seem to be present.

I'm just wondering if you more savvy people have any ideas or if my code seem fishy (I will also post to Analog Devices Engineer Zone).
Attached is my code, the area of interest is my void loop - what I've done in my setup is take an integer value (my Amp value) turn into binary, put into an array which I then split into two. (I'm aware this is clunky and there are better ways of doing it)
The actual loop command is meant to just be reading straight from the arrays I have prepared in my setup, so I can't really see how it would influence my problem anyway.

Cheers,
Chris

Chris_Summer_DDS_SingleFreq_AMP_SWEEP_working_code_clean.ino (4.26 KB)

Not sure what all of this is doing exactly, but from just a quick glance at your code you might want to print out the value of k in your for loop and see where it is going. I think I see TEST1 and TEST2 arrays declared 1023 bytes long, N defined as 1023/1 or 1023, and K going from 0 to <= N+1 or, 0 to 1024. Your index to those TEST arrays is 1023-K so at the end it looks like you get a -1 index into your array.

you might also want to fix two other things...

  1. int x = 0.012; //correction for loop time

Integers don't like decimal places so this is probably just x=0;

  1. delay(0.02-x);

delay() takes an argument that represents milliseconds. delay(1000) is a 1 sec delay. Did you mean 20ms - 12ms? or delay(8)?

Putting a serial print inside a fast loop will slow it down. I guess that if you remove them the code will run a lot faster.

Hey guys,
Thanks for your replies - I managed to work out it is not an issue with the arduino and is an issue with the DDS.
@wzaggle: what I was trying to do was have a delay of 20 microseconds - 12 microseconds for a 8 microsecond step size. Cheers for the feedback with regards to my values. The reason for the Test1 and Test2 arrays being 1023 bytes long is that the arduino does not seem to like array[N]={0}.
@Grumpy_Mike: yes that is something that I did observe, however it does not have an effect on my readings.

In any case, thanks to the both of you for taking the time to respond.

delay(0.02-x);

Does the Due allow fractional values for a delay? UNO/NANO etc. require an unsigned long integer.
If Due is the same, this will always evaluate to zero.

Pete

Great!

But I think you are still indexing outside the bounds of arrays TEST1 and TEST2 in several places.

Here is why I think that. Feel free to correct me if I am missing something.

endamp = 1023;
stepsize = 1;
N = endamp/stepsize; //N=1023

byte TEST1[1023]; //Valid indexes into TEST1 and TEST2 arrays are 0-1022 for 1023 places
byte TEST2[1023]; //

void Setup() {
for (int Amp = 0; Amp <= endamp; Amp = Amp + stepsize) { //Amp goes from 0 to 1023;
...
TEST1[1023-Amp/stepsize]=ACR_2; //When Amp=0, Index = 1023 !!!! Maximum is 1022
TEST2[1023-Amp/stepsize]=ACR_3; //
}
}

void loop() {
...
for (int K = 0; K<=(N+1);K++){ //K goes from 0 to (N+1) or 0-1024;
...
SPI.transfer(slaveSelectPin, TEST1[1023-K], SPI_CONTINUE); //When K=0, index = 1023 !!!! Max is 1022
SPI.transfer(slaveSelectPin, TEST2[1023-K], SPI_CONTINUE); //When K=1024, index = -1 !!!! Min is 0
}
}

Not sure exactly what data you are initializing or transferring with these boundary issues but probably not what you are intending and they cause bugs that are really hard to find. If you really want 1024 values indexed from 0 to 1023, I think someday you should consider changing the size of TEST1 and TEST2 to 1024, and change last for loop to stop at N rather than N+1.

Glad its working anyway. :slight_smile:

A couple of years LATE of this one.

But I was trying to run the code from the original post on a DUE (using arduino IDE 1.8.3 and selecting the Arduino Due (Programmng Port) option for the board using the latest board manager download for DUE), and using the DDS-1.0.2 library from :

And I'm getting a 'class DDS' has no member named 'updateIO'.

So then I did some internet searching and noticed the OP mentioning something about forgetting to set the mode of the pin on the arduino to an 'output' pin .... ie forgot to put in the setup area this line : pinMode(7,OUTPUT)

I then also discovered that the DDS library the OP was using wasn't shared by the OP, as they said it belonged to somebody else - which is fair enough. In other words - the OP's code isn't going to work on any particular DUE ---- because the OP didn't send out the library that they used.

So in case anybody else reaches this thread through 'google' while looking for arduino code for the AD9959 ..... the steps I'm currently following are going down a totally different path.

I first download and install the arduino DDS library (re: github - cjheath). I then get the "AD9959_test2.ino" file from : Single Tone Mode of AD9959 with Teensy - Q&A - Direct Digital Synthesis (DDS) - EngineerZone

In that arduino file, I had to comment out lines of code involving terms such as: GPIOC_PDOR &= 191;

And I will then need to leisurely figure out what GPIOC_PDOR relates to - in order to put in the counterpart term for working with the arduino DUE.

I also had to change in a couple of spots --- codewords like "Serial.printf" ..... changed it to Serial.print.

The nice thing so far is ----- once I remove the conflicting lines mentioned above, the code will load into the DUE. The next thing to do is to figure out what to replace "GPIOC_PDOR" with for the DUE, as the code from AD9959_test2.ino was obviously for a TEENSY.

Also, in a different post, the OP mentioned something quite important, that was not mentioned in this thread for the arduino/AD9959 combination. Aside from the issue where the OP forgot to set the pinmode of a particular output pin of the arduino, the OP mentioned this:

The problem was the 1K pull down resistor on the profile pins on the actual PCB board of the DDS. So what was happening is my trigger signal was not strong enough to actually trigger the sweep. I solved this by just putting the arduino output for that pin through a digital buffer and then to the DDS board. My attached code does in fact work fine except for some reason the no-dwell mode does not seem to work.

If I do manage to get something to work with the modified TEENSY code (re: click here to work for the AD9959 DDS module, then I'll be sure to post some workable code here.