Go Down

Topic: Best approach for changing PWM in certain time? (Read 951 times) previous topic - next topic

Baltasar

Hi, I'm creating a sort of timer for turn/DIM leds.
On this timer I can specify the duration I want that the leds take from 0 to 255 (PWM value), so to speak from off (0%) to full bright (100%).

So whats the best approach to do this and have always a smooth incresed brightness, taking in consideration that the user can setup a diferent duration time from 1 minute to 120 minutes to do the 0 to 100% DIM variation?

Thanks.
Check all my projects based on Atmel/Arduino -> www.aqualed-light.com

PaulS

Quote
Hi, I'm creating a sort of timer for turn/DIM leds.

No, you are using existing timers to make things happen.

Quote
On this timer I can specify the duration I want that the leds take from 0 to 255

Can the time be changed during a cycle? What does that do to the cycle? What is to happen when the LED gets to full brightness?

Are you aware that the human eye can not distinguish 255 different brightness levels?

Quote
So whats the best approach to do this and have always a smooth incresed brightness

What you have is basically a state machine. The state, at any time, defines what the current brightness level is. You need to invoke certain actions (change the PWM level) at each state change, and you need to change states at appropriate times. Since the desire is to have the state change occur at specific intervals, you need to record when the last state change occurred, and compare that to "now" on each pass through loop, to see if it is time to change state.

Recording when the last state change occurred is done using millis(), as is determining the current time.

Look at the blink with delay example.

Under these circumstances is it not appropriate for you to use delay().

Baltasar

#2
Jul 02, 2011, 12:27 pm Last Edit: Jul 02, 2011, 12:28 pm by Baltasar Reason: 1
Hi, thanks for your reply PaulS, when I said timer I meant to say that my machine is as sort of a clock to turn ON/OFF leds, so the user specifies X time and Y duration for the on, the machine at that time starts increasing PWM values from 0 to 255 divided by the Y duration specified, them the leds stay on until reach the time specifyd for OFF and do the oposit, witch is decreasing the PWM from 255 to 0 in another duration specifyed for OFF cycle.

Hope you understand now what I'm doing?

My main problem for now is trying to avoid float vars, since I have this already running with floats.

I take the duration value, convert it to seconds, them divide 255 for those seconds and I get the increment.
Using mils() everytime reach my next changing second I increase the PWM, I think is mor or less like you are saying... but how to take the float vars out so I can save as much memory space as possible?
Check all my projects based on Atmel/Arduino -> www.aqualed-light.com

PaulS

Quote
I take the duration value, convert it to seconds, them divide 255 for those seconds and I get the increment.

Watch your clock for a minute. Tick, tick, tick...

How much time elapses during each tick? Is it 1.0 seconds, or 2.3? or 5.1? The millis() function returns the number of milliseconds that have elapsed since the Arduino was reset, as an unsigned long (i.e. integer) value.

Determining a fractional number of milliseconds to wait is useless, since "now" and "then" are always integer values.

Even if you were able to change the PWM level at other than integral times, the length of time between changes only needs to be calculated when the total interval changes.

Avoiding float calculations that happen many times every pass through loop is a good idea. Avoiding all float calculations is an unnecessary objective.

Though, in this case, float calculations won't be useful anyway.

Baltasar

#4
Jul 02, 2011, 12:55 pm Last Edit: Jul 03, 2011, 03:08 am by Baltasar Reason: 1
Ok I see, let me show the code I have now, so you can comment on that or send me to a better direction...

This are excerpts from the total code as I have lots of other functions than the ON/OFF/DIM for the leds.

Code: [Select]

on_led_increment =  255.0 / (((float)dur_on * 60) );


void loop()
{

 if (on_finished == 0 && sec_on_count == 0){
   sec_on_count = sec_count;
   sec_on_count = sec_count + ldur_on;
 }


if (on_finished == 0 && sec_count == sec_on_count && led_dim < 255) {

   sec_on_count += 1;

   if (led_dim < 255) {
     led_dim += (float)on_led_increment;
     for (led = led_dim - on_led_increment; led <= led_dim; led += 0.10){
       analogWrite(10, led);
     }
   }

   if (led_dim >= 255) {
     on_finished = 1;
     getCloudsSec();
   }
}

void SyncClock() {
 // create a military-time integer from RTC values
 mil_time = (hours * 100) + minutes;
 sec_count = hours * 60;
 sec_count *= 60;
 sec_count += (minutes * 60);
 sec_count += seconds;
}
Check all my projects based on Atmel/Arduino -> www.aqualed-light.com

Go Up