Serial Wombat Arduino Library
SerialWombatDebouncedInput.h
Go to the documentation of this file.
1 #pragma once
2 /*
3 Copyright 2020-2021 Broadwell Consulting Inc.
4 
5 "Serial Wombat" is a registered trademark of Broadwell Consulting Inc. in
6 the United States. See SerialWombat.com for usage guidance.
7 
8 Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14 
15 The above copyright notice and this permission notice shall be included in
16  * all 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
21  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24  * OTHER DEALINGS IN THE SOFTWARE.
25 */
26 
27 #include "SerialWombat.h"
28 #include "limits.h"
29 
75 {
76 public:
83 
84 
93  void begin(uint8_t pin, uint16_t debounce_mS = 30, bool invert = true, bool usePullUp = true)
94  {
95  _pin = pin;
96  uint8_t tx[8] = { 200,_pin,10,SW_LE16(debounce_mS),invert,0,usePullUp };
97  _sw.sendPacket(tx);
98  }
99 
108  bool digitalRead()
109  {
110  return (_sw.readPublicData(_pin) > 0);
111  }
112 
113  /*
114  \brief return the number of mS that the debounced input has been in true state
115 
116  Note that this value starts incrementing after the debounce period, not after the physical pin transition.
117 
118  \return returns a value in mS which saturates at 65535. Returns 0 if currently false.
119  */
121  {
122 
123  uint8_t tx[8] = { 201,_pin,10,1,0x55,0x55,0x55,0x55 };
124  uint8_t rx[8];
125  _sw.sendPacket(tx,rx);
126 
127  transitions += (256 * rx[5] + rx[4]);
128  if (rx[3] == 0)
129  {
130  return (0);
131  }
132  else
133  {
134  return(256 * rx[7] + rx[6]);
135  }
136  }
137 
138  /*
139  \brief return the number of mS that the debounced input has been in false state
140 
141  Note that this value starts incrementing after the debounce period, not after the physical pin transition.
142 
143  \return returns a value in mS which saturates at 65535. Returns 0 if currently true.
144  */
146  {
147 
148  uint8_t tx[8] = { 201,_pin,10,1,0x55,0x55,0x55,0x55 };
149  uint8_t rx[8];
150  _sw.sendPacket(tx, rx);
151 
152  transitions += (256 * rx[5] + rx[4]);
153 
154  if (rx[3] == 1)
155  {
156  return (0);
157  }
158  else
159  {
160  return(256 * rx[7] + rx[6]);
161  }
162  }
163 
164  /*
165  \brief Queries the number of transistions that have occured on the debounced input
166 
167  This function queries the debounced input for current state and transitions since last call.
168  transition count is put in the global member transitions. The debounced input in the Serial
169  Wombat resets its count to zero after this call.
170 
171  \return TRUE or FALSE, current status of debounced input
172  */
173  bool readTransitionsState(bool resetTransitionCounts = true)
174  {
175  uint8_t tx[8] = { 201,_pin,10,(uint8_t)resetTransitionCounts,0x55,0x55,0x55,0x55 };
176  uint8_t rx[8];
177  _sw.sendPacket(tx, rx);
178  transitions = (256 * rx[5] + rx[4]);
179  return (rx[3] > 0);
180  }
181 
182 private:
183  uint8_t _pin = 255;
184 };
185 
186 
207 {
208 public:
209 
214  SerialWombatButtonCounter( SerialWombatAbstractButton& serialWombatDebouncedInput):_debouncedInput(serialWombatDebouncedInput)
215  {
216  _debouncedInput = serialWombatDebouncedInput;
217  }
218 
232  void begin(long* variableToIncrement,
233  long slowIncrement = 1, unsigned long slow_mS_betweenIncrements = 250,
234  uint16_t slowToMediumTransition_mS = 1000,
235  long mediumIncrement = 1, unsigned long medium_mS_betweenIncrements = 100,
236  uint16_t mediumToFastTransition_mS = 1000 ,
237  long fastIncrement = 1, unsigned long fast_mS_betweenIncrements = 50)
238  {
239  _variableToIncrement = variableToIncrement;
240 
241  _slowIncrement = slowIncrement;
242  _slow_mS_betweenIncrements = slow_mS_betweenIncrements;
243 
244  _slowToMediumTransition_mS = slowToMediumTransition_mS;
245 
246  _mediumIncrement = mediumIncrement;
247  _medium_mS_betweenIncrements = medium_mS_betweenIncrements;
248 
249  _mediumToFastTransistion_mS = mediumToFastTransition_mS;
250 
251  _fastIncrement = fastIncrement;
252  _fast_mS_betweenIncrements = fast_mS_betweenIncrements;
253 
254  _lastPressDuration = 0;
255 
256  }
258  bool update()
259  {
260  uint16_t pressDuration = _debouncedInput.readDurationInTrueState_mS();
261  int increments = 0;
262  bool incremented = false;
263  bool pressed = false;
264  if (pressDuration > 0)
265  {
266  if (_lastPressDuration >= pressDuration)
267  {
268  _lastPressDuration = 0;
269  }
270 
271  if (pressDuration > _mediumToFastTransistion_mS)
272  {
273  // Increment fast
274  increments = (pressDuration - _lastPressDuration) / _fast_mS_betweenIncrements;
275  *_variableToIncrement += _fastIncrement * increments;
276  _lastPressDuration += _fast_mS_betweenIncrements * increments;
277  }
278  else if (pressDuration > _slowToMediumTransition_mS)
279  {
280  // Increment medium
281  increments = (pressDuration - _lastPressDuration) / _medium_mS_betweenIncrements;
282  *_variableToIncrement += _mediumIncrement * increments;
283  _lastPressDuration += _medium_mS_betweenIncrements * increments;
284  }
285  else
286  {
287  //Increment slow
288  increments = (pressDuration - _lastPressDuration) / _slow_mS_betweenIncrements;
289  *_variableToIncrement += _slowIncrement * increments;
290  _lastPressDuration += _slow_mS_betweenIncrements * increments;
291  incremented = increments > 0; // An increment happened
292  }
293  if (incremented)
294  {
295  _debouncedInput.transitions = 0; // Get rid of false->true transition so that final release doesn't cause and increment
296  }
297  pressed = true;
298  }
299  else
300  {
301  // Button isn't currently pressed. if there were other transitions, add them
302  _lastPressDuration = 0;
303  int presses = _debouncedInput.transitions / 2;
304  *_variableToIncrement += _slowIncrement * presses;
305  _debouncedInput.transitions -= presses * 2;
306  }
307 
308  if (*_variableToIncrement > highLimit)
309  {
310  *_variableToIncrement = highLimit;
311  }
312  if (*_variableToIncrement < lowLimit)
313  {
314  *_variableToIncrement = lowLimit;
315  }
316 
317  return (pressed);
318  }
319 
321  long highLimit = LONG_MAX;
323  long lowLimit = LONG_MIN;
324 
325 private:
326  SerialWombatAbstractButton& _debouncedInput;
327  long* _variableToIncrement;
328 
329  long _slowIncrement;
330  unsigned long _slow_mS_betweenIncrements;
331 
332  uint16_t _slowToMediumTransition_mS;
333 
334  long _mediumIncrement;
335  unsigned long _medium_mS_betweenIncrements;
336 
337  uint16_t _mediumToFastTransistion_mS;
338 
339  long _fastIncrement;
340  unsigned long _fast_mS_betweenIncrements;
341 
342  unsigned long _lastPressDuration;
343 
344 };
345 
SerialWombatChip
Class for a Serial Wombat chip. Each Serial Wombat chip on a project should have its own instance.
Definition: SerialWombat.h:286
SerialWombatButtonCounter::update
bool update()
Called periodically to query the SerialWombatDebouncedInput and update the variable.
Definition: SerialWombatDebouncedInput.h:258
SerialWombatButtonCounter::begin
void begin(long *variableToIncrement, long slowIncrement=1, unsigned long slow_mS_betweenIncrements=250, uint16_t slowToMediumTransition_mS=1000, long mediumIncrement=1, unsigned long medium_mS_betweenIncrements=100, uint16_t mediumToFastTransition_mS=1000, long fastIncrement=1, unsigned long fast_mS_betweenIncrements=50)
Definition: SerialWombatDebouncedInput.h:232
SerialWombatButtonCounter
A class that runs on top of SerialWombaAbstractButton to increment or decrement a variable based on a...
Definition: SerialWombatDebouncedInput.h:206
SerialWombatPin::_sw
SerialWombatChip & _sw
Definition: SerialWombatPin.h:134
SerialWombatDebouncedInput::readDurationInTrueState_mS
uint16_t readDurationInTrueState_mS()
return the number of mS that the input has been in true state
Definition: SerialWombatDebouncedInput.h:120
SerialWombatButtonCounter::lowLimit
long lowLimit
The variable will not decrement below this limit.
Definition: SerialWombatDebouncedInput.h:323
SerialWombat.h
SerialWombatAbstractButton::transitions
uint16_t transitions
Number of transitions returned by last call to readTransitionsState()
Definition: SerialWombatAbstractButton.h:72
SerialWombatDebouncedInput
A pin mode class that debounces inputs.
Definition: SerialWombatDebouncedInput.h:74
SerialWombatChip::readPublicData
uint16_t readPublicData(uint8_t pin)
Read the 16 Bit public data associated with a Serial Wombat Pin Mode.
Definition: SerialWombat.h:661
SerialWombatPin
Describes a Serial Wombat Pin. Is base class for other pin modes.
Definition: SerialWombatPin.h:38
SerialWombatButtonCounter::highLimit
long highLimit
The variable will not increment above this limit.
Definition: SerialWombatDebouncedInput.h:321
SerialWombatDebouncedInput::readTransitionsState
bool readTransitionsState(bool resetTransitionCounts=true)
Queries the number of transistions that have occured on the debounced input.
Definition: SerialWombatDebouncedInput.h:173
SerialWombatChip::sendPacket
int sendPacket(uint8_t tx[], uint8_t rx[])
Send an 8 byte packet to the Serial Wombat chip and wait for 8 bytes back.
Definition: SerialWombat.cpp:115
SerialWombatPin::pin
uint8_t pin()
Returns the current SW pin number. Used primarily for virtual calls by derived classes.
Definition: SerialWombatPin.h:121
SerialWombatAbstractButton::readDurationInTrueState_mS
virtual uint16_t readDurationInTrueState_mS()=0
return the number of mS that the input has been in true state
SW_LE16
#define SW_LE16(_a)
Convert a uint16_t to two bytes in little endian format for array initialization.
Definition: SerialWombat.h:41
SerialWombatDebouncedInput::digitalRead
bool digitalRead()
Returns the debounced state of the input.
Definition: SerialWombatDebouncedInput.h:108
SerialWombatDebouncedInput::readDurationInFalseState_mS
uint16_t readDurationInFalseState_mS()
return the number of mS that the input has been in false state
Definition: SerialWombatDebouncedInput.h:145
SerialWombatDebouncedInput::begin
void begin(uint8_t pin, uint16_t debounce_mS=30, bool invert=true, bool usePullUp=true)
Initialize a debounced input.
Definition: SerialWombatDebouncedInput.h:93
SerialWombatDebouncedInput::SerialWombatDebouncedInput
SerialWombatDebouncedInput(SerialWombatChip &serialWombatChip)
Constructor for the SerialWombatDebouncedInput class.
Definition: SerialWombatDebouncedInput.h:82
SerialWombatButtonCounter::SerialWombatButtonCounter
SerialWombatButtonCounter(SerialWombatAbstractButton &serialWombatDebouncedInput)
Constructor for SerialWombatButtonCounter.
Definition: SerialWombatDebouncedInput.h:214
SerialWombatAbstractButton
SerialWombat18CapTouch, SerialWombatDebouncedInput and SerialWombatMatrixButton inherit from this cla...
Definition: SerialWombatAbstractButton.h:40