diff --git a/Doxyfile b/Doxyfile index 8895980..e0caafb 100644 --- a/Doxyfile +++ b/Doxyfile @@ -906,7 +906,7 @@ EXCLUDE_SYMBOLS = # that contain example code fragments that are included (see the \include # command). -EXAMPLE_PATH = +EXAMPLE_PATH = examples/bounce/bounce.ino # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and diff --git a/README.md b/README.md index 712fec1..2295093 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,38 @@ -BOUNCE 2 -===================== +# BOUNCE 2 -Debouncing library for Arduino and Wiring +Debouncing library for Arduino and Wiring by Thomas Ouellet Fredericks with contributions from: Eric Lowry, Jim Schimpf, Tom Harkaway and Joachim Krüger. -by Thomas Ouellet Fredericks - -with contributions from: - -Eric Lowry, Jim Schimpf, Tom Harkaway and Joachim Krüger. +More about debouncing: http://en.wikipedia.org/wiki/Debounce#Contact_bounce -HAVE A QUESTION? -===================== -Please post your questions here : +# HAVE A QUESTION? + +Please post your questions here http://forum.arduino.cc/index.php?topic=266132.0 -DOWNLOAD -===================== +# INSTALLATION & DOWNLOAD -Download the latest version (version 2) here : +Install through your software's Library Manager or download the latest version [here](https://github.com/thomasfredericks/Bounce2/archive/master.zip) and put the "Bounce2" folder in your "libraries" folder. -https://github.com/thomasfredericks/Bounce2/archive/master.zip +The original version of Bounce (Bounce 1) is included in the download but not supported anymore. + +# DOCUMENTATION + +The complet documentation can be found in the "docs" folder or [online here](http://thomasfredericks.github.io/Bounce2/). + +# DEBOUNCE ALGORITHMS -INSTALLATION -===================== -Put the "Bounce2" folder in your Arduino or Wiring "libraries" folder. +## Stable interval + +By default, the Bounce library uses a stable interval to process the debouncing. This is simpler to understand and can cancel unwanted noise. + +![](https://raw.github.com/thomasfredericks/Bounce-Arduino-Wiring/master/extras/BouncySwitch_stable.png) + +## Lock-out interval + +By defining "#define BOUNCE_LOCK_OUT" in "Bounce.h" you can activate the alternative debouncing method. This method is a lot more responsive, but does not cancel noise. + +![](https://raw.github.com/thomasfredericks/Bounce-Arduino-Wiring/master/extras/BouncySwitch_lockout.png) -DOCUMENTATION -===================== - -The latest version (version 2) documentation can be found here : - -https://github.com/thomasfredericks/Bounce2/wiki - - -ABOUT BOUNCE 1 (ORIGINAL VERSION) -===================== - -The original version of Bounce (Bounce 1) is included but not supported anymore. diff --git a/docs/_bounce2_8h_source.html b/docs/_bounce2_8h_source.html index a169181..89bb0ea 100644 --- a/docs/_bounce2_8h_source.html +++ b/docs/_bounce2_8h_source.html @@ -66,15 +66,18 @@ $(function() {
Bounce2.h
-
1 /*
2  The MIT License (MIT)
3 
4  Copyright (c) 2013 thomasfredericks
5 
6  Permission is hereby granted, free of charge, to any person obtaining a copy of
7  this software and associated documentation files (the "Software"), to deal in
8  the Software without restriction, including without limitation the rights to
9  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10  the Software, and to permit persons to whom the Software is furnished to do so,
11  subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in all
14  copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23 
24 /* * * * * * * * * * * * * * * * * * * * * * * * * * * *
25  Main code by Thomas O Fredericks (tof@t-o-f.info)
26  Previous contributions by Eric Lowry, Jim Schimpf and Tom Harkaway
27  * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
28 
29 #ifndef Bounce2_h
30 #define Bounce2_h
31 
32 #if defined(ARDUINO) && ARDUINO >= 100
33 #include "Arduino.h"
34 #else
35 #include "WProgram.h"
36 #endif
37 
38 // Uncomment the following line for "LOCK-OUT" debounce method
39 //#define BOUNCE_LOCK_OUT
40 
41 // Uncomment the following line for "BOUNCE_WITH_PROMPT_DETECTION" debounce method
42 //#define BOUNCE_WITH_PROMPT_DETECTION
43 
44 #include <inttypes.h>
45 
46 
50 class Bounce
51 {
52  public:
56  Bounce();
57 
61  void attach(int pin, int mode);
62 
66  void attach(int pin);
67 
68 
72  void interval(uint16_t interval_millis);
73 
77  bool update();
78 
82  bool read();
83 
87  bool fell();
88 
92  bool rose();
93 
94  // Partial compatibility for programs written with Bounce version 1
95  bool risingEdge() { return rose(); }
96  bool fallingEdge() { return fell(); }
97  Bounce(uint8_t pin, unsigned long interval_millis ) : Bounce() {
98  attach(pin);
99  interval(interval_millis);
100  }
101 
105  unsigned long duration();
106 
107 
108  // WIP HELD : unsigned long held(); // Returns the duration the previous state was held
109 
110  protected:
111  unsigned long previous_millis;
112  uint16_t interval_millis;
113  uint8_t state;
114  uint8_t pin;
115  unsigned long stateChangeLastTime;
116  // WIP HELD : unsigned long durationOfPreviousState;
117  virtual bool readCurrentState() { return digitalRead(pin); }
118  virtual void setPinMode(int pin, int mode) {
119 #if defined(ARDUINO_STM_NUCLEO_F103RB) || defined(ARDUINO_GENERIC_STM32F103C)
120  pinMode(pin, (WiringPinMode)mode);
121 #else
122  pinMode(pin, mode);
123 #endif
124  }
125 
126  private:
127  inline void changeState();
128  inline void setStateFlag(const uint8_t flag) {state |= flag;}
129  inline void unsetStateFlag(const uint8_t flag) {state &= ~flag;}
130  inline void toggleStateFlag(const uint8_t flag) {state ^= flag;}
131  inline bool getStateFlag(const uint8_t flag) {return((state & flag) != 0);}
132 };
133 
134 #endif
Definition: Bounce2.h:50
-
bool read()
Definition: Bounce2.cpp:127
-
void interval(uint16_t interval_millis)
Definition: Bounce2.cpp:36
-
void attach(int pin, int mode)
Definition: Bounce2.cpp:31
-
bool fell()
Definition: Bounce2.cpp:137
-
bool update()
Definition: Bounce2.cpp:41
-
unsigned long duration()
Definition: Bounce2.cpp:116
-
Bounce()
Definition: Bounce2.cpp:11
-
bool rose()
Definition: Bounce2.cpp:132
+
1 /*
2  The MIT License (MIT)
3 
4  Copyright (c) 2013 thomasfredericks
5 
6  Permission is hereby granted, free of charge, to any person obtaining a copy of
7  this software and associated documentation files (the "Software"), to deal in
8  the Software without restriction, including without limitation the rights to
9  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10  the Software, and to permit persons to whom the Software is furnished to do so,
11  subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in all
14  copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23 
24 /* * * * * * * * * * * * * * * * * * * * * * * * * * * *
25  Main code by Thomas O Fredericks (tof@t-o-f.info)
26  Previous contributions by Eric Lowry, Jim Schimpf and Tom Harkaway
27  * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
28 
29 #ifndef Bounce2_h
30 #define Bounce2_h
31 
32 #if defined(ARDUINO) && ARDUINO >= 100
33 #include "Arduino.h"
34 #else
35 #include "WProgram.h"
36 #endif
37 
38 // Uncomment the following line for "LOCK-OUT" debounce method
39 //#define BOUNCE_LOCK_OUT
40 
41 // Uncomment the following line for "BOUNCE_WITH_PROMPT_DETECTION" debounce method
42 //#define BOUNCE_WITH_PROMPT_DETECTION
43 
44 #include <inttypes.h>
45 
55 class Bounce
56 {
57  public:
58 
69  Bounce();
70 
71 
81  void attach(int pin, int mode);
82 
86  void attach(int pin);
87 
88 
96  void interval(uint16_t interval_millis);
97 
98 
107  bool update();
108 
114  bool read();
115 
119  bool fell();
120 
124  bool rose();
125 
126 
130  bool risingEdge() { return rose(); }
134  bool fallingEdge() { return fell(); }
138  Bounce(uint8_t pin, unsigned long interval_millis ) : Bounce() {
139  attach(pin);
140  interval(interval_millis);
141  }
142 
151  unsigned long duration();
152 
153 
154  // WIP HELD : unsigned long held(); // Returns the duration the previous state was held
155 
156  protected:
157  unsigned long previous_millis;
158  uint16_t interval_millis;
159  uint8_t state;
160  uint8_t pin;
161  unsigned long stateChangeLastTime;
162  // WIP HELD : unsigned long durationOfPreviousState;
163  virtual bool readCurrentState() { return digitalRead(pin); }
164  virtual void setPinMode(int pin, int mode) {
165 #if defined(ARDUINO_STM_NUCLEO_F103RB) || defined(ARDUINO_GENERIC_STM32F103C)
166  pinMode(pin, (WiringPinMode)mode);
167 #else
168  pinMode(pin, mode);
169 #endif
170  }
171 
172  private:
173  inline void changeState();
174  inline void setStateFlag(const uint8_t flag) {state |= flag;}
175  inline void unsetStateFlag(const uint8_t flag) {state &= ~flag;}
176  inline void toggleStateFlag(const uint8_t flag) {state ^= flag;}
177  inline bool getStateFlag(const uint8_t flag) {return((state & flag) != 0);}
178 };
179 
180 #endif
Definition: Bounce2.h:55
+
bool read()
Returns the pin&#39;s state (HIGH or LOW).
Definition: Bounce2.cpp:127
+
void interval(uint16_t interval_millis)
Sets the debounce interval in milliseconds.
Definition: Bounce2.cpp:36
+
bool fallingEdge()
Deprecated (i.e. do not use). Included for partial compatibility for programs written with Bounce ver...
Definition: Bounce2.h:134
+
void attach(int pin, int mode)
Attach to a pin and sets that pin&#39;s mode (INPUT, INPUT_PULLUP or OUTPUT).
Definition: Bounce2.cpp:31
+
bool fell()
Returns true if pin signal transitions from high to low.
Definition: Bounce2.cpp:137
+
bool update()
Updates the pin&#39;s state.
Definition: Bounce2.cpp:41
+
bool risingEdge()
Deprecated (i.e. do not use). Included for partial compatibility for programs written with Bounce ver...
Definition: Bounce2.h:130
+
unsigned long duration()
Returns the duration in milliseconds of the current state.
Definition: Bounce2.cpp:116
+
Bounce(uint8_t pin, unsigned long interval_millis)
Deprecated (i.e. do not use). Included for partial compatibility for programs written with Bounce ver...
Definition: Bounce2.h:138
+
Bounce()
Create an instance of the Bounce class.
Definition: Bounce2.cpp:11
+
bool rose()
Returns true if pin signal transitions from low to high.
Definition: Bounce2.cpp:132
-

Create an instance of the Bounce class.

+

Create an instance of the Bounce class.

+
// Create an instance of the Bounce class.
Bounce() button;

Member Function Documentation

@@ -174,7 +188,16 @@ unsigned long stateChangeL
-

Attach to a pin and sets that pin's mode (INPUT/INPUT_PULLUP/OUTPUT)

+ +

Attach to a pin and sets that pin's mode (INPUT, INPUT_PULLUP or OUTPUT).

+
Parameters
+ + + +
pinThe pin that is to be debounced.
modeA valid Arduino pin mode (INPUT, INPUT_PULLUP or OUTPUT).
+
+
+
Returns
True if the event read was successful, otherwise false.
@@ -193,7 +216,7 @@ unsigned long stateChangeL
-

Attach to a pin for advanced users. Only attach the pin this way once you have previously set it up. Otherwise use attach(int pin, int mode).

+

Attach to a pin for advanced users. Only attach the pin this way once you have previously set it up. Otherwise use attach(int pin, int mode).

@@ -211,25 +234,10 @@ unsigned long stateChangeL
-

Returns the duration in milliseconds of the current state. Is reset to 0 once the pin rises or falls.

-
- - -

◆ fell()

- -
-
- - - - - - - -
bool Bounce::fell ()
-
-

Returns true if pin signal transitions from high to low.

+

Returns the duration in milliseconds of the current state.

+

Is reset to 0 once the pin rises ( rose() ) or falls ( fell() ).

+
Returns
The duration in milliseconds (unsigned long) of the current state.
@@ -248,7 +256,14 @@ unsigned long stateChangeL
+

Sets the debounce interval in milliseconds.

+
Parameters
+ + +
interval_millisThe interval time in milliseconds.
+
+
@@ -266,25 +281,9 @@ unsigned long stateChangeL
+

Returns the pin's state (HIGH or LOW).

- -
- - -

◆ rose()

- -
-
- - - - - - - -
bool Bounce::rose ()
-
-

Returns true if pin signal transitions from low to high.

+
Returns
HIGH or LOW.
@@ -302,7 +301,10 @@ unsigned long stateChangeL
-

Updates the pin's state. Returns 1 if the state changed. Returns 0 if the state did not change. Because Bounce does not use interrupts, you have to "update" the object before reading its value and it has to be done as often as possible (that means to include it in your loop()). Only call update() once per loop().

+ +

Updates the pin's state.

+

Because Bounce does not use interrupts, you have to "update" the object before reading its value and it has to be done as often as possible (that means to include it in your loop()). Only call update() once per loop().

+
Returns
True if the pin changed state.
diff --git a/docs/class_bounce.js b/docs/class_bounce.js new file mode 100644 index 0000000..6ac219c --- /dev/null +++ b/docs/class_bounce.js @@ -0,0 +1,22 @@ +var class_bounce = +[ + [ "Bounce", "class_bounce.html#aa62a2e2b5ad0ee6913a95f2f2a0e7606", null ], + [ "Bounce", "class_bounce.html#ab34517094faf21d4f38b36da2915132b", null ], + [ "attach", "class_bounce.html#aba08e592941465d033e3eba3dde66eaf", null ], + [ "attach", "class_bounce.html#a163477dbcbaf1a3dee6cb3b62eedf09e", null ], + [ "duration", "class_bounce.html#a62412d814d36102ab3d285e801d5d29a", null ], + [ "fallingEdge", "class_bounce.html#ac756559419bfa1c5060e5e4a4ad6406f", null ], + [ "fell", "class_bounce.html#abfbb0910f5b1ec4e25315cff26dd6289", null ], + [ "interval", "class_bounce.html#a2c6e68bf749497c597a9437b488b3d7c", null ], + [ "read", "class_bounce.html#ae1936fdf44501992707e6cbaee9bbc76", null ], + [ "readCurrentState", "class_bounce.html#ad6efc6dd65035de20f015cc44be37873", null ], + [ "risingEdge", "class_bounce.html#a3417beb80eb6593d768c2e9884c57aa0", null ], + [ "rose", "class_bounce.html#a9e4187934576e568cdfa8f94efeff6f2", null ], + [ "setPinMode", "class_bounce.html#a231a992bf2a1f4521043068e35eb50a6", null ], + [ "update", "class_bounce.html#ab36d7b83bf32e0935a0c2c6a05096441", null ], + [ "interval_millis", "class_bounce.html#a8c1991db9415ccc5acf9b24779b332c7", null ], + [ "pin", "class_bounce.html#a1cb79cb0ba2379cd12cc7c098d97053a", null ], + [ "previous_millis", "class_bounce.html#a223ab27b8094acd12d77a3a9145f56c9", null ], + [ "state", "class_bounce.html#af013db8b02e1e252eb60dd5b40d5480b", null ], + [ "stateChangeLastTime", "class_bounce.html#ad5aa630c50e7b783bac50aad0385262e", null ] +]; \ No newline at end of file diff --git a/docs/deprecated.html b/docs/deprecated.html new file mode 100644 index 0000000..88da2ac --- /dev/null +++ b/docs/deprecated.html @@ -0,0 +1,81 @@ + + + + + + + +Bounce2: Deprecated List + + + + + + + + + +
+
+ + + + + + +
+
Bounce2 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
Deprecated List
+
+
+
+
Member Bounce::__attribute__ ((__deprecated__)) bool risingEdge()
+
Partial compatibility for programs written with Bounce version 1
+
Member Bounce::__attribute__ ((__deprecated__)) Bounce(uint8_t pin
+
Partial compatibility for programs written with Bounce version 1
+
Member Bounce::__attribute__ ((__deprecated__)) bool fallingEdge()
+
Partial compatibility for programs written with Bounce version 1
+
+
+ + + + diff --git a/docs/dir_68267d1309a1af8e8297ef4c3efbcdba.js b/docs/dir_68267d1309a1af8e8297ef4c3efbcdba.js new file mode 100644 index 0000000..26e47e2 --- /dev/null +++ b/docs/dir_68267d1309a1af8e8297ef4c3efbcdba.js @@ -0,0 +1,4 @@ +var dir_68267d1309a1af8e8297ef4c3efbcdba = +[ + [ "Bounce2.h", "_bounce2_8h_source.html", null ] +]; \ No newline at end of file diff --git a/docs/examples.html b/docs/examples.html new file mode 100644 index 0000000..92294f5 --- /dev/null +++ b/docs/examples.html @@ -0,0 +1,77 @@ + + + + + + + +Bounce2: Examples + + + + + + + + + +
+
+ + + + + + +
+
Bounce2 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Examples
+
+
+
Here is a list of all examples:
+
+ + + + diff --git a/docs/files.js b/docs/files.js new file mode 100644 index 0000000..04b0a8e --- /dev/null +++ b/docs/files.js @@ -0,0 +1,4 @@ +var files = +[ + [ "src", "dir_68267d1309a1af8e8297ef4c3efbcdba.html", "dir_68267d1309a1af8e8297ef4c3efbcdba" ] +]; \ No newline at end of file diff --git a/docs/functions.html b/docs/functions.html index 9c841e9..9e9dc30 100644 --- a/docs/functions.html +++ b/docs/functions.html @@ -68,6 +68,9 @@ $(function() {
  • duration() : Bounce
  • +
  • fallingEdge() +: Bounce +
  • fell() : Bounce
  • @@ -77,6 +80,9 @@ $(function() {
  • read() : Bounce
  • +
  • risingEdge() +: Bounce +
  • rose() : Bounce
  • diff --git a/docs/functions_func.html b/docs/functions_func.html index 9825ba6..5014d1f 100644 --- a/docs/functions_func.html +++ b/docs/functions_func.html @@ -68,6 +68,9 @@ $(function() {
  • duration() : Bounce
  • +
  • fallingEdge() +: Bounce +
  • fell() : Bounce
  • @@ -77,6 +80,9 @@ $(function() {
  • read() : Bounce
  • +
  • risingEdge() +: Bounce +
  • rose() : Bounce
  • diff --git a/docs/menudata.js b/docs/menudata.js index 275d790..5e01a33 100644 --- a/docs/menudata.js +++ b/docs/menudata.js @@ -7,4 +7,5 @@ var menudata={children:[ {text:"All",url:"functions.html"}, {text:"Functions",url:"functions_func.html"}]}]}, {text:"Files",url:"files.html",children:[ -{text:"File List",url:"files.html"}]}]} +{text:"File List",url:"files.html"}]}, +{text:"Examples",url:"examples.html"}]} diff --git a/docs/navtree.css b/docs/navtree.css new file mode 100644 index 0000000..0cc7e77 --- /dev/null +++ b/docs/navtree.css @@ -0,0 +1,146 @@ +#nav-tree .children_ul { + margin:0; + padding:4px; +} + +#nav-tree ul { + list-style:none outside none; + margin:0px; + padding:0px; +} + +#nav-tree li { + white-space:nowrap; + margin:0px; + padding:0px; +} + +#nav-tree .plus { + margin:0px; +} + +#nav-tree .selected { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} + +#nav-tree img { + margin:0px; + padding:0px; + border:0px; + vertical-align: middle; +} + +#nav-tree a { + text-decoration:none; + padding:0px; + margin:0px; + outline:none; +} + +#nav-tree .label { + margin:0px; + padding:0px; + font: 12px 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +} + +#nav-tree .label a { + padding:2px; +} + +#nav-tree .selected a { + text-decoration:none; + color:#fff; +} + +#nav-tree .children_ul { + margin:0px; + padding:0px; +} + +#nav-tree .item { + margin:0px; + padding:0px; +} + +#nav-tree { + padding: 0px 0px; + background-color: #FAFAFF; + font-size:14px; + overflow:auto; +} + +#doc-content { + overflow:auto; + display:block; + padding:0px; + margin:0px; + -webkit-overflow-scrolling : touch; /* iOS 5+ */ +} + +#side-nav { + padding:0 6px 0 0; + margin: 0px; + display:block; + position: absolute; + left: 0px; + width: 250px; +} + +.ui-resizable .ui-resizable-handle { + display:block; +} + +.ui-resizable-e { + background-image:url("splitbar.png"); + background-size:100%; + background-repeat:no-repeat; + background-attachment: scroll; + cursor:ew-resize; + height:100%; + right:0; + top:0; + width:6px; +} + +.ui-resizable-handle { + display:none; + font-size:0.1px; + position:absolute; + z-index:1; +} + +#nav-tree-contents { + margin: 6px 0px 0px 0px; +} + +#nav-tree { + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + -webkit-overflow-scrolling : touch; /* iOS 5+ */ +} + +#nav-sync { + position:absolute; + top:5px; + right:24px; + z-index:0; +} + +#nav-sync img { + opacity:0.3; +} + +#nav-sync img:hover { + opacity:0.9; +} + +@media print +{ + #nav-tree { display: none; } + div.ui-resizable-handle { display: none; position: relative; } +} + diff --git a/docs/navtree.js b/docs/navtree.js new file mode 100644 index 0000000..e6d31b0 --- /dev/null +++ b/docs/navtree.js @@ -0,0 +1,517 @@ +var navTreeSubIndices = new Array(); +var arrowDown = '▼'; +var arrowRight = '►'; + +function getData(varName) +{ + var i = varName.lastIndexOf('/'); + var n = i>=0 ? varName.substring(i+1) : varName; + return eval(n.replace(/\-/g,'_')); +} + +function stripPath(uri) +{ + return uri.substring(uri.lastIndexOf('/')+1); +} + +function stripPath2(uri) +{ + var i = uri.lastIndexOf('/'); + var s = uri.substring(i+1); + var m = uri.substring(0,i+1).match(/\/d\w\/d\w\w\/$/); + return m ? uri.substring(i-6) : s; +} + +function hashValue() +{ + return $(location).attr('hash').substring(1).replace(/[^\w\-]/g,''); +} + +function hashUrl() +{ + return '#'+hashValue(); +} + +function pathName() +{ + return $(location).attr('pathname').replace(/[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]/g, ''); +} + +function localStorageSupported() +{ + try { + return 'localStorage' in window && window['localStorage'] !== null && window.localStorage.getItem; + } + catch(e) { + return false; + } +} + + +function storeLink(link) +{ + if (!$("#nav-sync").hasClass('sync') && localStorageSupported()) { + window.localStorage.setItem('navpath',link); + } +} + +function deleteLink() +{ + if (localStorageSupported()) { + window.localStorage.setItem('navpath',''); + } +} + +function cachedLink() +{ + if (localStorageSupported()) { + return window.localStorage.getItem('navpath'); + } else { + return ''; + } +} + +function getScript(scriptName,func,show) +{ + var head = document.getElementsByTagName("head")[0]; + var script = document.createElement('script'); + script.id = scriptName; + script.type = 'text/javascript'; + script.onload = func; + script.src = scriptName+'.js'; + if ($.browser.msie && $.browser.version<=8) { + // script.onload does not work with older versions of IE + script.onreadystatechange = function() { + if (script.readyState=='complete' || script.readyState=='loaded') { + func(); if (show) showRoot(); + } + } + } + head.appendChild(script); +} + +function createIndent(o,domNode,node,level) +{ + var level=-1; + var n = node; + while (n.parentNode) { level++; n=n.parentNode; } + if (node.childrenData) { + var imgNode = document.createElement("span"); + imgNode.className = 'arrow'; + imgNode.style.paddingLeft=(16*level).toString()+'px'; + imgNode.innerHTML=arrowRight; + node.plus_img = imgNode; + node.expandToggle = document.createElement("a"); + node.expandToggle.href = "javascript:void(0)"; + node.expandToggle.onclick = function() { + if (node.expanded) { + $(node.getChildrenUL()).slideUp("fast"); + node.plus_img.innerHTML=arrowRight; + node.expanded = false; + } else { + expandNode(o, node, false, false); + } + } + node.expandToggle.appendChild(imgNode); + domNode.appendChild(node.expandToggle); + } else { + var span = document.createElement("span"); + span.className = 'arrow'; + span.style.width = 16*(level+1)+'px'; + span.innerHTML = ' '; + domNode.appendChild(span); + } +} + +var animationInProgress = false; + +function gotoAnchor(anchor,aname,updateLocation) +{ + var pos, docContent = $('#doc-content'); + var ancParent = $(anchor.parent()); + if (ancParent.hasClass('memItemLeft') || + ancParent.hasClass('fieldname') || + ancParent.hasClass('fieldtype') || + ancParent.is(':header')) + { + pos = ancParent.position().top; + } else if (anchor.position()) { + pos = anchor.position().top; + } + if (pos) { + var dist = Math.abs(Math.min( + pos-docContent.offset().top, + docContent[0].scrollHeight- + docContent.height()-docContent.scrollTop())); + animationInProgress=true; + docContent.animate({ + scrollTop: pos + docContent.scrollTop() - docContent.offset().top + },Math.max(50,Math.min(500,dist)),function(){ + if (updateLocation) window.location.href=aname; + animationInProgress=false; + }); + } +} + +function newNode(o, po, text, link, childrenData, lastNode) +{ + var node = new Object(); + node.children = Array(); + node.childrenData = childrenData; + node.depth = po.depth + 1; + node.relpath = po.relpath; + node.isLast = lastNode; + + node.li = document.createElement("li"); + po.getChildrenUL().appendChild(node.li); + node.parentNode = po; + + node.itemDiv = document.createElement("div"); + node.itemDiv.className = "item"; + + node.labelSpan = document.createElement("span"); + node.labelSpan.className = "label"; + + createIndent(o,node.itemDiv,node,0); + node.itemDiv.appendChild(node.labelSpan); + node.li.appendChild(node.itemDiv); + + var a = document.createElement("a"); + node.labelSpan.appendChild(a); + node.label = document.createTextNode(text); + node.expanded = false; + a.appendChild(node.label); + if (link) { + var url; + if (link.substring(0,1)=='^') { + url = link.substring(1); + link = url; + } else { + url = node.relpath+link; + } + a.className = stripPath(link.replace('#',':')); + if (link.indexOf('#')!=-1) { + var aname = '#'+link.split('#')[1]; + var srcPage = stripPath(pathName()); + var targetPage = stripPath(link.split('#')[0]); + a.href = srcPage!=targetPage ? url : "javascript:void(0)"; + a.onclick = function(){ + storeLink(link); + if (!$(a).parent().parent().hasClass('selected')) + { + $('.item').removeClass('selected'); + $('.item').removeAttr('id'); + $(a).parent().parent().addClass('selected'); + $(a).parent().parent().attr('id','selected'); + } + var anchor = $(aname); + gotoAnchor(anchor,aname,true); + }; + } else { + a.href = url; + a.onclick = function() { storeLink(link); } + } + } else { + if (childrenData != null) + { + a.className = "nolink"; + a.href = "javascript:void(0)"; + a.onclick = node.expandToggle.onclick; + } + } + + node.childrenUL = null; + node.getChildrenUL = function() { + if (!node.childrenUL) { + node.childrenUL = document.createElement("ul"); + node.childrenUL.className = "children_ul"; + node.childrenUL.style.display = "none"; + node.li.appendChild(node.childrenUL); + } + return node.childrenUL; + }; + + return node; +} + +function showRoot() +{ + var headerHeight = $("#top").height(); + var footerHeight = $("#nav-path").height(); + var windowHeight = $(window).height() - headerHeight - footerHeight; + (function (){ // retry until we can scroll to the selected item + try { + var navtree=$('#nav-tree'); + navtree.scrollTo('#selected',0,{offset:-windowHeight/2}); + } catch (err) { + setTimeout(arguments.callee, 0); + } + })(); +} + +function expandNode(o, node, imm, showRoot) +{ + if (node.childrenData && !node.expanded) { + if (typeof(node.childrenData)==='string') { + var varName = node.childrenData; + getScript(node.relpath+varName,function(){ + node.childrenData = getData(varName); + expandNode(o, node, imm, showRoot); + }, showRoot); + } else { + if (!node.childrenVisited) { + getNode(o, node); + } if (imm || ($.browser.msie && $.browser.version>8)) { + // somehow slideDown jumps to the start of tree for IE9 :-( + $(node.getChildrenUL()).show(); + } else { + $(node.getChildrenUL()).slideDown("fast"); + } + node.plus_img.innerHTML = arrowDown; + node.expanded = true; + } + } +} + +function glowEffect(n,duration) +{ + n.addClass('glow').delay(duration).queue(function(next){ + $(this).removeClass('glow');next(); + }); +} + +function highlightAnchor() +{ + var aname = hashUrl(); + var anchor = $(aname); + if (anchor.parent().attr('class')=='memItemLeft'){ + var rows = $('.memberdecls tr[class$="'+hashValue()+'"]'); + glowEffect(rows.children(),300); // member without details + } else if (anchor.parent().attr('class')=='fieldname'){ + glowEffect(anchor.parent().parent(),1000); // enum value + } else if (anchor.parent().attr('class')=='fieldtype'){ + glowEffect(anchor.parent().parent(),1000); // struct field + } else if (anchor.parent().is(":header")) { + glowEffect(anchor.parent(),1000); // section header + } else { + glowEffect(anchor.next(),1000); // normal member + } + gotoAnchor(anchor,aname,false); +} + +function selectAndHighlight(hash,n) +{ + var a; + if (hash) { + var link=stripPath(pathName())+':'+hash.substring(1); + a=$('.item a[class$="'+link+'"]'); + } + if (a && a.length) { + a.parent().parent().addClass('selected'); + a.parent().parent().attr('id','selected'); + highlightAnchor(); + } else if (n) { + $(n.itemDiv).addClass('selected'); + $(n.itemDiv).attr('id','selected'); + } + if ($('#nav-tree-contents .item:first').hasClass('selected')) { + $('#nav-sync').css('top','30px'); + } else { + $('#nav-sync').css('top','5px'); + } + showRoot(); +} + +function showNode(o, node, index, hash) +{ + if (node && node.childrenData) { + if (typeof(node.childrenData)==='string') { + var varName = node.childrenData; + getScript(node.relpath+varName,function(){ + node.childrenData = getData(varName); + showNode(o,node,index,hash); + },true); + } else { + if (!node.childrenVisited) { + getNode(o, node); + } + $(node.getChildrenUL()).css({'display':'block'}); + node.plus_img.innerHTML = arrowDown; + node.expanded = true; + var n = node.children[o.breadcrumbs[index]]; + if (index+11) hash = '#'+parts[1].replace(/[^\w\-]/g,''); + else hash=''; + } + if (hash.match(/^#l\d+$/)) { + var anchor=$('a[name='+hash.substring(1)+']'); + glowEffect(anchor.parent(),1000); // line number + hash=''; // strip line number anchors + } + var url=root+hash; + var i=-1; + while (NAVTREEINDEX[i+1]<=url) i++; + if (i==-1) { i=0; root=NAVTREE[0][1]; } // fallback: show index + if (navTreeSubIndices[i]) { + gotoNode(o,i,root,hash,relpath) + } else { + getScript(relpath+'navtreeindex'+i,function(){ + navTreeSubIndices[i] = eval('NAVTREEINDEX'+i); + if (navTreeSubIndices[i]) { + gotoNode(o,i,root,hash,relpath); + } + },true); + } +} + +function showSyncOff(n,relpath) +{ + n.html(''); +} + +function showSyncOn(n,relpath) +{ + n.html(''); +} + +function toggleSyncButton(relpath) +{ + var navSync = $('#nav-sync'); + if (navSync.hasClass('sync')) { + navSync.removeClass('sync'); + showSyncOff(navSync,relpath); + storeLink(stripPath2(pathName())+hashUrl()); + } else { + navSync.addClass('sync'); + showSyncOn(navSync,relpath); + deleteLink(); + } +} + +function initNavTree(toroot,relpath) +{ + var o = new Object(); + o.toroot = toroot; + o.node = new Object(); + o.node.li = document.getElementById("nav-tree-contents"); + o.node.childrenData = NAVTREE; + o.node.children = new Array(); + o.node.childrenUL = document.createElement("ul"); + o.node.getChildrenUL = function() { return o.node.childrenUL; }; + o.node.li.appendChild(o.node.childrenUL); + o.node.depth = 0; + o.node.relpath = relpath; + o.node.expanded = false; + o.node.isLast = true; + o.node.plus_img = document.createElement("span"); + o.node.plus_img.className = 'arrow'; + o.node.plus_img.innerHTML = arrowRight; + + if (localStorageSupported()) { + var navSync = $('#nav-sync'); + if (cachedLink()) { + showSyncOff(navSync,relpath); + navSync.removeClass('sync'); + } else { + showSyncOn(navSync,relpath); + } + navSync.click(function(){ toggleSyncButton(relpath); }); + } + + $(window).load(function(){ + navTo(o,toroot,hashUrl(),relpath); + showRoot(); + }); + + $(window).bind('hashchange', function(){ + if (window.location.hash && window.location.hash.length>1){ + var a; + if ($(location).attr('hash')){ + var clslink=stripPath(pathName())+':'+hashValue(); + a=$('.item a[class$="'+clslink.replace(/ + + + + + + +Bounce2: Related Pages + + + + + + + + + +
    +
    + + + + + + +
    +
    Bounce2 +
    +
    +
    + + + + + + + +
    + +
    +
    + + +
    + +
    + +
    +
    +
    Related Pages
    +
    +
    +
    Here is a list of all related documentation pages:
    + + +
     Deprecated List
    +
    +
    + + + + diff --git a/docs/resize.js b/docs/resize.js new file mode 100644 index 0000000..56e4a02 --- /dev/null +++ b/docs/resize.js @@ -0,0 +1,114 @@ +function initResizable() +{ + var cookie_namespace = 'doxygen'; + var sidenav,navtree,content,header,collapsed,collapsedWidth=0,barWidth=6,desktop_vp=768,titleHeight; + + function readCookie(cookie) + { + var myCookie = cookie_namespace+"_"+cookie+"="; + if (document.cookie) { + var index = document.cookie.indexOf(myCookie); + if (index != -1) { + var valStart = index + myCookie.length; + var valEnd = document.cookie.indexOf(";", valStart); + if (valEnd == -1) { + valEnd = document.cookie.length; + } + var val = document.cookie.substring(valStart, valEnd); + return val; + } + } + return 0; + } + + function writeCookie(cookie, val, expiration) + { + if (val==undefined) return; + if (expiration == null) { + var date = new Date(); + date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week + expiration = date.toGMTString(); + } + document.cookie = cookie_namespace + "_" + cookie + "=" + val + "; expires=" + expiration+"; path=/"; + } + + function resizeWidth() + { + var windowWidth = $(window).width() + "px"; + var sidenavWidth = $(sidenav).outerWidth(); + content.css({marginLeft:parseInt(sidenavWidth)+"px"}); + writeCookie('width',sidenavWidth-barWidth, null); + } + + function restoreWidth(navWidth) + { + var windowWidth = $(window).width() + "px"; + content.css({marginLeft:parseInt(navWidth)+barWidth+"px"}); + sidenav.css({width:navWidth + "px"}); + } + + function resizeHeight() + { + var headerHeight = header.outerHeight(); + var footerHeight = footer.outerHeight(); + var windowHeight = $(window).height() - headerHeight - footerHeight; + content.css({height:windowHeight + "px"}); + navtree.css({height:windowHeight + "px"}); + sidenav.css({height:windowHeight + "px"}); + var width=$(window).width(); + if (width!=collapsedWidth) { + if (width=desktop_vp) { + if (!collapsed) { + collapseExpand(); + } + } else if (width>desktop_vp && collapsedWidth0) { + restoreWidth(0); + collapsed=true; + } + else { + var width = readCookie('width'); + if (width>200 && width<$(window).width()) { restoreWidth(width); } else { restoreWidth(200); } + collapsed=false; + } + } + + header = $("#top"); + sidenav = $("#side-nav"); + content = $("#doc-content"); + navtree = $("#nav-tree"); + footer = $("#nav-path"); + $(".side-nav-resizable").resizable({resize: function(e, ui) { resizeWidth(); } }); + $(sidenav).resizable({ minWidth: 0 }); + $(window).resize(function() { resizeHeight(); }); + var device = navigator.userAgent.toLowerCase(); + var touch_device = device.match(/(iphone|ipod|ipad|android)/); + if (touch_device) { /* wider split bar for touch only devices */ + $(sidenav).css({ paddingRight:'20px' }); + $('.ui-resizable-e').css({ width:'20px' }); + $('#nav-sync').css({ right:'34px' }); + barWidth=20; + } + var width = readCookie('width'); + if (width) { restoreWidth(width); } else { resizeWidth(); } + resizeHeight(); + var url = location.href; + var i=url.indexOf("#"); + if (i>=0) window.location.hash=url.substr(i); + var _preventDefault = function(evt) { evt.preventDefault(); }; + $("#splitbar").bind("dragstart", _preventDefault).bind("selectstart", _preventDefault); + $(".ui-resizable-handle").dblclick(collapseExpand); + $(window).load(resizeHeight); +} + + diff --git a/docs/search/all_1.js b/docs/search/all_1.js index cd3ddd0..52e20e5 100644 --- a/docs/search/all_1.js +++ b/docs/search/all_1.js @@ -1,5 +1,5 @@ var searchData= [ - ['bounce',['Bounce',['../class_bounce.html',1,'Bounce'],['../class_bounce.html#aa62a2e2b5ad0ee6913a95f2f2a0e7606',1,'Bounce::Bounce()']]], + ['bounce',['Bounce',['../class_bounce.html',1,'Bounce'],['../class_bounce.html#aa62a2e2b5ad0ee6913a95f2f2a0e7606',1,'Bounce::Bounce()'],['../class_bounce.html#ab34517094faf21d4f38b36da2915132b',1,'Bounce::Bounce(uint8_t pin, unsigned long interval_millis)']]], ['bounce_202',['BOUNCE 2',['../index.html',1,'']]] ]; diff --git a/docs/search/all_3.js b/docs/search/all_3.js index 0f04bac..c61b06c 100644 --- a/docs/search/all_3.js +++ b/docs/search/all_3.js @@ -1,4 +1,5 @@ var searchData= [ + ['fallingedge',['fallingEdge',['../class_bounce.html#ac756559419bfa1c5060e5e4a4ad6406f',1,'Bounce']]], ['fell',['fell',['../class_bounce.html#abfbb0910f5b1ec4e25315cff26dd6289',1,'Bounce']]] ]; diff --git a/docs/search/all_5.js b/docs/search/all_5.js index 28f9bb9..81afa51 100644 --- a/docs/search/all_5.js +++ b/docs/search/all_5.js @@ -1,5 +1,6 @@ var searchData= [ ['read',['read',['../class_bounce.html#ae1936fdf44501992707e6cbaee9bbc76',1,'Bounce']]], + ['risingedge',['risingEdge',['../class_bounce.html#a3417beb80eb6593d768c2e9884c57aa0',1,'Bounce']]], ['rose',['rose',['../class_bounce.html#a9e4187934576e568cdfa8f94efeff6f2',1,'Bounce']]] ]; diff --git a/docs/search/all_7.html b/docs/search/all_7.html new file mode 100644 index 0000000..de19107 --- /dev/null +++ b/docs/search/all_7.html @@ -0,0 +1,26 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/search/all_7.js b/docs/search/all_7.js new file mode 100644 index 0000000..5223992 --- /dev/null +++ b/docs/search/all_7.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['update',['update',['../class_bounce.html#ab36d7b83bf32e0935a0c2c6a05096441',1,'Bounce']]] +]; diff --git a/docs/search/functions_1.js b/docs/search/functions_1.js index e06fa55..b46f930 100644 --- a/docs/search/functions_1.js +++ b/docs/search/functions_1.js @@ -1,4 +1,4 @@ var searchData= [ - ['bounce',['Bounce',['../class_bounce.html#aa62a2e2b5ad0ee6913a95f2f2a0e7606',1,'Bounce']]] + ['bounce',['Bounce',['../class_bounce.html#aa62a2e2b5ad0ee6913a95f2f2a0e7606',1,'Bounce::Bounce()'],['../class_bounce.html#ab34517094faf21d4f38b36da2915132b',1,'Bounce::Bounce(uint8_t pin, unsigned long interval_millis)']]] ]; diff --git a/docs/search/functions_3.js b/docs/search/functions_3.js index 0f04bac..c61b06c 100644 --- a/docs/search/functions_3.js +++ b/docs/search/functions_3.js @@ -1,4 +1,5 @@ var searchData= [ + ['fallingedge',['fallingEdge',['../class_bounce.html#ac756559419bfa1c5060e5e4a4ad6406f',1,'Bounce']]], ['fell',['fell',['../class_bounce.html#abfbb0910f5b1ec4e25315cff26dd6289',1,'Bounce']]] ]; diff --git a/docs/search/functions_5.js b/docs/search/functions_5.js index 28f9bb9..81afa51 100644 --- a/docs/search/functions_5.js +++ b/docs/search/functions_5.js @@ -1,5 +1,6 @@ var searchData= [ ['read',['read',['../class_bounce.html#ae1936fdf44501992707e6cbaee9bbc76',1,'Bounce']]], + ['risingedge',['risingEdge',['../class_bounce.html#a3417beb80eb6593d768c2e9884c57aa0',1,'Bounce']]], ['rose',['rose',['../class_bounce.html#a9e4187934576e568cdfa8f94efeff6f2',1,'Bounce']]] ]; diff --git a/docs/search/functions_7.html b/docs/search/functions_7.html new file mode 100644 index 0000000..83a7b84 --- /dev/null +++ b/docs/search/functions_7.html @@ -0,0 +1,26 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/search/functions_7.js b/docs/search/functions_7.js new file mode 100644 index 0000000..5223992 --- /dev/null +++ b/docs/search/functions_7.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['update',['update',['../class_bounce.html#ab36d7b83bf32e0935a0c2c6a05096441',1,'Bounce']]] +]; diff --git a/docs/search/pages_1.html b/docs/search/pages_1.html new file mode 100644 index 0000000..aedb14e --- /dev/null +++ b/docs/search/pages_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/docs/search/pages_1.js b/docs/search/pages_1.js new file mode 100644 index 0000000..038da54 --- /dev/null +++ b/docs/search/pages_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['deprecated_20list',['Deprecated List',['../deprecated.html',1,'']]] +]; diff --git a/src/Bounce2.h b/src/Bounce2.h index c956c95..ccf77f1 100644 --- a/src/Bounce2.h +++ b/src/Bounce2.h @@ -43,6 +43,11 @@ #include +/** + @example bounce.ino + This is an example of how to use the Example_Test class. + More details about this example. +*/ /** The Bounce class. @@ -50,14 +55,29 @@ class Bounce { public: - /** - Create an instance of the Bounce class. - */ + +/*! + @brief Create an instance of the Bounce class. + + @code + + // Create an instance of the Bounce class. + Bounce() button; + + @endcode +*/ Bounce(); - /** - Attach to a pin and sets that pin's mode (INPUT/INPUT_PULLUP/OUTPUT) - */ + +/*! + @brief Attach to a pin and sets that pin's mode (INPUT, INPUT_PULLUP or OUTPUT). + + @param pin + The pin that is to be debounced. + @param mode + A valid Arduino pin mode (INPUT, INPUT_PULLUP or OUTPUT). + @return True if the event read was successful, otherwise false. +*/ void attach(int pin, int mode); /** @@ -67,41 +87,67 @@ class Bounce /** - Sets the debounce interval in milliseconds. + @brief Sets the debounce interval in milliseconds. + + @param interval_millis + The interval time in milliseconds. + */ void interval(uint16_t interval_millis); - /** - Updates the pin's state. Returns 1 if the state changed. Returns 0 if the state did not change. Because Bounce does not use interrupts, you have to "update" the object before reading its value and it has to be done as often as possible (that means to include it in your loop()). Only call update() once per loop(). - */ + +/*! + @brief Updates the pin's state. + + Because Bounce does not use interrupts, you have to "update" the object before reading its value and it has to be done as often as possible (that means to include it in your loop()). Only call update() once per loop(). + + @return True if the pin changed state. +*/ + bool update(); /** - Returns the pin's state (HIGH or LOW). + @brief Returns the pin's state (HIGH or LOW). + + @return HIGH or LOW. */ bool read(); /** - Returns true if pin signal transitions from high to low. + @brief Returns true if pin signal transitions from high to low. */ bool fell(); /** - Returns true if pin signal transitions from low to high. + @brief Returns true if pin signal transitions from low to high. */ bool rose(); - // Partial compatibility for programs written with Bounce version 1 + + /** + @brief Deprecated (i.e. do not use). Included for partial compatibility for programs written with Bounce version 1 + */ bool risingEdge() { return rose(); } + /** + @brief Deprecated (i.e. do not use). Included for partial compatibility for programs written with Bounce version 1 + */ bool fallingEdge() { return fell(); } - Bounce(uint8_t pin, unsigned long interval_millis ) : Bounce() { + /** + @brief Deprecated (i.e. do not use). Included for partial compatibility for programs written with Bounce version 1 + */ + Bounce(uint8_t pin, unsigned long interval_millis ) : Bounce() { attach(pin); interval(interval_millis); } /** - Returns the duration in milliseconds of the current state. Is reset to 0 once the pin rises or falls. + @brief Returns the duration in milliseconds of the current state. + + Is reset to 0 once the pin rises ( rose() ) or falls ( fell() ). + + @return The duration in milliseconds (unsigned long) of the current state. */ + unsigned long duration();