Pages: [1]   Go Down
Author Topic: How fast is an Arduino ...  (Read 1099 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Full Member
***
Karma: 0
Posts: 207
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

First post, and new to Arduinos, but not electronics or Microcontrollers.

I havea few questions whilst I wait for my Arduino to arrive:

1) How fast does an Arduino output go up and down with this code:

Code:
int outPin = 13;                
void setup()
{
  pinMode(outPin, OUTPUT);
}
void loop()
{
  digitalWrite(outPin, HIGH);
  digitalWrite(outPin, LOW);  
}

and would it be a square wave?

2) Is the C-like source code compiled to native AVR instructions or some intermediate code that is interpreted by the AVR at run time?

Thanks,

Mike
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't know but you might find the answer on www.linuxformat.co.uk. Go on the hardware forum. There's lots of useful stuff there. Good luck! 8-)
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 207
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for your reply ... looking at the forum you suggest, there is a little Arduino info, but not much. My questions were pretty much Arduino specific, so I should hope an authoritative answer would be available here.

Regards,

Mike
Logged

Forum Administrator
Cambridge, MA
Offline Offline
Faraday Member
*****
Karma: 12
Posts: 3538
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The digitalWrite() function is somewhat slow, plus there's the overhead of calling into the loop() function.  You'll get a square wave, but it won't have a 50% duty cycle.  If you need a faster frequency, you can manipulate the port registers directly: see the reference for port manipulation.

Arduino code is straight C/C++ (with a small bit of preprocessing, see the build process page) that is compiled down to native AVR instructions (using avr-gcc and avr-g++).
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 207
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for that, Mellis, much appreciated.

I guess this is something I'll be able to look at when my board arrives, but I'm trying to get a handle on the performance of the system before then.

If not 50% duty cycle, then what would I expect to see? >49% or more like 40%?

Any idea what frequency this will go at?

Like I said, I'm really just trying to get a handle on the performance of the system, rather than actually doing this.

Cheers,

Mike
Logged

Forum Administrator
Cambridge, MA
Offline Offline
Faraday Member
*****
Karma: 12
Posts: 3538
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm not sure of the details, sorry.  Someone else might have a better idea.
Logged

0
Offline Offline
Faraday Member
**
Karma: 8
Posts: 2526
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I'm trying to get a handle on the performance of the system
The system runs at 16MHz. Nearly all AVR instructions are executed in one clock cycle, so you'll be executing instructions at about 16 million instructions/s.

When using a high level language (like C), the way you write your program has a serious impact on performance.   For example, let's look at the code you posted:
Code:
int outPin = 13;                
void setup()
{
  pinMode(outPin, OUTPUT);
}
void loop()
{
  digitalWrite(outPin, HIGH);
  digitalWrite(outPin, LOW);  
}
The main() function is provided by the Arduino environment.  It calls setup() once, then calls loop() once each time through its main event loop, so the sequence of events is:
  • main() does some stuff
  • main() calls setup()
  • main() does some stuff
  • main() calls loop()
  • loop() calls digitalWrite()
  • ldigitalWrite() sets the pin low
  • loop() calls digitalWrite()
  • digitalWrite() sets the pin low
  • main() does some stuff
  • ...

Now this is pretty fast - way too fast to generate PWM for a typical servo, for example.  I haven't measured the actual resulting clock rate for such a system, and to be honest I'm just too lazy to pull out the o-scope and arduino to set it up and see right now (I'm on vacation smiley ).


We can make the pin toggle faster by looping inside our own loop() function:
Code:
#define PIN 13;                
void setup()
{
  pinMode(PIN, OUTPUT);
}
void loop()
{
  while(1)
  {
    digitalWrite(PIN, HIGH);
    digitalWrite(PIN, LOW);  
  }
}

We never leave our loop function's infinite while loop, so the new sequence of events is:
  • main() does some stuff
  • main() calls setup()
  • main() does some stuff
  • main() calls loop()
  • loop() calls digitalWrite()
  • ldigitalWrite() sets the pin low
  • loop() calls digitalWrite()
  • digitalWrite() sets the pin low
  • loop() calls digitalWrite()
  • ldigitalWrite() sets the pin low
  • loop() calls digitalWrite()
  • digitalWrite() sets the pin low
  • ...

Note we're calling a function that does some stuff before it gets around to setting the output pin state.  Let's say that is still not fast enough, and we want to see as close to a 16MHz square wave as we can get.
Code:
#define PIN 13;                
void setup()
{
  pinMode(PIN, OUTPUT);
}
void loop()
{
  while(1)
  {
    PORTB = 0x40; // set pin 13 to high, all other port B pins low
    PORTB = 0x00; // set pin 13 and all other port B pins low
  }
}

As best I can tell, this will get the absolute maximum square wave of 16MHz.  Note we're not doing anything else, not even testing to break out of the loop.  If we wanted to execute this loop N times, we'd slow down to a maximum of 8MHz or so.  Also note we may be occasionally interrupted by a service routine that is triggered by an internal timer, so our square wave could pause every so often.

That's about enough random blathering from me.  If you'd like a better answer, tell us what you are trying to do and that will in turn make our answers a bit more meaningful.

-j
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 207
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks, kg - very informative.

It is not part of a project - I'm just trying to get to grips with the system.  It is always possible that the Arduino environment would put a significant overhead on the code and that the c compiler would produce complete rubbish (I have seen some bad assembler produced by c compliers in my time).

Using your last code snippet:

Code:
while(1)
  {
    PORTB = 0x40; // set pin 13 to high, all other port B pins low
    PORTB = 0x00; // set pin 13 and all other port B pins low
  }

one would hope that would end up as 2 single instructions and a goto. If so, and the goto also takes a single clock cycle, we're looking at a ~33% duty cycle with 5.3MHz frequency.

Not too shabby.

As you say, the Arduino system also does some periodic stuff - keeping track of milli seconds, for example, so my nice output will be interrupted from time to time.

Mike

« Last Edit: December 28, 2007, 04:20:30 am by BigMike » Logged

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 134
Posts: 6763
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Not too shabby.
People have managed to generate video entirely by software with an AVR no faster than the one used in the arduino...
Logged

0
Offline Offline
Faraday Member
**
Karma: 8
Posts: 2526
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
one would hope that would end up as 2 single instructions and a goto. If so, and the goto also takes a single clock cycle, we're looking at a ~33% duty cycle with 5.3MHz frequency.
Doh!  You're right of course, I forgot the jump instruction.

-j

Logged

Pages: [1]   Go Up
Jump to: