How long does analogWrite() take?

Hi,
I'll be programming my Arduino Duemilanove to recieve DMX values (from scratch, it's a school assignment). It will have to output to 3 LEDs, using PWM. Since it'll be very time-sensitive, I need to know how long the analogWrite function takes. Does anyone know this?
Yours,
Rchard2scout

It funtions too fast.
If you want to brighten and dim the LED u would have to use delay() function

I need it to function fast, preferably within a few microseconds. It recieves a DMX value and it has to output this value as soon as possible.

Here's a completely off-the-wall crazy idea; why don't you time it?
Radical, huh?

@gshubham96:
The concept of "too fast" isn't really sensible with a protocol pushing 250 000 bits per second though a microcontroller

Assuming that human beings will be looking at your LEDs do you really think you have to have your changes happen within a few microseconds? I would think that a few milliseconds would be sufficient. The processor in the Arduino can execute up to 16 instructions per microsecond and up to 16,000 instructions per millisecond. I think that the AnalogWrite function will be satisfactory.

Don

The problem here is that it shouldn't take so long that the uart misses the next characters in the (fast!) serial communications stream. The actual brightness changes don't need to be fast (and since the PWM is on about a 1kHz frequency, they certainly won't be.)

I think analogWrite() is fast enough. Since this is for an assignment, I would say: 1) Look at the code and figure it out. 2) if analogWrite() isn't fast enough, the class is significantly different in what it is teaching! 3) I think I can convince myself that there are ways that the speed of analogWrite() need not be relevant. Can you think of how to do this (hint: does the Arduino have to receive the entire DMX message, or only the part relevant to the lights connected to it?)

I'd be more worried about whether Serial.read() and set can keep up with DMX speeds (but perhaps it isn't actually running that fast...)

OTOH, the concept of "too fast" is imminently sensible compared to the reaction time of the human eye.

Made clear by the invention of the motion picture and projector, where individual film frames are exposed/displayed at just a certain standard frames per second rate and to the human eye it's a continuous process, no need to move to a higher rate then what the eye can discern (outside of special high speed applications).

Lefty

the concept of "too fast" is imminently sensible

Do you mean "it is about to become sensible"?

Or did you mean "eminently"?

I indeed mean that I don't want to miss any DMX signals while using analogWrite(). I just recieved my Duemilanove, so I'm currently writing a program to test how long it takes. I don't think the serial speed is too high: a bit is 4uS long, so that translates to a serial speed of 250,000 bits/sec (=baud), which is possible. I indeed don't need to refresh the values sent to the LEDs every time, once every few ms should be enough. Thanks for the comments!

Ok, I've been monitoring how long it takes, i created a loop with 10 analogWrites in it. It ran 168887 times, and the average time was 77.1 uS. Most took 76 uS, but I've also seen 80 and 84 uS. (I used micros(), which has a resolution of 4 uS)
Here's my code, can you look at it to see if the data is legit?

/* program to test how long analogWrite takes */

const byte analogPin = 3;  //the PWM pin to test

void setup()
{
  Serial.begin(38400);
  pinMode(analogPin,OUTPUT);
}

void loop()
{
  unsigned long starttime = micros();
  unsigned long endtime;
  analogWrite(3, 0);
  analogWrite(3, 26);
  analogWrite(3, 51);
  analogWrite(3, 77);
  analogWrite(3, 102);
  analogWrite(3, 128);
  analogWrite(3, 153);
  analogWrite(3, 204);
  analogWrite(3, 230);
  analogWrite(3, 255);
  endtime = micros();
  unsigned long totaltime = endtime - starttime;
  Serial.print(starttime);
  Serial.print("\t");  //tabs for easy copying to MS excel
  Serial.print(endtime);
  Serial.print("\t");
  Serial.println(totaltime);
}

Ok, I've been monitoring how long it takes, i created a loop with 10 analogWrites in it. It ran 168887 times, and the average time was 77.1 uS. Most took 76 uS, but I've also seen 80 and 84 uS. (I used micros(), which has a resolution of 4 uS)

Hey, who gave you permission to actually try something? Are you trying to set a precedence or something? :stuck_out_tongue:

Your code looks OK, and 76 us for 10 analogWrite()s plus a bit of overhead sounds about right. Looking at the code, the actual speed might be dependent on exactly which pin you use...

I changed the code a bit, analogWrite(3,0) etc became analogWrite(analogPin,0) etc. That didn't make a difference in time. However, different pins do give different times:
3:77uS
5:75uS
6:73uS
9:73uS
10:80uS
11:76uS
It seems pin 10 is significantly slower, I don't know why this is. Pin 6 and 9 are the fastest.

different pins do give different times ... I don't know why this is

The code has

switch(timer) {
case TIMER0A:
   //blah
case timer0B:
  // blah
case timer1A:
  // blah
//etc

which will usually results in the same code as you'd get with:

if (timer == TIMER0A) {
} else if (timer == TIMER0B) {
} else if timer == TIMER1A) {
} else if ...

so timers that appear first in the chain will be slightly faster. Also, timer0 is slightly faster to access than the other timers, because it appears in the address range where it can be accessed by IN and OUT instructions.