Wednesday, July 22, 2009

A trivial LED class

I needed a simple way of turning an LED on for a while and then coming back to it later to turn it off. In my case I wanted to signal to a user that I had done something (in my case written something to an SD card) but didn't want to interrupt everything else while this was going on. This is how I did this:

First, I created an LED class - I pass in the pin the LED is on in the constructor:


class AMLed
{
private:
 uint8_t _ledPin;
 long _turnOffTime;

public:
 AMLed(uint8_t pin);
 void setOn();
 void setOff();

 // Turn the led on for a given amount of time (relies on a call to check() in the main loop())
 void setOnForTime(int millis);
 void check();
};

In this case I added some simple setOn/setOff functions (you'd normally simply call digitalWrite functions for this inline in your code). Here's the code for the implementation, I'll describe it after the code:

AMLed::AMLed(uint8_t ledPin) : _ledPin(ledPin), _turnOffTime(0)
{
 pinMode(_ledPin, OUTPUT);
}

void AMLed::setOn()
{
 digitalWrite(_ledPin, HIGH);
}

void AMLed::setOff()
{
 digitalWrite(_ledPin, LOW);
}

void AMLed::setOnForTime(int p_millis)
{
 _turnOffTime = millis() + p_millis;
 setOn();
}

void AMLed::check()
{
 if (_turnOffTime != 0 && (millis() > _turnOffTime))
 {
                _turnOffTime = 0;
  setOff();
 }
}

So when I call setOnForTime I of course turn on the LED but I also record a time in the future when the LED should be turned off. Then, when the check() method is called I check to see whether the current time is greater than the turn off time and turn it off if necessary. I set _turnOffTime to zero so I don't overly exercise that code. Due to the short-circuit nature of C++ the check against millis() is never executed if _turnOffTime is zero.

Back to the code - this is how it would look in a sketch:


AMLED myLED(3);

void setup()
{
}

void loop()
{
   myLED.check();
   if (someEventHappened)
   {
      myLED.setOnForTime(5000);
   }
   // Some other interesting stuff
}

And that's it!

No comments:

Post a Comment