PDA

View Full Version : Blinking LED function ???



Tom_G_2010
11-27-2012, 02:08 AM
I am starting to write the sketch for my annunciator panel. I would like to have some of the LEDs blink for x seconds and then turn on steady if a given condition is met, or in some cases blink continuously if a given condition is met.

I have the first one or two announciator LEDs doing this by setting the dig output high for x milliseconds and then low for x and back high and so on. All the while this goes on though it is holding up any other code execution. Is there a way to right a sub routine, independent loop, or function that can manage LED blinking without holding up other code execution?

I looked at the Arduino libraries and didn't see anything that looked like it fit the bill so I thought I would ask.

AK Mongo
11-27-2012, 03:35 AM
Ditching your Phidgets, Tom?

Tom_G_2010
11-27-2012, 09:03 AM
Ditching your Phidgets, Tom?

Seriously contemplating it.

Alan's Version 5 program seemed like the greatest thing since sliced bread. When he decided to abandon it and go back to the Version 4 I decided to try that out. It's way more complicated and far less flexible. There are things I was doing in V5 that can't be done in V4. Now I could stick with V5 but the support is minimal and it does have a few bugs which will, of course, never be worked out. Then the final knife in the heart, most likely a pc based issue on my end, the phidgets drivers keep going blind. They see the cards but not the I/O on the cards for some reason until I reboot.

I have not given up completely but at the moment I have an Arduino in hand, tons of online documentation, Jim's great support and Link2FS, and a several knowledgeable users posting here so it's a winning combination. In the end I could end up with both Arduino and Phidgets. I also saw an interesting article online about an FSUIPC to Arduino concept compelete with the C++ code provided but I'm not sure I have the programming chops to even touch that.

Last night I got several basic annunciators coded. I would like to improve the blinking portion so it does not hold up other code execution though. My next learning curve item will be to collect multiple parameters from FSX and store them as variables to compare for tripping logic based warnings like my landing gear warning. For example:If (AGL below 200' or Throttle below 25%) and Gear Up then trip warning lamp.

But, for now, just figuring out a blinking subroutine would be good.

BuildABoeing
11-29-2012, 11:25 AM
You can buy LEDs that blink. (I have installed one on my sons toy-excevator)
So an easy fix could be to install two LEDs (a steady and a blinking) in the same annunciator, and then code a switch between the two giving which condition is met.

Tom_G_2010
11-29-2012, 12:32 PM
You can buy LEDs that blink. (I have installed one on my sons toy-excevator)
So an easy fix could be to install two LEDs (a steady and a blinking) in the same annunciator, and then code a switch between the two giving which condition is met.

Interesting solution and one I had not considered, thanks!

Since posting this question I also came across some good sketchs for blinking LEDs without code delays.

Here's the link to one of them:
Arduino - BlinkWithoutDelay (http://arduino.cc/en/Tutorial/BlinkWithoutDelay)

Here's the code sample from that link:


/* Blink without Delay

Turns on and off a light emitting diode(LED) connected to a digital
pin, without using the delay() function. This means that other code
can run at the same time without being interrupted by the LED code.

The circuit:
* LED attached from pin 13 to ground.
* Note: on most Arduinos, there is already an LED on the board
that's attached to pin 13, so no hardware is needed for this example.


created 2005
by David A. Mellis
modified 8 Feb 2010
by Paul Stoffregen

This example code is in the public domain.


http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
*/

// constants won't change. Used here to
// set pin numbers:
const int ledPin =13;// the number of the LED pin

// Variables will change:
int ledState =LOW;// ledState used to set the LED
long previousMillis =0;// will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval =1000;// interval at which to blink (milliseconds)

voidsetup(){
// set the digital pin as output:
pinMode(ledPin,OUTPUT);
}

voidloop()
{
// here is where you'd put code that needs to be running all the time.

// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsignedlong currentMillis =millis();

if(currentMillis - previousMillis > interval){
// save the last time you blinked the LED
previousMillis = currentMillis;

// if the LED is off turn it on and vice-versa:
if(ledState ==LOW)
ledState =HIGH;
else
ledState =LOW;

// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}


SO off to do more experimentation this weekend...

zulucat
11-29-2012, 01:55 PM
Tom,

I can think of three ways to solve your problem; two involve using interrupts.

1) Use an internal timer/counter to generate a periodic interrupt. The interrupt service routine (ISR) toggles the leds on/off. This approach has a couple of major drawbacks. First, you need to learn how to to program the uP registers that control a timer/counter. Second, you need to go through the Arduino code to find out which timer/counters are already being used -- maybe all of them are used! I'd use this as a last resort

2) Use an external device (like a NE555) to generate an interrupt to the UNO. Again, the ISR would blink the leds. The only drawback to this approach is time critical code. Since the interrupt can pull you out of your normal (foreground) code at any time you need to protect code that, once started, cannot be stopped. You would do this by disabling interrupts at the start of that code and then turning interrupts back on when you are done.

3) Simple software approach. You've already run across this approach using millis(). This has this advantage that it is easy to implement but has the drawback that if processing takes too long blinking can become erratic.

I've included a partial sketches that show how to use millis() to blink the leds 2 times a second. The example uses a switch statement to break processing into smaller steps.



void loop()
{
unsigned long stm, ctm;
int flag, psv;

flag = psv = 0;
stm = millis(); // get start time

while(1) { // loop forever
ctm = millis(); // get current time
if ((ctm-stm) >= 250) {
if (flag) {
// turn leds on
} else {
// turn leds off
}
flag ^= 1; // flip flag
stm = ctm; // reset start time
}

switch(psv)
{
case 0;
// do procrss #1
break;

case 1:
// do procees #2
break

case 2:
// do process #3
break;

default:
psv = 0;
break;
}
psv++;
}
}


Good luck - Doug