├── GOTStateMachine.cpp ├── GOTStateMachine.h ├── LICENSE ├── README.md ├── examples └── Flash │ └── Flash.ino ├── keywords.txt └── library.properties /GOTStateMachine.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // GOTStateMachine.cpp 3 | // 4 | // MIT License 5 | // 6 | // Copyright (c) Saturday 1st September 2018, Neville Kripp (Grumpy Old Tech) 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in all 16 | // copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | // SOFTWARE. 25 | 26 | #include "Arduino.h" 27 | #include "GOTStateMachine.h" 28 | 29 | // Instantiate and set to process current state every processTime - specify in mS 30 | GOTStateMachine::GOTStateMachine(unsigned long processTime) { 31 | 32 | executeTime = processTime; 33 | lastStateProcessedTime = 0; 34 | delayStartTime = 0; 35 | alreadyProcessed = false; 36 | } 37 | 38 | // Call last thing in Setup function 39 | void GOTStateMachine::setStartState(FUNC_PTR newState) { 40 | 41 | lastStateProcessedTime = millis(); 42 | changeState(newState); 43 | } 44 | 45 | // Change to new state 46 | void GOTStateMachine::changeState(FUNC_PTR newState) { 47 | 48 | currentState = newState; 49 | alreadyProcessed = false; 50 | changedState = true; 51 | } 52 | 53 | // Process the current state if required 54 | void GOTStateMachine::execute() { 55 | 56 | changedState = false; 57 | unsigned long loopTime = millis(); 58 | 59 | if ((loopTime - lastStateProcessedTime) > executeTime) { // Time to process states 60 | 61 | if (!alreadyProcessed) { 62 | 63 | delayStartTime = loopTime; 64 | } 65 | 66 | currentState(); 67 | 68 | lastStateProcessedTime = loopTime; 69 | if (!changedState) { 70 | alreadyProcessed = true; 71 | } 72 | } 73 | } 74 | 75 | // Check if been in state longer that delayPeriod - specify in mS 76 | bool GOTStateMachine::isFirstTime() { 77 | 78 | if (!alreadyProcessed) { 79 | 80 | return true; 81 | } 82 | return false; 83 | } 84 | 85 | // Check if first time state is processed 86 | bool GOTStateMachine::isDelayComplete(unsigned long delayPeriod) { 87 | 88 | unsigned long loopTime = millis(); 89 | 90 | if ((loopTime - delayStartTime) > delayPeriod) { 91 | 92 | return true; 93 | } 94 | return false; 95 | } 96 | 97 | -------------------------------------------------------------------------------- /GOTStateMachine.h: -------------------------------------------------------------------------------- 1 | // 2 | // GOTStateMachine.h 3 | // 4 | // MIT License 5 | // 6 | // Copyright (c) Saturday 1st September 2018, Neville Kripp (Grumpy Old Tech) 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in all 16 | // copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | // SOFTWARE. 25 | 26 | #ifndef GOTSTATEMACHINE_H 27 | #define GOTSTATEMACHINE_H 28 | 29 | #include "Arduino.h" 30 | 31 | //#define STATE_PROCESSING_FREQUENCY 50 // every xxx milliseconds 32 | 33 | typedef void (*FUNC_PTR)(); // Funtion pointer type 34 | 35 | class GOTStateMachine 36 | { 37 | public: 38 | GOTStateMachine(unsigned long processTime); // Instantiate and set to process current state every processTime - specify in mS 39 | 40 | void setStartState(FUNC_PTR newState); // Call last thing in Setup function 41 | void changeState(FUNC_PTR newState); // Change to new state 42 | void execute(); // Process the current state if required 43 | bool isDelayComplete(unsigned long delayPeriod); // Check if been in state longer that delayPeriod - specify in mS 44 | bool isFirstTime(); // Check if first time state is processed 45 | 46 | private: 47 | void (*currentState)(); 48 | unsigned long executeTime; 49 | unsigned long lastStateProcessedTime; 50 | unsigned long delayStartTime; 51 | bool alreadyProcessed; 52 | bool changedState; 53 | }; 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Grumpy Old Tech 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GOTStateMachine 2 | This library implements a light weight basic State Machine. The states are implemented as State functions in your sketch to keep implementation very flexible. 3 | 4 | ## STATE EXECUTION 5 | State functions will be processed at the time interval specified when the State Machine is instaniated in milliSeconds (mS). It is important to implement the state machine as follows: 6 | 1. Instaniate the state machine with a cycle time in milliseconds (mS). 7 | 2. The setStartState() function should be called as the setup() function ends to initialise the State Machine parameters and enter the starting state. 8 | 3. The execute() function should be called in the loop() function. State functions will only be executed when the set time interval is complete. 9 | 10 | ## STATE FUNCTIONS 11 | State functions should be implemented as follows: 12 | 1. State functions should first implement the required logic for the state. 13 | 2. Following the State logic any required transitions should be implemented. 14 | 3. Where code is required to execute once when entering a new state, the isFirstTime function can be called in the State function. The check will return a boolean true for the first execution of a state. 15 | 16 | ## TRANSITIONS 17 | Where multiple transitions need to be implemented in a State function, the following should be considered: 18 | 1. Consideration should be given to the priority of transitions with the highest priority transition being processed first. 19 | 2. The transition to a new state is completed by calling the changeState function and passing the actual State function name. 20 | 3. Following a changeState a return should be included to end the State function. 21 | 4. Where a transition is related to a period period the state has been active the function isDelayComplete(delayPeriod) can be called. The function will return a boolean true if the delay period is completed. delayPeriod should be specified in milliseconds (mS). 22 | 5. The State Machine will stay in the same state if changeState is not called. 23 | 24 | -------------------------------------------------------------------------------- /examples/Flash/Flash.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LED_PIN 13 4 | 5 | //***** State Machine ***** 6 | GOTStateMachine stateMachine(50); // execute every 50 milliseconds 7 | 8 | // States 9 | void ledOn(); 10 | void ledOff(); 11 | 12 | void setup() { 13 | 14 | pinMode(LED_PIN, OUTPUT); 15 | 16 | stateMachine.setStartState(ledOff); // Initialise state machine 17 | } 18 | 19 | void loop() { 20 | 21 | stateMachine.execute(); // process the states as required 22 | } 23 | 24 | 25 | //***** States ***** 26 | 27 | void ledOff() { 28 | 29 | // State logic 30 | digitalWrite(LED_PIN, LOW); 31 | 32 | // Transitions 33 | if (stateMachine.isDelayComplete(1000)) { 34 | 35 | stateMachine.changeState(ledOn); 36 | return; 37 | } 38 | } 39 | 40 | void ledOn() { 41 | 42 | // State logic 43 | digitalWrite(LED_PIN, HIGH); 44 | 45 | // Transitions 46 | if (stateMachine.isDelayComplete(1000)) { 47 | 48 | stateMachine.changeState(ledOff); 49 | return; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ########################################## 2 | # Syntax Colouring Map For GOTStateMachine 3 | ########################################## 4 | 5 | ########################################## 6 | # Datatypes (KEYWORD1) 7 | ########################################## 8 | 9 | GOTStateMachine KEYWORD1 10 | 11 | ########################################## 12 | # Methods and Functions (KEYWORD2) 13 | ########################################## 14 | 15 | setStartState KEYWORD2 16 | changeState KEYWORD2 17 | execute KEYWORD2 18 | isDelayComplete KEYWORD2 19 | isFirstTime KEYWORD2 20 | 21 | ########################################## 22 | # Constants (LITERAL1) 23 | ########################################## 24 | 25 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=GOTStateMachine 2 | category=Device Control 3 | version=1.0.0 4 | author=Neville Kripp 5 | maintainer=Neville Kripp 6 | sentence="A light weight State Machine for Arduino." 7 | url=https://github.com/Grumpy-Old-Tech/GOTStateMachine 8 | paragraph=A light weight State Machine for Arduino. 9 | architectures=* 10 | includes=GOTStateMachine.h 11 | --------------------------------------------------------------------------------