Minimal cycle time for Uno

First ever post for me. I am building a capacitive discharge ignition (CDI) for my motorcycle which will incorporate an Arduino Uno into an existing CDI circuit. The arduino will just be the "heart beat" of the device. I'm just learning how to use the arduino and have been following the tutorials, etc. Finally got to several variations of my intended program and was dismayed to find that they all became unstable at around 3500 rpm engine speed. (signal generator input -- oscilloscope output) So I started putting microsecond timers in the program.

It seems that no matter what I do, the minimal loop() cycle time is around 32,000 usecs. I get that even when running an "empty program" with no code in it. That is too great a cycle time by at least a factor of four (or five). With an engine speed of around 7000 rpm I need to be able to have a max cycle time of around 8500 usecs.

Now, understand I don't know what I'm doing --- lol --- so I'm hoping someone can tell me that there is a much faster way of trying to get the Uno to run timing circles. Looking forward to any help in this matter. {{ or do I simply need a faster controller?}}

regards,

geo

the minimal loop() cycle time is around 32,000 usecs.

Don't see any code to support this claim .

Hopefully I did the upload correctly. If not, I'll try again. The simple program shows cycle times of right around 32,000 usecs on my Uno. If I'm doing something wrong, please advise.

geo

averagetiming06.ino (775 Bytes)

If I'm doing something wrong, please advise

You're not posting your code, so we don't know what you're doing.

Aways post code in code tags

 //first attempt at a timing function with averaging
 //"time" is the raw time reading - in usecs.
 
 int const PULSE = 2;                  // the input pin
 int unsigned long time = 0;               // the raw input time in usecs.
 int const LED = 13;                   // outputting to LED @ pin 13
 int unsigned long test = 0;


 void setup()
 {
 // set pin 13 as an output:
  pinMode(LED, OUTPUT);
 // set pin 2 as a digital input:
  pinMode(PULSE, INPUT);
  // initialize all the "readings" to 50000.
  // this basically means the engine starts up at 1200 rpm.
  Serial.begin(9600);
 }

 void loop ()
 {
   test = micros();
   Serial.print("start  ");
   Serial.println(test);


       test = micros();
       Serial.print("end  ");
       Serial.println(test);
  }

The above is your code. The code does NOT measure the time it takes for a loop nor does it measure anything else. It could be used (with a lot of work) to find the baud rate but we already know that.

Mark

The Serial.println() command is itself relatively slow so it should not be included in your test loop.

The simplest way to test the time of a code loop is to save the start time (millis()) before the loop starts. Then run the loop 1000 times (say) and then when the loop is finished save the end time (again with millis()). And after all that print the difference between start and end and divide it by 1000 for the time of each loop. If the loop is very short it may be worth doing 10000 iterations.

It's probably easier to do all of this within setup() so that it just goes through the process once.

...R

Thanks mucho for the help. I'll give it a try. Previously, I did wonder about the serial print being the dominant factor and your explanation helps confirm it.

The code I posted up (incorrect method but next time I'll know how to do it) was just my "reduced code." When I composed the actual timing program I had two separate means: neither of which was stable above ~58 Hz. Definitely a case of aliasing. The first method used a couple algebraic functions to get my timing advance. Thinking that the floating point math (simple but still....) was causing the problem, I switched over to an array assignment scheme. Same problem. So I started inserting the clocks. The results were bizarre. In some cases I'd see a short half loop of around 640 usecs and a longer half loop of around 32,000 usecs. In other cases I'd see the half loops split to around 16,000 usecs but they always totaled to around 32,000 usecs.

That got me thinking as to just how fast I should expect an "empty loop" to run, i.e. how fast I SHOULD expect the Uno to cycle. And here we are...

So I won't give up on the Uno yet. I'll run more tests and report back as appropriate.

One more question - this section of the overall forum seemed to be the best for my initial question. In the future, is there a more appropriate section to post to? As y'all know, I am very new to this.

Thanks again.

geo

The Atmega 328 processor does most of its machine code instructions in one clock cycle - in other words 16 million per second on an Uno. Obviously some of the Arduino commands such as serial.print and digitalWrite use up quite a few machine code instructions. But if you need very high speed you can dispense with the printing and use "direct port manipulation" in place of digitalWrite. In general the compiler produces very efficient code.

This is a good enough place for this topic. The alternative might have been the Microcontrollers section. The best thing is to read a few of the Forum sections so that you get a feel for what goes where. The one thing NOT to do is post the same question in more than one place.

...R

Thanks again for the very helpful insight. I wasn't aware that the ATM328 was a 16 MHz controller - I thought I had read something much lower. But surely 16 MHz should get the job done. My guess is that ME being so low on the learning curve as I am at present, I'm probably doing something to inhibit good response. We'll get into that later on after I can do some more experimenting. Eventually with help from this site I'll get to the Land of Good Performance.

{{And I DID find the section in the FAQ on how to post up code correctly -- lol -- somehow I had read through it and missed it the first time around}} So in the future I'll get my code posted up properly when I have questions.

OK - "back to the laboratory Schmedly....." as the saying goes.

geo