Go Down

Topic: How long does analogWrite() take? (Read 1 time) previous topic - next topic

rchard2scout

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

gshubham96

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

rchard2scout

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.

AWOL

#3
Jun 21, 2011, 11:33 am Last Edit: Jun 21, 2011, 11:35 am by AWOL Reason: 1
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
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

floresta

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

westfw

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...)

retrolefty

Quote
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


AWOL

Quote
the concept of "too fast" is imminently sensible

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

Or did you mean "eminently"?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

rchard2scout

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!

rchard2scout

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?
Code: [Select]

/* 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);
}

PaulS

Quote
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?  :P

westfw

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...

rchard2scout

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.

westfw

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

The code has
Code: [Select]
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:
Code: [Select]
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.


Go Up