Blinking LED without delay_ms() - function?

Hi,

on several parts of my program i need to get some “timing-functionality”, e.g for blinking led or for some effects with scrolling/repeating text on my lcd. If i do it with the delay_ms()-function, i have the problem, that the program is not able to do any other tasks in between, e.g. responding on user interactions.

therfore my question: how can i use the timer-functionality for these issues? is there a simple sample code for that? i only found some more sophisticated tuts for motor controlling. i just need a small and lightweight solution for a delay without delaying the whole program.

i’m using an Orangutan SVP1284

thank you!

In the Arduino environment you can follow the guidelines of the Arduino blink “without delay” example. If instead you are using the Orangutan library, be aware that it does not provide an elapsed time function like millis() or micros(). You will have to write your own, which is not difficult but it must not conflict with any of the other uses of the timers in the library that you might be using. Timers 0,1 and 2 are used by different functions. I believe Timer3 is available on the 1284.

Hello, Hahi9.

Like Jim mentioned, you will probably want to use the same strategy found in the Blink Without Delay Arduino Example. However, you will not need to create your own function for millis(). The Orangutan has multiple functions that return the time elapsed. You can find those functions in the “Timing and Delays” section of the Pololu AVR Library Command Reference.

If you have problems implementing those functions, you can post your code and I would be happy to take a look at it.

- Jeremy

Hi, Jeremy:
I overlooked those timing functions! When programming Orangutans I’ve always consulted this link: pololu.com/docs/0J20 which doesn’t seem to mention them.
Thanks, Jim

Hi,

finally i was able to create a timed action without the delay-function. i took the example code from the orangutan svp-demo-program:

void start_blinking_red_led()
{
    // Configure Timer 0 to overflow 76 times per second and enable the interrupt.
	TCCR0A = 0;
	TCCR0B = 0x05; // Prescaler 1:1024: (20MHz/1024/256) = 76 Hz
	TIMSK0 = 1<<TOIE0; // Enable the overflow interrupt.
	sei();
}

// This interrupt service routine is called each time Timer 0 overflows.
// It takes care of blinking the LED app
ISR(TIMER0_OVF_vect)
{
	static unsigned char counter = 0;
	counter++;
	if (counter == 1){ red_led(1); }
	if (counter == 35){ red_led(0); }
	if (counter == 70){ counter = 0; }
}

void stop_blinking_red_led()
{
	TIMSK0 = 0; // Disable the Timer 0 interrupts.
	red_led(0); // Turn off the red led.
}

It works fine and i need no while()-loop and no delays.

But now i have another problem: am i right that i can use this timer just once at a time? what can i do if i need e.g. 5 blinking leds, but not inside one synced loop, but on different places inside my program. one example: i have two motors. every motor has a status led. the leds should be able to perform different “blinking-tasks”, depending on motor speed or even some other user interactions. and beside that i need the timing function for a stepper motor and a LCD.
so, as you can see, i need 3 or more timing functions at the same time. is that possible? what about the get_ms() - function? is it possible to call it on different places without influencing each other?

One more question,

what about the get_ms(), which is similar used in the mentioned Blink Without Delay Arduino Example?
In the “Timing and and Delays”- description it is mentioned, that it counts since the first time an OrangutanTime function was called. What does that mean exactly? What do i have to do to start the time function? Can i use it with different timers? Are there some other examples? I only found som code fragments, they only show the function get_ms() itself, but not the whole code so that i can see the whole implementation of the correspomnding timer and, whats important for me, the usage of a timer for more than one task, as mentioned above…

If get_ms() is the first OrangutanTime function you call, it will return 0. Any subsequent calls will return the time elapsed since the first OrangutanTime function was called unless you reset the time with time_reset() (it will then return the time elapsed since the last reset). If you are only interested in how long it has been between the last time you called get_ms(), you should not have to reset the time, as the millisecond counter overflows on an even data boundary. This makes the difference between any two calls of get_ms() produce the correct result even if the millisecond counter overflows (unless it has overflowed multiple times).

You should be able to implement get_ms() to control multiple LEDs. For example, if you were trying to control two LEDs, where one LED blinks every 100ms and the other every 150ms, you could start by calling get_ms() to set the reference time. You could then call get_ms() periodically in your code followed by some if statements. If the time elapsed is divisible by 100ms, you would blink the first LED, and if the time elapsed is divisible by 150ms, you would blink the second LED.

- Jeremy

Ok, thank you for your help. One more question:
Which timer is used for this function? What about parallel usage of a stepper motor? How can i use an other timer in the same program?

Stated quite clearly here: pololu.com/docs/0J18/17

Thank you, but i still do not understand how to call the timing function on e.g. Timer 3. in the description you mentioned it says:
1.) timer2 is used for the timing functions at the svp
2.) this timer also is used for pwm
3.) timer3 is free to use for custom tasks

So it would be a useful thing to use this timer, but how? Its not mentioned there- i only understood that timer 2 is initiated automatically, but how can i switch to timer 3 or change this behaviour, so that timer 3 is used automatcally for the timing functions? Thanks a lot!

It says that the use of Timer2 in the get_ms(), etc. functions is compatible with other uses of Timer2 in the Pololu library.

Why do you think you need to use Timer3? You will need to write code to use Timer3.