Read duty cycle of a pwm pin on Arduino Mega... ?!

Hi, i've build a little Pool light with 5 3W RGB LEDs, witch is supposed to have new functions (controlable by a IR Remote), on of them would be fading between random Colors, for that i would like to make a fade function, for that function i need to know the previous PWM Values writen to the LEDs, and i wanted to ask if it is possible to "pwmRead" a PWM Pin to obtain the current duty cycles instead of having to save all the Values in to Variables each time the Arduino updates them... This is not really a big problem, i just always feel bad for the Arduino having to save so much values when it's not even absolutely necessary, so i wanted to finally ask if this is absolutely necessary, since i've often asked my self that question "woulden't it be possible to read the PWM pins similar to the digitalRead() with digital pins configured as Output?", googled it, didn't find a answer but also didn't find it necessary to Start a new topic for it... Now where such a function would have come in handy often enough, i thought maybe it's time to finally get an answer for that question...

Thanks in advance,
Delphiño

and i wanted to ask if it is possible to "pwmRead" a PWM Pin to obtain the current duty cycles instead of having to save all the Values in to Variables each time the Arduino updates them...

No.

This is not really a big problem, i just always feel bad for the Arduino having to save so much values when it's not even absolutely necessary

Get over it. The Arduino doesn't mind. That space would be just sitting there containing some random garbage anyway.

I don't get why saving a variable is such a big deal.
The value was in a variable when you did the analogWrite, so why not use that again?

I think it should be possible to get the information from the Arduino timer registers directly.

I'm not exactly sure about the details when using analog write, but if you generated your own PWM signal using timer1 for example, with ICR1 or OCRnA for duty cycle, you should be able to query the value of OCRnA or ICRn at any time to find the duty cycle.

My assumption is that analogwrite uses similar timing functions, so you should be able to grab the details from the Arduino registers. Of course, I could be completely wrong...

Apart from an exercise in microcontroller masochism, why bother?
It's a pool light controller; I find it very hard to believe it is going to be so RAM-constrained that saving a few bytes is going to make that much difference. Unless you return references to the registers themselves, you may well end up using more RAM.

I don't get why saving a variable is such a big deal.

Oh, come on, don't take it so seriously, i don't think saving variables is such a big deal :slight_smile:
I just generally try to make my programms as efficient as possible (i think i'm not very good at that though :)) and i thought if there would be something like digitalRead() except for reading the pwm duty cycle, i could have used that instead of having to save all the values in variables (although, i was already woundering, if assuming that would be possible, it wouldn't take alot more time to read the duty cycles instead of reading them from the variables).

The value was in a variable when you did the analogWrite, so why not use that again?

The problem is, the variables that are used for the analogWrite, are the parameters passed to the function, and they get overwritten each time the function is called... But never mind, i'll just save them to variables, i just wanted to ask, i mean it could have been as easy as digitalRead, who knows...

Thanks for all the replys...

Delphiño

delphino-999:

I don't get why saving a variable is such a big deal.

Oh, come on, don't take it so seriously, i don't think saving variables is such a big deal :slight_smile:
I just generally try to make my programms as efficient as possible (i think i'm not very good at that though :)) and i thought if there would be something like digitalRead() except for reading the pwm duty cycle, i could have used that instead of having to save all the values in variables (although, i was already woundering, if assuming that would be possible, it wouldn't take alot more time to read the duty cycles instead of reading them from the variables).

The value was in a variable when you did the analogWrite, so why not use that again?
The problem is, the variables that are used for the analogWrite, are the parameters passed to the function, and they get overwritten each time the function is called... But never mind, i'll just save them to variables, i just wanted to ask, i mean it could have been as easy as digitalRead, who knows...

Thanks for all the replys...

Delphiño

That makes no sense. The contents of the variable you pass to the analogWrite function do not change due to the fact that you called that function. The function uses the value but does not change it. The contents of the variable remain the same until you yourself change them else where in your sketch. Hence your sketch already knows the current duty cycle being outputted, it was and is the contents of the variable you used in the last call to the analogWrite function. I think you are trying to see a problem that does not exist. Your sketch knows where you last left your car keys, even if you yourself can't recall.
Lefty

You could read the timer register couldn't you? (eg. OCR2A)

But that makes your code pretty processor-dependent. As the others said, you already know what value you have sent to the analogWrite function. Why not just save that byte somewhere?

I just generally try to make my programms as efficient as possible ...

You should also try to make them as readable and maintainable as possible.

Of course the call to analogWrite doesn't change the Variables... Sorry, i think i didn't explain myself very well, i wrote a function that write the RGB Values to 1 of 5 LEDs the function looks like this:

void ledWrite(int led_number, int r_brightness, int g_brightness, int b_brightness) {
  int r_pin = led_pins[(3*led_number)-3];
  int g_pin = led_pins[(3*led_number)-2];
  int b_pin = led_pins[(3*led_number)-1];
  analogWrite(r_pin, map(r_brightness, 0, 255, 255, 0));
  analogWrite(g_pin, map(g_brightness, 0, 255, 255, 0));
  analogWrite(b_pin, map(b_brightness, 0, 255, 255, 0));
}

And now i want to make a new function witch handles the whole fading process, but since i have to keep the code running also while fading, i just call the function every loop, and i thought the function could just have a target color whitch you specifie and then every time it gets called, just read the current pwm value and increment it one step closer to the target color, and i just meant that all the variables used in that function would be overwritten each loop (every time the function is called), but i just remembered, that that doesn't matter because in this function only the target color, led number and stuff gets passed to the function, but not the brightnesses, the idea was something like analogWrite(pin, pwmRead(pin) + 1); where i wouldn't have to use variables, of course the function would first have to decide wicth color get changed and if that fade darker or brighter...

I think you are trying to see a problem that does not exist.

Actually, i'm not seeing a problem at all, or at least, not a real problem, i mean i can stil run the code, no matter if the values get read from somewhere, or saved in variables, i was just curious, and i think we can all agree that in some cases this would be practicle (assuming you don't have to write a bunch of code just to be able to read the value in the first place, of course)...

Delphiño

Looking at the source of "analogWrite", it looks like it would be a little trickier than I had thought to do what you propose.
If the PWM value given is 0 or 255, then the timer registers are not written to at all, but instead a simple "digitalWrite" LOW or HIGH is performed.
Otherwise, retrieving the timer register contents is relatively simple, if a little tedious.

Best just remember the values you wrote. :wink:

AWOL is right. And since you won't know if you wrote 0 or 255, you can't necessarily believe the last value left in the timer register.

To me, the requirements make me think of a design which has a class encapsulating the LED pin assignment and desired fade behaviour that can remember what state the LED was left in and what the desired end state is and knows how to get from one to the other.

@PeterH Yeah, thats what i'm doing :slight_smile:
I just thought i would be easier to be able to read the last value, instead of having to save it every time it changes... But as i already said, it's not a big problem, so i'll just save them to Variables, alltough i don't have much time for programming now anyhow... :slight_smile:

Delphiño