From 2e10f36c621d9f2650c1332c2303efea3ccd2b65 Mon Sep 17 00:00:00 2001 From: Leonel Lopes Parente Date: Wed, 7 Apr 2021 01:56:08 +0200 Subject: [PATCH] Add reset() and initialState() methods Version 1.1.0 --- README.md | 34 ++++++----- .../led-activelevel-tester.ino | 16 ++--- examples/led-advanced/led-advanced.ino | 12 ++-- examples/led-basics/led-basics.ino | 4 +- examples/led-state/led-state.ino | 8 +-- keywords.txt | 4 +- library.json | 6 +- library.properties | 6 +- src/EasyLed.cpp | 60 ++++++++++++++----- src/EasyLed.h | 7 ++- 10 files changed, 101 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index d421d86..9ec7f16 100644 --- a/README.md +++ b/README.md @@ -4,24 +4,22 @@ Arduino library for controlling standard LEDs in an easy way. -It provides simple logical methods like `led.on()`, `led.toggle()`, `led.flash()`, `led.isOff()` and more. This library will help to write cleaner code that is easy to read and understand. +EasyLed provides simple logical methods like `led.on()`, `led.toggle()`, `led.flash()`, `led.isOff()` and more. This library will help to write cleaner code that is easy to read and understand. -A LED can be switched On by simply using the statement `led.on()`. -When reading that code it is instantly clear what it does: switch the LED On. -With EasyLed there is no need to use `pinMode()`, `digitalWrite()`, `HIGH` and `LOW` anymore. - -**Active-low and active-high** -LEDs are switched On and Off by programming the state of a GPIO pin. Setting the GPIO pin to a LOW level can turn a LED either On or Off. When the LED is On when the GPIO pin level is LOW it is called active-low. When the LED is On when the pin level is HIGH it is called active-high. Whether a LED is active-low or active-high depends on how the LED is physically connected. Both configurations are used in practice. +A LED can be switched On by simply using the statement **`led.on()`**. When someone reads that statement it is instantly clear what it does: switch the LED On. With EasyLed there is no need to use `pinMode()`, `digitalWrite()`, `HIGH` and `LOW` anymore. Without EasyLed you will have to use a statement like `digitalWrite(LED_PIN, LOW)` to switch a LED On (if active-low). When reading that statement it does not become clear if it will switch the LED On or Off. This makes it more difficult to read and understand the code. You need to remember whether `HIGH` or `LOW` means the LED is On or Off. When both active-low *and* active-high LEDs are used that will make the code even more difficult to read and understand. -LEDs are defined as instance of the `EasyLed` class. Its constructor need two parameters: `pin`, which is the GPIO pin the LED is connected to and `activelevel` which indicates whether the LED is active-low or active-high. Enum value `EasyLed::ActiveLevel::Low` represents active-low and `EasyLed::ActiveLevel::High` represents active-high. +LEDs are defined as instance of the `EasyLed` class. The constructor needs two parameters: `pin`, which is the GPIO pin the LED is connected to and `activeLevel` which indicates whether the LED is active-low or active-high. Enum value `EasyLed::ActiveLevel::Low` represents active-low and `EasyLed::ActiveLevel::High` represents active-high. -For On and Off states similar enum values are used: `EasyLed::State::On` means the LED is On and `EasyLed::State::Off` means it is Off. Enum values are used for state because neither `LOW` nor `HIGH` uniquely determine if a LED is On or Off. +For On and Off states similar enum values are used: `EasyLed::State::On` means the LED is On and `EasyLed::State::Off` means it is Off. Enum values are used for state because neither `LOW` nor `HIGH` uniquely identify if a LED is On or Off. Optionally a third parameter `initialState` can be specified to set the initial state to On (default is Off). The fourth parameter `pinmode` is also optional and sets the pin as output. This should normally not be changed -_(except when there is reason to change it to OUTPUT_OPEN_DRAIN for architectures that support it)_. +_(except when there is reason to change it to OUTPUT_OPEN_DRAIN for architectures that support it)_. + +####Active-low and active-high explained +LEDs are switched On and Off by programming the state of a GPIO pin. Setting the GPIO pin to a LOW level can turn a LED either On or Off. If the LED is On when the GPIO pin level is LOW this is called active-low. If the LED is On when the pin level is HIGH this is called active-high. Whether a LED is active-low or active-high depends on how the LED is physically connected. Both types are used in practice. ### Constructor @@ -51,6 +49,8 @@ void off() // Switch LED off void toggle() // Toggle LED state. +void reset() // Reset LED state to initialState. + void flash( // Flash LED (all parameters are optional) const uint8_t count = 2, // Number of flashes const uint16_t onTimeMs = 160, // on-time duration in milliseconds @@ -68,16 +68,18 @@ EasyLed::State getState() // Returns the current state (On or void setState(EasyLed::State state) // Sets the current state -uint8_t pin() // Returns the GPIO pin number as specified in constructor +uint8_t pin() // Returns GPIO pin number as specified in constructor -EasyLed::ActiveLevel activeLevel() // Returns the active-level as specified in constructor +EasyLed::ActiveLevel activeLevel() // Returns active-level as specified in constructor + +EasyLed::State initialState() // Returns initialState as specified in constructor ``` ### Included examples -- `led-basics.ino` - Shows basic use -- `led-advanced.ino` - Shows more advanced use -- `led-state.ino` - Shows how to save and restore state +- `led-basics.ino` - Demonstrates basic use +- `led-advanced.ino` - Demonstrates more advanced use +- `led-state.ino` - Demonstrates how to save and restore state - `led-activelevel-tester.ino` - Helps determine if LED is active-low or active-high @@ -100,5 +102,7 @@ void loop() led.on(); transmitSensorData(); led.off(); + + ... } ``` diff --git a/examples/led-activelevel-tester/led-activelevel-tester.ino b/examples/led-activelevel-tester/led-activelevel-tester.ino index d9e9e55..e44ff04 100644 --- a/examples/led-activelevel-tester/led-activelevel-tester.ino +++ b/examples/led-activelevel-tester/led-activelevel-tester.ino @@ -34,11 +34,13 @@ void printLedInfo() { Serial.println("\nObtained information:"); Serial.print("LED is currently "); - Serial.println(led.isOn() ? "on" : "off"); + Serial.println(led.isOn() ? "On" : "Off"); Serial.print("Is connected to pin "); Serial.println(led.pin()); - Serial.print("Activelevel is set to active-"); - Serial.println(led.activeLevel() == EasyLed::ActiveLevel::Low ? "low" : "high"); + Serial.print("Activelevel is active-"); + Serial.println(led.activeLevel() == EasyLed::ActiveLevel::High ? "high" : "low"); + Serial.print("Initial state is "); + Serial.println(led.initialState() == EasyLed::State::On ? "On" : "Off"); Serial.println(); } @@ -50,7 +52,7 @@ String getString(EasyLed::ActiveLevel level) String getString(EasyLed::State state) { - return (state == EasyLed::State::On ? String("on") : String("off")); + return (state == EasyLed::State::On ? String("On") : String("Off")); } EasyLed::ActiveLevel getInverse(EasyLed::ActiveLevel level) @@ -68,7 +70,7 @@ void setup() { Serial.begin(115200); Serial.println("\n\nled-activelevel-tester started"); - Serial.println("\nLED should currently be off"); + Serial.println("\nLED should currently be Off"); delay(period); printLedInfo(); delay(period); @@ -89,13 +91,13 @@ void loop() Serial.print(getString(targetState)); Serial.print(" then the LED is active-"); Serial.println(getString(activeLevel)); - Serial.println("The activelevel parameter for the constructor is correct"); + Serial.println("The activeLevel parameter for the constructor is correct"); Serial.print("\nIf the LED is "); Serial.print(getString(getInverse(targetState))); Serial.print(" then the LED is active-"); Serial.println(getString(getInverse(activeLevel))); - Serial.print("The activelevel parameter for the constructor should be changed to active-"); + Serial.print("The activeLevel parameter for the constructor should be changed to active-"); Serial.println(getString(getInverse(activeLevel))); Serial.println(); diff --git a/examples/led-advanced/led-advanced.ino b/examples/led-advanced/led-advanced.ino index 9c24ff8..b93e354 100644 --- a/examples/led-advanced/led-advanced.ino +++ b/examples/led-advanced/led-advanced.ino @@ -31,11 +31,13 @@ void printLedInfo() { Serial.println("\nObtained information:"); Serial.print("LED is currently "); - Serial.println(led.isOn() ? "on" : "off"); + Serial.println(led.isOn() ? "On" : "Off"); Serial.print("Is connected to pin "); Serial.println(led.pin()); - Serial.print("Activelevel is set to active-"); - Serial.println(led.activeLevel() == EasyLed::ActiveLevel::Low ? "low" : "high"); + Serial.print("Activelevel is active-"); + Serial.println(led.activeLevel() == EasyLed::ActiveLevel::High ? "high" : "low"); + Serial.print("Initial state is "); + Serial.println(led.initialState() == EasyLed::State::On ? "On" : "Off"); Serial.println(); } @@ -44,8 +46,8 @@ void setup() { Serial.begin(115200); Serial.println("\n\nled-advanced started"); - Serial.println("\nLED should currently be on"); - Serial.println("If off, change activelevel in the constructor"); + Serial.println("\nLED should currently be On"); + Serial.println("If Off, change activeLevel in the constructor"); delay(period); Serial.println("\nrunning:"); printLedInfo(); diff --git a/examples/led-basics/led-basics.ino b/examples/led-basics/led-basics.ino index 9b24ce8..33c573a 100644 --- a/examples/led-basics/led-basics.ino +++ b/examples/led-basics/led-basics.ino @@ -31,8 +31,8 @@ void setup() { Serial.begin(115200); Serial.println("\n\nled-basics started"); - Serial.println("\nLED should currently be off."); - Serial.println("If on, change activelevel in the constructor."); + Serial.println("\nLED should currently be Off."); + Serial.println("If On, change activeLevel in the constructor."); delay(period); Serial.println("\nrunning:"); } diff --git a/examples/led-state/led-state.ino b/examples/led-state/led-state.ino index 395558b..6079402 100644 --- a/examples/led-state/led-state.ino +++ b/examples/led-state/led-state.ino @@ -31,8 +31,8 @@ void doOtherLedStuff() { Serial.println("\ndoing other led stuff:"); - Serial.println("off"); - led.off(); + Serial.println("reset"); + led.reset(); delay(period); Serial.println("flash 5"); led.flash(5); @@ -43,8 +43,8 @@ void setup() { Serial.begin(115200); Serial.println("\n\nled-state started"); - Serial.println("\nLED should currently be off."); - Serial.println("If on, change activelevel in the constructor."); + Serial.println("\nLED should currently be Off."); + Serial.println("If On, change activeLevel in the constructor."); delay(period); Serial.println("\nrunning:\n"); Serial.println("on"); diff --git a/keywords.txt b/keywords.txt index 3fc8944..0d952ca 100644 --- a/keywords.txt +++ b/keywords.txt @@ -3,12 +3,14 @@ ActiveLevel KEYWORD1 State KEYWORD1 on KEYWORD2 off KEYWORD2 +toggle KEYWORD2 +reset KEYWORD2 flash KEYWORD2 isOff KEYWORD2 isOn KEYWORD2 -toggle KEYWORD2 setState KEYWORD2 getState KEYWORD2 activelevel KEYWORD2 +initialState KEYWORD2 pin KEYWORD2 diff --git a/library.json b/library.json index 945fa29..dc8e8e9 100644 --- a/library.json +++ b/library.json @@ -1,8 +1,8 @@ { "name": "EasyLed", - "version": "1.0.0", - "keywords": ["led", "easy", "control"], - "description": "EasyLed is an Arduino library that makes controlling standard LEDs easy. Use simple logical functions like led.on(), led.toggle(), led.flash(), led.isOff() and more. Helps to write clean code that is easy to read and understand.", + "version": "1.1.0", + "keywords": ["led", "control", "blink", "easy"], + "description": "Arduino library for controlling standard LEDs in an easy way. EasyLed provides simple logical methods like led.on(), led.toggle(), led.flash(), led.isOff() and more. This library will help to write cleaner code that is easy to read and understand.", "authors": { "name": "Leonel Lopes Parente", diff --git a/library.properties b/library.properties index 1173c64..4176bc7 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=EasyLed -version=1.0.0 +version=1.1.0 author=Leonel Lopes Parente maintainer=Leonel Lopes Parente -sentence=EasyLed is an Arduino library that makes controlling standard LEDs easy. Use simple logical functions like led.on(), led.toggle(), led.flash(), led.isOff() and more. -paragraph=Helps to write clean code that is easy to read and understand. +sentence=Arduino library for controlling standard LEDs in an easy way. EasyLed provides simple logical methods like led.on(), led.toggle(), led.flash(), led.isOff() and more. +paragraph=This library will help to write cleaner code that is easy to read and understand. category=Device Control url=https://github.com/lnlp/EasyLed architectures=* diff --git a/src/EasyLed.cpp b/src/EasyLed.cpp index 3332f26..22262be 100644 --- a/src/EasyLed.cpp +++ b/src/EasyLed.cpp @@ -2,10 +2,9 @@ * * File: EasyLed.cpp * - * Description: Arduino library that makes controlling standard LEDs easy. - * Use simple logical functions like led.on(), led.toggle(), - * led.flash(), led.isOff() and more. Helps to write clean code - * that is easy to read and understand. + * Description: Arduino library for controlling standard LEDs in an easy way. + * EasyLed provides simple logical methods like led.on(), + * led.toggle(), led.flash(), led.isOff() and more. * * Author: Leonel Lopes Parente * @@ -26,6 +25,8 @@ #include "EasyLed.h" +// --- Public ----- + EasyLed::EasyLed( const uint8_t pin, // GPIO pin to which the LED is connected. const ActiveLevel activeLevel, // The logic level when the LED is on. @@ -33,13 +34,22 @@ EasyLed::EasyLed( const uint8_t pinmode // Default is OUTPUT, some Arduino cores also ) // support OUTPUT_OPEN_DRAIN which can be { // optionally specified here. + // Note: only a simple check is implemented to prevent + // that INPUT is specified as pinmode. It is not possible to check + // for other possible invalid options because these are hardware dependent + // and will not be defined in all situations. pin_ = pin; activeLevel_ = activeLevel; - // Initialize state_ to inverse of initialState otherwise - // setState(initialState) will not set state. - state_ = (initialState == State::Off ? State::On : State::Off); - pinMode(pin, pinmode); - setState(initialState); + initialState_ = initialState; + if (pinmode == INPUT) // Prevent setting pinmode to INPUT + { + pinMode(pin, OUTPUT); + } + else + { + pinMode(pin, pinmode); + } + forceState(initialState_); } @@ -51,14 +61,10 @@ EasyLed::State EasyLed::getState() const void EasyLed::setState(const State state) { - // Only perform actions when state is different from current state_. + // Only set state if specified state is different from current state_. if (state != state_) { - if (state == State::On) - digitalWrite(pin_, static_cast(activeLevel_)); // LOW or HIGH - else - digitalWrite(pin_, static_cast(activeLevel_) ^ 1); // For On use inverse of value for Off. - state_ = state; + forceState(state); } } @@ -75,6 +81,12 @@ EasyLed::ActiveLevel EasyLed::activeLevel() const } +EasyLed::State EasyLed::initialState() const +{ + return initialState_; +} + + void EasyLed::on() { setState(State::On); @@ -99,6 +111,12 @@ bool EasyLed::isOff() const } +void EasyLed::reset() +{ + setState(initialState_); +} + + void EasyLed::toggle() { setState(state_ == State::On ? State::Off : State::On); @@ -146,6 +164,18 @@ void EasyLed::flash( } +// --- Private ----- + +void EasyLed::forceState(const State state) +{ + if (state == State::On) + digitalWrite(pin_, static_cast(activeLevel_)); // LOW or HIGH + else + digitalWrite(pin_, static_cast(activeLevel_) ^ 1); // For On use inverse of value for Off. + state_ = state; +} + + diff --git a/src/EasyLed.h b/src/EasyLed.h index 0961ed9..655c382 100644 --- a/src/EasyLed.h +++ b/src/EasyLed.h @@ -49,10 +49,12 @@ class EasyLed bool isOff() const; uint8_t pin() const; ActiveLevel activeLevel() const; + State initialState() const; void on(); void off(); void toggle(); + void reset(); void flash( const uint8_t count = 2, const uint16_t onTimeMs = 160, @@ -65,7 +67,10 @@ class EasyLed uint8_t pin_; ActiveLevel activeLevel_; State state_; - EasyLed(); // Disable parameterless public constructor. + State initialState_; + + EasyLed(); // Disable parameterless public constructor. + void forceState(const State state); }; #endif // EASY_LED_H_ \ No newline at end of file