├── README.md └── libraries ├── PulseInOne ├── PulseInOne.cpp ├── PulseInOne.h ├── README.md ├── examples │ └── pulseInWithoutDelay │ │ └── pulseInWithoutDelay.ino ├── keywords.txt └── licence.txt └── PulseInZero ├── PulseInZero.cpp ├── PulseInZero.h ├── README.md ├── examples └── pulseInWithoutDelay │ └── pulseInWithoutDelay.ino ├── keywords.txt └── licence.txt /README.md: -------------------------------------------------------------------------------- 1 | arduino-pulseInWithoutDelay 2 | =========================== 3 | 4 | A couple of libraries to emulate Arduino::pulseIn functionality without pausing code execution, using hardware interrupts. 5 | -------------------------------------------------------------------------------- /libraries/PulseInOne/PulseInOne.cpp: -------------------------------------------------------------------------------- 1 | /*Copyright (c) 2013 Mike Almond - @mikedotalmond - https://github.com/mikedotalmond 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE.*/ 20 | 21 | /** 22 | * @author Mike Almond - https://github.com/mikedotalmond 23 | * 24 | * Use a hardware interrupt to emulate the Arduino::pulseIn functionality without pausing code execution while waiting for the pulse 25 | * see http://arduino.cc/en/Reference/Interrupts 26 | * */ 27 | 28 | #include "Arduino.h" 29 | #include "PulseInOne.h" 30 | 31 | // initialise static vars 32 | bool PulseInOne::state = false; 33 | bool PulseInOne::active = false; 34 | 35 | void (*PulseInOne::onComplete)(unsigned long) = NULL; 36 | 37 | 38 | /** 39 | * 40 | * 41 | **/ 42 | void PulseInOne::setup(void (*pulseComplete)(unsigned long)){ 43 | onComplete = pulseComplete; 44 | active = false; 45 | } 46 | 47 | 48 | /** 49 | * @public 50 | * Start listening on the desired interrupt for a pulse 51 | */ 52 | void PulseInOne::begin(){ 53 | state = false; 54 | active = true; 55 | attachInterrupt(1, pinChange, RISING); 56 | } 57 | 58 | 59 | /** 60 | * @public 61 | * There's no timeout with this class: it will listen indefinitely for a change on the interrupt pin. 62 | * Use abandon to stop waiting for a pulse. 63 | */ 64 | void PulseInOne::abandon(){ 65 | if(active){ 66 | state = active = false; 67 | detachInterrupt(1); 68 | } 69 | } 70 | 71 | 72 | /** 73 | * @static 74 | * interrupt handler - called whenever the interrupt pin state changes 75 | */ 76 | void PulseInOne::pinChange(){ 77 | 78 | static unsigned long pulseStart = 0; 79 | 80 | state = !state; 81 | 82 | if(state){ 83 | // interrupt pin has changed, a pulse has started 84 | pulseStart = micros(); // store the current microseconds 85 | attachInterrupt(1, pinChange, FALLING); // now wait for the falling edge 86 | } else { 87 | 88 | // pulse complete, detach the interrupt... 89 | detachInterrupt(1); 90 | 91 | // pin state changed again - pulse ended 92 | unsigned long duration = micros() - pulseStart; // get the pulse length 93 | 94 | active = false; 95 | onComplete(duration); 96 | } 97 | } -------------------------------------------------------------------------------- /libraries/PulseInOne/PulseInOne.h: -------------------------------------------------------------------------------- 1 | /*Copyright (c) 2013 Mike Almond - @mikedotalmond - https://github.com/mikedotalmond 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE.*/ 20 | 21 | /** 22 | * @author Mike Almond - https://github.com/mikedotalmond 23 | * */ 24 | 25 | #ifndef PulseInOne_h 26 | #define PulseInOne_h 27 | 28 | #include "Arduino.h" 29 | 30 | class PulseInOne { 31 | 32 | public: 33 | 34 | static void setup(void (*callback)(unsigned long)); 35 | 36 | static void begin(); 37 | static void abandon(); 38 | 39 | static bool active; 40 | static bool state; 41 | 42 | static void (*onComplete)(unsigned long); 43 | 44 | // interrupt handler 45 | static void pinChange(); 46 | 47 | }; 48 | 49 | 50 | #endif -------------------------------------------------------------------------------- /libraries/PulseInOne/README.md: -------------------------------------------------------------------------------- 1 | Use a hardware interrupt to emulate the Arduino::pulseIn functionality without pausing code execution while waiting for the pulse 2 | See http://arduino.cc/en/Reference/Interrupts 3 | -------------------------------------------------------------------------------- /libraries/PulseInOne/examples/pulseInWithoutDelay/pulseInWithoutDelay.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Mike Almond - @mikedotalmond - https://github.com/mikedotalmond 3 | * 4 | * PulseInZero and PulseInOne provide a non-blocking implementation 5 | * similar to the Arduino pulseIn() function ... 6 | * 7 | * Code execution will pause when reading the duration of a pulse on a pin using pulseIn() 8 | * These libraries each use an interrupt to monitor a pin and measure pulse lengths without 9 | * pausing code execution during the pulse. 10 | * 11 | * PulseInZero uses interrupt 0 (pin 2 on arduino uno) 12 | * PulseInOne uses interrupt 1 (pin 3 on an arduino uno) 13 | * See http://arduino.cc/en/Reference/AttachInterrupt for more on the Arduino hardware interrupts 14 | * 15 | * Connect a button, or anything else that produces didital pulses, 16 | * to the pin for interrupt 1 (pin 3 on an arduino uno). 17 | * 18 | * 19 | * Run the program and check the Serial Monitor while making some pulses. 20 | * The duration of a pulse (in microseconds) is logged when it ends. 21 | * 22 | * The library currently only looks for LOW-->HIGH-->LOW pulses: __|RISING->->->FALLING|__ 23 | */ 24 | 25 | #include 26 | 27 | 28 | void setup() { 29 | 30 | Serial.begin(9600); 31 | 32 | // set up PulseInOne, pass in the callback function to be triggered when a pulse completes. 33 | PulseInOne::setup(pulseInComplete); 34 | 35 | // use PulseInOne::begin() in place of pulseIn(), and pulseInComplete will fire when a pulse completes. 36 | PulseInOne::begin(); 37 | /* Calling PulseInOne::begin() will make it watch for a rising edge on a pin indefinitely - there is no timeout. 38 | * You can stop listening and detach the interrupt by calling PulseInOne::abandon(); 39 | * 40 | * After a pulse is detected and the pulseInComplete callback fires you will need to 41 | * call PulseInOne::begin() again if you want to watch for another pulse. 42 | * (I'm considering a contunious-capture mode that will keep reporting pulse durations without 43 | * having to call begin again each time...) 44 | */ 45 | 46 | } 47 | 48 | 49 | void loop() { 50 | 51 | // do stuff... 52 | } 53 | 54 | 55 | /** 56 | * Pulse complete callback hanlder for PulseInOne 57 | * @param duration - pulse length in microseconds 58 | */ 59 | void pulseInComplete(unsigned long duration){ 60 | // note: if you're detecting a lot of pulses a second it's probably best to remove the serial prints... 61 | // (this function is triggered by an interrupt so the serial buffer can fill up and cause the program to hang) 62 | Serial.print("pulse complete - duration: "); 63 | Serial.print(duration); 64 | Serial.println(" us"); 65 | 66 | PulseInOne::begin(); // Start listening again... 67 | 68 | } 69 | -------------------------------------------------------------------------------- /libraries/PulseInOne/keywords.txt: -------------------------------------------------------------------------------- 1 | ## Syntax Coloring Map For PulseInOne ## 2 | 3 | ## 4 | ## Datatypes (KEYWORD1) 5 | PulseInOne KEYWORD1 6 | 7 | ## 8 | ## Instance Methods and Functions (KEYWORD2) ## 9 | begin KEYWORD2 10 | abandon KEYWORD2 11 | setup KEYWORD2 12 | 13 | ## 14 | ## Const/Defs (LITERAL1) -------------------------------------------------------------------------------- /libraries/PulseInOne/licence.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Mike Almond - @mikedotalmond - https://github.com/mikedotalmond 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /libraries/PulseInZero/PulseInZero.cpp: -------------------------------------------------------------------------------- 1 | /*Copyright (c) 2013 Mike Almond - @mikedotalmond - https://github.com/mikedotalmond 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE.*/ 20 | 21 | /** 22 | * @author Mike Almond - https://github.com/mikedotalmond 23 | * 24 | * Use a hardware interrupt to emulate the Arduino::pulseIn functionality without pausing code execution while waiting for the pulse 25 | * see http://arduino.cc/en/Reference/Interrupts 26 | * */ 27 | 28 | #include "Arduino.h" 29 | #include "PulseInZero.h" 30 | 31 | // initialise static vars 32 | bool PulseInZero::state = false; 33 | bool PulseInZero::active = false; 34 | 35 | void (*PulseInZero::onComplete)(unsigned long) = NULL; 36 | 37 | 38 | /** 39 | * 40 | * 41 | **/ 42 | void PulseInZero::setup(void (*pulseComplete)(unsigned long)){ 43 | onComplete = pulseComplete; 44 | active = false; 45 | } 46 | 47 | 48 | /** 49 | * @public 50 | * Start listening on the desired interrupt for a pulse 51 | */ 52 | void PulseInZero::begin(){ 53 | state = false; 54 | active = true; 55 | attachInterrupt(0, pinChange, RISING); 56 | } 57 | 58 | 59 | /** 60 | * @public 61 | * There's no timeout with this class: it will listen indefinitely for a change on the interrupt pin. 62 | * Use abandon to stop waiting for a pulse. 63 | */ 64 | void PulseInZero::abandon(){ 65 | if(active){ 66 | state = active = false; 67 | detachInterrupt(0); 68 | } 69 | } 70 | 71 | 72 | /** 73 | * @static 74 | * interrupt handler - called whenever the interrupt pin state changes 75 | */ 76 | void PulseInZero::pinChange(){ 77 | 78 | static unsigned long pulseStart = 0; 79 | 80 | state = !state; 81 | 82 | if(state){ 83 | // interrupt pin has changed, a pulse has started 84 | pulseStart = micros(); // store the current microseconds 85 | attachInterrupt(0, pinChange, FALLING); // now wait for the falling edge 86 | } else { 87 | 88 | // pulse complete, detach the interrupt... 89 | detachInterrupt(0); 90 | 91 | // pin state changed again - pulse ended 92 | unsigned long duration = micros() - pulseStart; // get the pulse length 93 | 94 | active = false; 95 | onComplete(duration); 96 | } 97 | } -------------------------------------------------------------------------------- /libraries/PulseInZero/PulseInZero.h: -------------------------------------------------------------------------------- 1 | /*Copyright (c) 2013 Mike Almond - @mikedotalmond - https://github.com/mikedotalmond 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE.*/ 20 | 21 | /** 22 | * @author Mike Almond - https://github.com/mikedotalmond 23 | * */ 24 | 25 | #ifndef PulseInZero_h 26 | #define PulseInZero_h 27 | 28 | #include "Arduino.h" 29 | 30 | class PulseInZero { 31 | 32 | public: 33 | 34 | static void setup(void (*callback)(unsigned long)); 35 | 36 | static void begin(); 37 | static void abandon(); 38 | 39 | static bool active; 40 | static bool state; 41 | 42 | static void (*onComplete)(unsigned long); 43 | 44 | // interrupt handler 45 | static void pinChange(); 46 | 47 | }; 48 | 49 | 50 | #endif -------------------------------------------------------------------------------- /libraries/PulseInZero/README.md: -------------------------------------------------------------------------------- 1 | Use a hardware interrupt to emulate the Arduino::pulseIn functionality without pausing code execution while waiting for the pulse 2 | See http://arduino.cc/en/Reference/Interrupts 3 | -------------------------------------------------------------------------------- /libraries/PulseInZero/examples/pulseInWithoutDelay/pulseInWithoutDelay.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Mike Almond - @mikedotalmond - https://github.com/mikedotalmond 3 | * 4 | * PulseInZero and PulseInOne provide a non-blocking implementation 5 | * similar to the Arduino pulseIn() function ... 6 | * 7 | * Code execution will pause when reading the duration of a pulse on a pin using pulseIn() 8 | * These libraries each use an interrupt to monitor a pin and measure pulse lengths without 9 | * pausing code execution during the pulse. 10 | * 11 | * PulseInZero uses interrupt 0 (pin 2 on arduino uno) 12 | * PulseInOne uses interrupt 1 (pin 3 on an arduino uno) 13 | * See http://arduino.cc/en/Reference/AttachInterrupt for more on the Arduino hardware interrupts 14 | * 15 | * Connect a button, or anything else that produces didital pulses, 16 | * to the pin for interrupt 0 (pin 2 on an arduino uno). 17 | * 18 | * 19 | * Run the program and check the Serial Monitor while making some pulses. 20 | * The duration of a pulse (in microseconds) is logged when it ends. 21 | * 22 | * The library currently only looks for LOW-->HIGH-->LOW pulses: __|RISING->->->FALLING|__ 23 | */ 24 | 25 | #include 26 | 27 | 28 | void setup() { 29 | 30 | Serial.begin(9600); 31 | 32 | // set up PulseInZero, pass in the callback function to be triggered when a pulse completes. 33 | PulseInZero::setup(pulseInComplete); 34 | 35 | // use PulseInZero::begin() in place of pulseIn(), and pulseInComplete will fire when a pulse completes. 36 | PulseInZero::begin(); 37 | /* Calling PulseInZero::begin() will make it watch for a rising edge on a pin indefinitely - there is no timeout. 38 | * You can stop listening and detach the interrupt by calling PulseInZero::abandon(); 39 | * 40 | * After a pulse is detected and the pulseInComplete callback fires you will need to 41 | * call PulseInZero::begin() again if you want to watch for another pulse. 42 | * (I'm considering a contunious-capture mode that will keep reporting pulse durations without 43 | * having to call begin again each time...) 44 | */ 45 | 46 | } 47 | 48 | 49 | void loop() { 50 | 51 | // do stuff... 52 | } 53 | 54 | 55 | /** 56 | * Pulse complete callback hanlder for PulseInZero 57 | * @param duration - pulse length in microseconds 58 | */ 59 | void pulseInComplete(unsigned long duration){ 60 | // note: if you're detecting a lot of pulses a second it's probably best to remove the serial prints... 61 | // (this function is triggered by an interrupt so the serial buffer can fill up and cause the program to hang) 62 | Serial.print("pulse complete - duration: "); 63 | Serial.print(duration); 64 | Serial.println(" us"); 65 | 66 | PulseInZero::begin(); // Start listening again... 67 | 68 | } 69 | -------------------------------------------------------------------------------- /libraries/PulseInZero/keywords.txt: -------------------------------------------------------------------------------- 1 | ## Syntax Coloring Map For PulseInZero ## 2 | 3 | ## 4 | ## Datatypes (KEYWORD1) 5 | PulseInZero KEYWORD1 6 | 7 | ## 8 | ## Instance Methods and Functions (KEYWORD2) ## 9 | begin KEYWORD2 10 | abandon KEYWORD2 11 | setup KEYWORD2 12 | 13 | ## 14 | ## Const/Defs (LITERAL1) -------------------------------------------------------------------------------- /libraries/PulseInZero/licence.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Mike Almond - @mikedotalmond - https://github.com/mikedotalmond 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. --------------------------------------------------------------------------------