CPU SCAN TIME

Hi!

I'm wandering what's the minimal cycle time available in an ARDUINO. For instance, if I write a program like this:

void setup()
{
pinMode(13,OUTPUT);
}
void loop()
{
digitalWrite(13,HIGH);
digitalWrite(13,LOW);
}

and I'm using a typical ARDUINO DUEMILANOVE PCB at 16 MHz, what's the frequency at pin 13??? :o

I'm writing an application with an EM4095 and I think that I'm suffering "aliasing" problems because of this. :-/

Let me know something, please !!!!

Thanks in advance!

/me

been a while since I measured it but as I recall it takes around 2.5 microseconds for two consecutive calls to digitalWrite.

Here are some measurements for your code (first image) and with direct port manipulations (2nd image, fastwrite macros):

2µs/div:

The rotten pulse shape is caused by the cheap scope. It's a nice square wave.

0.1µs/div:

The pulse shape may be nicer in reality. I'm pushing this old scope to its limits here.

As I recall from an experiment I did some months ago comparing simply toggling one output pin using digitalWrite() calls and then using only direct port manipulation, the direct port was like 8X faster (maybe faster, hard to remember but it was significantly faster) I think.

There is quite a bit of overhead using the wire libary function compared to direct port writing but of course you trade off a little portability between the different AVR chips support by the Arduino IDE.

Lefty

There's a complete thread on this subject here too: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1230286016/0

I wrote this sketch to see how long it would take to do the loop a million times.

long counter;
long timer;

void setup() {
  pinMode(13,OUTPUT);
  counter = 0;
}

void loop() {
  digitalWrite(13,HIGH);
  digitalWrite(13,LOW);
  counter++;
  if(counter==1000000)    // loop a million times
  {
    timer=millis();        //how long did it take to reach a million?
    Serial.begin(19200);  //not in setup, because I didn't want to include
               //the time it takes to begin
    Serial.println(timer);
  }
}

I got 9463 ms to go high/low a million times (and increment the counter a million times). So frequency = 1,000,000 / 9.463 = 105,675

Or if you prefer, time of 1 loop = 9.463 microseconds

I assume exiting "loop" and reentering takes time as well, so if you did a for loop a million times, the answer might be different.

Thanks!
I assume that I'll have the same problem with digitalRead() instruction.

/me

if you really care about the time of a single instruction you should really work using assembler... haven't checked how you can make this with arduino yet trough...

if you really care about the time of a single instruction you should really work using assembler...

You don't have to use assembler to get single instruction write times, as madworm illustrated in his post. There have been a few threads with macros posted that can be used in an arduino sketch, try searching for: arduino fastWrite

Thanks again!
I think that some time-critical sections of my code will be written in C and will access directly to AVR SFR instead of using Arduino Library.
It's enough for me!

of course, you can use fastwrite for faster write, but if you really care of that time use direct assembler, like that the result will be predictable on the hardware and will not depend on how the compiler build your code...

I don't think it matters too much if it is predictable, just so long as it is consistent.

of course, you can use fastwrite for faster write, but if you really care of that time use direct assembler, like that the result will be predictable on the hardware and will not depend on how the compiler build your code...

huh?

There is no difference in the code produced by:
sbi 0x0b, 5
or
PORTD |= 1 << 5
and :
fastWrite(5, HIGH)
if you include the fastWrite macros in your sketch.

huh?

There is no difference in the code produced by:
sbi 0x0b, 5
or
PORTD |= 1 << 5
and :
fastWrite(5, HIGH)
if you include the fastWrite macros in your sketch.

not exactly, the fact that "PORTD |= 1 << 5" or "fastWrite(5, HIGH)"
will be translated to "sbi 0x0b, 5" will depend on the compiler choice, it most likely will be, but if you really care of what will be done do it in assembler...

I think it is reasonable to assume that people here will compile using the AVR-GCC compiler. This is unlikely to do anything with PORTD |= 1 << 5 other than produce sbi 0x0b, 5 (on an ATmega168 compatible chip). If you want to make sure the correct code is produced, it's easier and much more portable to use macros and check the expected assembler code is produced using a tool like avr-objdump.exe.