225 lines
6.3 KiB
C++
225 lines
6.3 KiB
C++
#include <LEDStatus.h>
|
|
|
|
// constructor defines which pin the LED is attached to
|
|
LEDStatus::LEDStatus(int8_t ledPin) {
|
|
// if pin negative, reverse and set inverse on pin outputs
|
|
if (ledPin < 0) {
|
|
ledPin = -ledPin;
|
|
_inverse = true;
|
|
} else {
|
|
_inverse = false;
|
|
}
|
|
// set up the pin
|
|
_ledPin = ledPin;
|
|
pinMode(_ledPin, OUTPUT);
|
|
digitalWrite(_ledPin, _pinState(LOW));
|
|
_timer = millis();
|
|
}
|
|
|
|
// change pin at runtime
|
|
void LEDStatus::changePin(int8_t ledPin) {
|
|
bool inverse;
|
|
// if pin negative, reverse and set inverse on pin outputs
|
|
if (ledPin < 0) {
|
|
ledPin = -ledPin;
|
|
inverse = true;
|
|
} else {
|
|
inverse = false;
|
|
}
|
|
|
|
if ((ledPin != _ledPin) || (inverse != _inverse)) {
|
|
// make sure old pin is off
|
|
digitalWrite(_ledPin, _pinState(LOW));
|
|
_ledPin = ledPin;
|
|
_inverse = inverse;
|
|
// and make sure new pin is also off
|
|
pinMode(_ledPin, OUTPUT);
|
|
digitalWrite(_ledPin, _pinState(LOW));
|
|
}
|
|
}
|
|
|
|
|
|
// identify how to flash the LED by mode, continuously until changed
|
|
void LEDStatus::continuous(LEDStatus::LEDMode mode) {
|
|
uint16_t ledOffMs, ledOnMs;
|
|
_modeToTime(mode, ledOffMs, ledOnMs);
|
|
continuous(ledOffMs, ledOnMs);
|
|
}
|
|
|
|
// identify how to flash the LED by on/off times (in ms), continuously until changed
|
|
void LEDStatus::continuous(uint16_t ledOffMs, uint16_t ledOnMs) {
|
|
_continuousOffMs = ledOffMs;
|
|
_continuousOnMs = ledOnMs;
|
|
_continuousCurrentlyOn = false;
|
|
// reset LED to off
|
|
if (_ledPin > 0) {
|
|
digitalWrite(_ledPin, _pinState(LOW));
|
|
}
|
|
// restart timer
|
|
_timer = millis();
|
|
}
|
|
|
|
// identify a one-shot LED action (overrides continuous until done) by mode
|
|
void LEDStatus::oneshot(LEDStatus::LEDMode mode, uint8_t count) {
|
|
uint16_t ledOffMs, ledOnMs;
|
|
_modeToTime(mode, ledOffMs, ledOnMs);
|
|
oneshot(ledOffMs, ledOnMs, count);
|
|
}
|
|
|
|
// identify a one-shot LED action (overrides continuous until done) by times (in ms)
|
|
void LEDStatus::oneshot(uint16_t ledOffMs, uint16_t ledOnMs, uint8_t count) {
|
|
_oneshotOffMs = ledOffMs;
|
|
_oneshotOnMs = ledOnMs;
|
|
_oneshotCountRemaining = count;
|
|
_oneshotCurrentlyOn = false;
|
|
// reset LED to off
|
|
if (_ledPin > 0) {
|
|
digitalWrite(_ledPin, _pinState(LOW));
|
|
}
|
|
// restart timer
|
|
_timer = millis();
|
|
}
|
|
|
|
// call this function in your loop - it will return quickly after calculating if any changes need to
|
|
// be made to the pin to flash the LED
|
|
void LEDStatus::LEDStatus::handle() {
|
|
// is a pin defined?
|
|
if (_ledPin == 0) {
|
|
return;
|
|
}
|
|
|
|
// are we currently running a one-shot?
|
|
if (_oneshotCountRemaining > 0) {
|
|
if (_oneshotCurrentlyOn) {
|
|
if ((_timer + _oneshotOnMs) < millis()) {
|
|
if (_oneshotOffMs > 0) {
|
|
digitalWrite(_ledPin, _pinState(LOW));
|
|
}
|
|
_oneshotCurrentlyOn = false;
|
|
--_oneshotCountRemaining;
|
|
if (_oneshotCountRemaining == 0) {
|
|
_continuousCurrentlyOn = false;
|
|
}
|
|
_timer += _oneshotOnMs;
|
|
}
|
|
} else {
|
|
if ((_timer + _oneshotOffMs) < millis()) {
|
|
if (_oneshotOnMs > 0) {
|
|
digitalWrite(_ledPin, _pinState(HIGH));
|
|
}
|
|
_oneshotCurrentlyOn = true;
|
|
_timer += _oneshotOffMs;
|
|
}
|
|
}
|
|
} else {
|
|
// operate using continuous
|
|
if (_continuousCurrentlyOn) {
|
|
if ((_timer + _continuousOnMs) < millis()) {
|
|
if (_continuousOffMs > 0) {
|
|
digitalWrite(_ledPin, _pinState(LOW));
|
|
}
|
|
_continuousCurrentlyOn = false;
|
|
_timer += _continuousOnMs;
|
|
}
|
|
} else {
|
|
if ((_timer + _continuousOffMs) < millis()) {
|
|
if (_continuousOnMs > 0) {
|
|
digitalWrite(_ledPin, _pinState(HIGH));
|
|
}
|
|
_continuousCurrentlyOn = true;
|
|
_timer += _continuousOffMs;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// helper function to convert an LEDMode enum to a string
|
|
String LEDStatus::LEDModeToString(LEDStatus::LEDMode mode) {
|
|
switch (mode) {
|
|
case LEDStatus::LEDMode::Off:
|
|
return "Off";
|
|
case LEDStatus::LEDMode::SlowToggle:
|
|
return "Slow toggle";
|
|
case LEDStatus::LEDMode::FastToggle:
|
|
return "Fast toggle";
|
|
case LEDStatus::LEDMode::SlowBlip:
|
|
return "Slow blip";
|
|
case LEDStatus::LEDMode::FastBlip:
|
|
return "Fast blip";
|
|
case LEDStatus::LEDMode::Flicker:
|
|
return "Flicker";
|
|
case LEDStatus::LEDMode::On:
|
|
return "On";
|
|
default:
|
|
return "Unknown";
|
|
}
|
|
}
|
|
|
|
// helper function to convert a string to an LEDMode enum (note, mismatch returns LedMode::Unknown)
|
|
LEDStatus::LEDMode LEDStatus::stringToLEDMode(String mode) {
|
|
if (mode == "Off")
|
|
return LEDStatus::LEDMode::Off;
|
|
if (mode == "Slow toggle")
|
|
return LEDStatus::LEDMode::SlowToggle;
|
|
if (mode == "Fast toggle")
|
|
return LEDStatus::LEDMode::FastToggle;
|
|
if (mode == "Slow blip")
|
|
return LEDStatus::LEDMode::SlowBlip;
|
|
if (mode == "Fast blip")
|
|
return LEDStatus::LEDMode::FastBlip;
|
|
if (mode == "Flicker")
|
|
return LEDStatus::LEDMode::Flicker;
|
|
if (mode == "On")
|
|
return LEDStatus::LEDMode::On;
|
|
// unable to match...
|
|
return LEDStatus::LEDMode::Unknown;
|
|
}
|
|
|
|
|
|
// private helper converts mode to on/off times in ms
|
|
void LEDStatus::_modeToTime(LEDStatus::LEDMode mode, uint16_t& ledOffMs, uint16_t& ledOnMs) {
|
|
switch (mode) {
|
|
case LEDMode::Off:
|
|
ledOffMs = 1000;
|
|
ledOnMs = 0;
|
|
break;
|
|
case LEDMode::SlowToggle:
|
|
ledOffMs = 1000;
|
|
ledOnMs = 1000;
|
|
break;
|
|
case LEDMode::FastToggle:
|
|
ledOffMs = 100;
|
|
ledOnMs = 100;
|
|
break;
|
|
case LEDMode::SlowBlip:
|
|
ledOffMs = 1500;
|
|
ledOnMs = 50;
|
|
break;
|
|
case LEDMode::FastBlip:
|
|
ledOffMs = 333;
|
|
ledOnMs = 50;
|
|
break;
|
|
case LEDMode::On:
|
|
ledOffMs = 0;
|
|
ledOnMs = 1000;
|
|
break;
|
|
case LEDMode::Flicker:
|
|
ledOffMs = 50;
|
|
ledOnMs = 30;
|
|
break;
|
|
default:
|
|
Serial.printf_P(PSTR("LEDStatus::_modeToTime: Uknown LED mode %d\n"), mode);
|
|
ledOffMs = 500;
|
|
ledOnMs = 2000;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// private helper to optionally inverse the LED
|
|
uint8_t LEDStatus::_pinState(uint8_t val) {
|
|
if (_inverse) {
|
|
return (val == LOW) ? HIGH : LOW;
|
|
}
|
|
return val;
|
|
}
|
|
|