diff --git a/4ButtonKeypad/4ButtonKeypad.ino b/4ButtonKeypad/4ButtonKeypad.ino index 4f8d83d..c00d58e 100644 --- a/4ButtonKeypad/4ButtonKeypad.ino +++ b/4ButtonKeypad/4ButtonKeypad.ino @@ -18,7 +18,7 @@ //# * EasyButton.h //# * HID-Project.h //# Author(s) : Zachery Seibel-Barnes and Anthony Seibel-Barnes -//# Date : 17/09/2022 (Ver 2.1) +//# Date : 23/09/2022 (Ver 2.2) //# Notes : 1) Hardware: Buttons are defined as '1' to '4' from Top (furthest from USB lead) to Bottom (closest to USB lead) //# 2) IMPORTANT: A 'Button Press' action needs to have corresponding a 'Button Release' action (either 'implicidly defined' or as a generic 'release all') //# 2) Testing: To check parameters values (as generated by run code), use 'Serial Monitor' (Ctrl+Shft+M). Examples: @@ -35,11 +35,16 @@ //*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~* //********************************************* -//Includes +////////////////////// +// LIBRARIES // +////////////////////// #include //Used to define a button and debounces it #include "HID-Project.h" //Lets us simulate keyboard presses. -//Pin Definitions. These numbers refer to the physical GPIO pins on the board +////////////////////// +// DEFINITIONS // +////////////////////// +//These PIN numbers refer to the physical GPIO pins on the board. //LEDS #define LED1 3 #define LED2 5 @@ -52,20 +57,30 @@ #define BUTTON3 A1 #define BUTTON4 A0 -const int cintLedOffTime = 10000; //LED 'OFF' time (milliseconds) is how long LED will remain on for after a button was pressed (For reference: 60,000 = 1 minute) -const int cintLedMaxBrightness = 100; //LED Maximum brightness level (0 will be off, and 255 is brightest... like the SUN !!) -const int cintLedDimmerStepTime = 10; //Time interval for LED Dimmer (milliseconds) -const int cintLedDimmerStep = 1; //Step interval for LED Dimmer (1 = slow fade ; 10 = quick fade) -const int cintDebounceTime = 180; //DebounceTime (milliseconds) is used with the 'Delay' function to pause code after a button press. This helps to slow 'extra' commands from - //a Button like 'PASTING repeated data'). Increase the 'time' if wishing to 'hold' an action from happening (or repeating) for longer. - //This is currently only used when 'blnDelayActions' is set to 'true'. If it is 'false', then the delay is effectively 'zero'. - +////////////////////// +// Global Constants // +////////////////////// +const int cintLedOffTime = 10000; //LED 'OFF' time (milliseconds) is how long LED will remain on for after a button was pressed (For reference: 60,000 = 1 minute). This only relevant if 'cblnLEDsToDimCycle = False'. +const int cintLedMaxBrightness = 100; //LED Maximum brightness level (0 will be off, and 255 is brightest... like the SUN !!) +const int cintLedMinBrightness = 1; //LED Minimum brightness level (0 will be off, and 255 is brightest) +const int cintLedDimmerStepTime = 100; //Time interval for LED Dimmer (milliseconds) (Higher=slow fade ; Lower=quick fade). NOTE: 'cintLedDimmerStep' is relative (linked) to this & will also influence how fast/slow actions occur. +const int cintLedDimmerStep = 1; //Step interval for LED Dimmer (1=very smooth fades ; >10=stepped fades). NOTE: 'cintLedDimmerStepTime' is relative (linked) to this and will also influence how fast/slow this action occurs. +const bool cblnLEDsToDimCycle = true; //Used to set when 'LEDs' are required to CYCLE back to Max after the LEDs are Minimised - even when NO Button Activity has occurred. + //When TRUE, it will (forever) cycle LEDS brightness - GRADUALLY cycling UP (using cintLedDimmerStep) from 'Mimimum' (cintLedMinBrightness) to 'Max ' (cintLedMaxBrightness), + //then 'Dimming' back down to the Mimimum. + //Whem FALSE, the LEDs will simply Dim to the Minimum (cintLedMinBrightness) until next button press. +const int cintDebounceTime = 180; //DebounceTime (milliseconds) is used with the 'Delay' function to pause code after a button press. This helps to slow 'extra' commands from + //a Button like 'PASTING repeated data'). Increase the 'time' if wishing to 'hold' an action from happening (or repeating) for longer. + //This is currently only used when 'blnDelayActions' is set to 'true'. If it is 'false', then the delay is effectively 'zero'. +////////////////////// +// Global Variables // +////////////////////// unsigned long ledTickTime = 0; unsigned long lastPressTime = 0; uint8_t ledBrightness = cintLedMaxBrightness; -bool blnLEDsOn = true; //Used to flag when 'LEDs' are ON at any Brightness level (ie. when LEDs are NOT off). Initated to True for initial illumination. -bool blnButtonActivty = false; //Used to flag when a Button action has actually occured. This is used primarily so it can correctly turn off LEDs after the specified activity time (ie. indirectly works with 'cintLedOffTime') - +bool blnLEDsOn = true; //Used to flag when 'LEDs' are ON at any Brightness level (ie. when LEDs are NOT off). Initated to True for initial illumination. +bool blnButtonActivty = false; //Used to flag when a Button action has actually occured. This is used primarily so it can correctly turn off LEDs after the specified activity time (ie. indirectly works with 'cintLedOffTime') +bool blnLEDsAreCyclingUp = false; //Only used when 'cblnLEDsDimCycle' is TRUE - It identifies when LEDs are in the process of 'Cycling UP' (to LEDs Max On) or when False they will 'Cycle Down' first. //Using the EasyButton library we create 4 buttons, with each button being connected to a GPIO pin as defined above, and having a 35ms debounce time. From memory, these do not have internal pullup //resistors, and are not inverted. Hence the two falses. @@ -74,7 +89,12 @@ EasyButton button2(BUTTON2, 35, false, false); EasyButton button3(BUTTON3, 35, false, false); EasyButton button4(BUTTON4, 35, false, false); -//Standard Arduino setup function. Code that only needs to run once goes here +//********************************************* +//*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~* +//* MAIN * +//*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~* +//********************************************* +//Standard Arduino setup function. Code that only needs to 'run once' goes here. void setup() { // Send a clean report to the host. This is important on any Arduino type. @@ -102,10 +122,10 @@ void setup() //********************************************* //*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~* -//* MAIN * +//* MAIN LOOP * //*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~* //********************************************* -//Code that is runs constantly goes here +//Code that is 'runs constantly' goes here. void loop() { //Reset 'Button Activity' flag (when False it sits in a wait-state for someone to press a button) blnButtonActivty=false; @@ -159,7 +179,6 @@ void loop() { blnButtonActivty = ButtonReleaseAction(4,false); } - //--------------------------------------------------------- //--- LED Illumination: Full ON (when Button Activity) --- //--------------------------------------------------------- @@ -176,64 +195,79 @@ void loop() { if(ledBrightness < cintLedMaxBrightness) { ledBrightness = cintLedMaxBrightness; - - analogWrite(LED1, ledBrightness); - analogWrite(LED2, ledBrightness); - analogWrite(LED3, ledBrightness); - analogWrite(LED4, ledBrightness); } - //Set flag indicating that 'LEDs are ON' and reset 'LED ON timer' - blnLEDsOn = true; break; + default: // A 'Button Activty' HAS NOT Occurred. No need to do anything - This will also retain the 'lastPressTime' time value. break; } //--------------------------------------------------------- - //--- LED Illumination: DIM to OFF (Standby) --- + //--- LED Illumination: Minimised or DIMMING CYCLING --- //--------------------------------------------------------- - //If the LEDs are ON at ANY Brightness level (ie. LED NOT Off) .... Check timer since last Button Activity. - switch (blnLEDsOn) + if((millis() - lastPressTime) > cintLedOffTime) { - case true: - //If MAX time has elapsed (for LEDs to be ON), then turn off LEDS - if((millis() - lastPressTime) > cintLedOffTime) - { - lastPressTime = 0; //Reset (no button action) - ledBrightness = 0; //LEDs Off - - analogWrite(LED1, ledBrightness); - analogWrite(LED2, ledBrightness); - analogWrite(LED3, ledBrightness); - analogWrite(LED4, ledBrightness); - - //Set flag 'LEDs are OFF' - blnLEDsOn = false; - } - else if(lastPressTime>0) - { - //Check if certain time has elapsed, then adjust LEDs brightness (Dimmer) - if ((millis() - ledTickTime) > cintLedDimmerStepTime) + //The maximun 'LED on' time has elapsed since the last Button Press (or initial on). Check if 'Dimming Cycling' is set to occur, otherwise simply MINIMISE LEDs. + + switch (cblnLEDsToDimCycle) //Global Constant 'cblnLEDsToDimCycle' determines if 'DIMMING CYCLING' occurs. + { + case true: + //Call LED Dimming function (to Cycle LED Brightness) + ledBrightness = GetLEDsDimCycleValue(ledBrightness); + break; + case false: + //If LEDs are ON (at ANY Brightness level ... LEDS should now be MINIMISED. + if(blnLEDsOn) { - ledTickTime = millis(); - - if(ledBrightness > 0) - { - ledBrightness = ledBrightness-cintLedDimmerStep; - analogWrite(LED1, ledBrightness); - analogWrite(LED2, ledBrightness); - analogWrite(LED3, ledBrightness); - analogWrite(LED4, ledBrightness); - } - } - } - break; - default: - // LEDs are Off.... Do nothing - break; + //MINIMISE LEDs: MAX time has ELAPSED for LEDs to be on Max Brightness. + lastPressTime = 0; //Reset for 'No Button Activity' + ledBrightness = cintLedMinBrightness; //Set LEDs to 'Minimum Brightness' + } + break; + default: + //Should not ever get here, but 'break' out just in case. + break; + } } - + + //--------------------------------------------------------- + //--- WRITE LED Values --- + //--------------------------------------------------------- + if (blnLEDsOn) + { + //Write LED brightness level to the LEDs. + analogWrite(LED1, ledBrightness); + analogWrite(LED2, ledBrightness); + analogWrite(LED3, ledBrightness); + analogWrite(LED4, ledBrightness); + } + + //--------------------------------------------------------- + //--- RESET LED Variables for MAIN LOOP --- + //--------------------------------------------------------- + if(ledBrightness > cintLedMinBrightness) + { + //LED's ON: + if (!blnLEDsOn) + { + blnLEDsOn=true; + } + } + else if(ledBrightness <= cintLedMinBrightness) + { + //LED's at MINIMUM: Minimun LED Brightness has been reached (this is considered as 'LED Off', but they may not be FULLY Off - it depends on the constant cintLedMinBrightness) + if (blnLEDsOn) + { + blnLEDsOn = false; + } + + if (cblnLEDsToDimCycle) + { + //Reset the flag to begin 'LED cycle Up' process (This is only relevant when cblnLEDsToDimCycle = true) + blnLEDsAreCyclingUp = true; + } + } // LOOP MAIN } @@ -249,7 +283,10 @@ void loop() { //* only fail when the 'Button ID is not 1-6'. //* Returns : 'True' if successful, otherwise 'False' where button is undefined. //* Parameters: 'intButtonNumber' - Corresponds to the Arduino Board button ID number. -//* Prereqs : Keyboard Library (HID-Project.h) should be set in MAIN PROGRAM +//* Prereqs : Requires the following Libraries set in the Main (Libraries) Code: +//* *Keyboard Libray - HID-Project.h +//* Requires the following GLOBAL Contants or Variables set in the Main (Initialisation) Code: +//* * Constant 'cintDebounceTime' specifies DELAY before preformaing additional buttion actions. //* Author : A. Seibel-Barnes (from original source by Z. Seibel-Barnes) //* Date : 17/09/2022 (Ver 1.0) //* Notes : 'Keyboard.press' code options (examples for reference) @@ -288,8 +325,9 @@ bool ButtonPressAction(int intButtonNumber) case 4: // DEFINITION: CUSTOM TEXT (Message) //Keyboard.println("Hi"); - //Keyboard.println(); - Keyboard.println("Just confirming that your item is in the mail (and may have already been delivered)... See pics."); + //Keyboard.println; + Keyboard.print("Tracking progress applies on business days as it processes through Postal and Customs facilities."); + //Keyboard.println("Just confirming that your item is in the mail (and may have already been delivered)... See pics."); //Keyboard.println(); //Keyboard.println("Tracking is available via Australia Post: TMP40083004070052454xxxxx"); //Keyboard.println("Tracking progress applies on business days as it processes through Australia Post facilities.."); @@ -325,8 +363,9 @@ bool ButtonPressAction(int intButtonNumber) // No Delay, or maybe repeat action(s) delay(0); break; - } - + } + + //Return the fuctions result return blnButtonActioned; } @@ -344,7 +383,7 @@ bool ButtonPressAction(int intButtonNumber) //* Parameters: 'intButtonNumber' - Corresponds to the Arduino Board 'Button ID' number (1-6) //* 'blnReleaseALLKeys' - When 'true' it simply 'Releases ALL Keys' (and ignores the 'Button ID' since there are no specific Key-release requirements). //* When 'false' it requires that specific Key(s) are implicidly released. -//* Prereqs : Keyboard Library (HID-Project.h) should be set in MAIN PROGRAM +//* Prereqs : Keyboard Library (HID-Project.h) should be set in the Main (Libraries) Code. //* Author : A. Seibel-Barnes (from original source by Z. Seibel-Barnes) //* Date : 17/09/2022 (Ver 1.0) //* Notes : 'Keyboard.release' code options (for use when blnReleaseALLKeys = false) @@ -398,6 +437,73 @@ bool ButtonReleaseAction(int intButtonNumber, bool blnReleaseALLKeys) } break; } - + + //Return the fuctions result return blnButtonActioned; } + +//******************************************************************************************** +//* FUNCTION NAME: 'GetLEDsDimCycleValue' +//******************************************************************************************** +//* Purpose : Determines the LED Brightness 'Dimming Cycle' Value. +//* Code Type : FUCTION CALL: C - Arduino Leonardo (Arduino IDE) +//* Usage : Can be called anytime. Function call example: ledBrightness = GetLEDsDimCycleValue(ledBrightness); +//* Where: * 'GetLEDsDimCycleValue(ledBrightness)' calls the fuction and specifies the CURRENT LED Brigtness Value. +//* * 'ledBrightness=' would receive the RETURN LED Brightness Value. +//* Returns : An integer value to specify the new LED Brightness. +//* Parameters: 'intCurrentLEDBrightnessValue' - Is the current / existing LED Brightness value. +//* Prereqs : Requires the following GLOBAL Contants or Variables set in the Main (Initialisation) Code: +//* * Constant 'cblnLEDsToDimCycle' to be set to TRUE in MAIN PROGRAM (and evaluated as TRUE with an 'If or Switch Statement' in the main code) +//* * Constant 'cintLedDimmerStep' is used to moderate the LED Brightness change (in steps) +//* * Constant 'cintLedMinBrightness' specifies the MINIMUM LED brightness to DIM to. +//* * Variable 'ledTickTime' keeps track of the LED Timer between LED Brightness value changes. +//* Author : A. Seibel-Barnes +//* Date : 23/09/2022 (Ver 1.0) +//* Notes : Live Long and Propser _\// +//'********************************************************************************************** +int GetLEDsDimCycleValue(int intCurrentLEDBrightnessValue) +{ + int intLEDBrightnessValue; //LED brightness level to return to Main Code + + intLEDBrightnessValue = intCurrentLEDBrightnessValue; + + //Begin to 'Cycle LED DIMMING' (Up or DOWN) - even if there has been NO Button Activity. + if(!blnLEDsAreCyclingUp) + { + //CYCLE LEDs DOWN: Adjust LEDs brightness Down. LEDs are not in the process of Cycling up to Max ... So, DIM LEDs brightness (slowly 'Dim step DOWN' to Off) + if ((millis() - ledTickTime) > cintLedDimmerStepTime) + { + ledTickTime = millis(); + + if(intLEDBrightnessValue > cintLedMinBrightness) + { + intLEDBrightnessValue = intLEDBrightnessValue - cintLedDimmerStep; + } + } + } + else if(blnLEDsAreCyclingUp) + { + //CYCLE LEDs UP: Adjust LEDs brightness Up (slowly 'Dim step UP' to Max) + if ((millis() - ledTickTime) > cintLedDimmerStepTime) + { + ledTickTime = millis(); + + if(intLEDBrightnessValue < cintLedMaxBrightness) + { + intLEDBrightnessValue = intLEDBrightnessValue + cintLedDimmerStep; + } + else if(intLEDBrightnessValue >= cintLedMaxBrightness) + { + //Max LED Brightness has been reached (Reset the flag to begin 'LED cycle Down' process) + blnLEDsAreCyclingUp = false; + } + } + } + else if(intLEDBrightnessValue = cintLedMaxBrightness) + { + blnLEDsAreCyclingUp = false; + } + + //Return the fuctions result + return intLEDBrightnessValue; +}