-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathSwitch.cpp
161 lines (134 loc) · 4.84 KB
/
Switch.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
Switch
Copyright (C) 2012 Albert van Dalen http://www.avdweb.nl
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at http://www.gnu.org/licenses .
Version 20-4-2013
_debounceDelay=50
Version 22-5-2013
Added longPress, doubleClick
_______________________ _false
| | || |
input | || ||| |
_____| ||_||| ||____________
poll ^ ^ ^ ^
switchedTime ^ ^
<---------100ms--------><--->
debounceDelay <----50ms----> <----50ms---->
switched 1 1 0 0
newlevel 1 0 1 0
________________________
level _____| |___________________
.......................................................................
_______________________ _______
| | |
input | | |
________| |___________|
longPressDelay <----------->
doubleClickDelay <-------------------------------------->
_________
_longPressLatch ______________________| |_________________
_
_longPress ______________________| |__________________________
_
_doubleClick ____________________________________________| |____
*/
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include "Switch.h"
// level(0)
Switch::Switch(byte _pin, byte PinMode, bool polarity, int debounceDelay, int longPressDelay, int doubleClickDelay):
pin(_pin), debounceDelay(debounceDelay), longPressDelay(longPressDelay), doubleClickDelay(doubleClickDelay), polarity(polarity)
{ pinMode(pin, PinMode);
_switchedTime = millis();
level = digitalRead(pin);
}
bool Switch::poll()
{ _longPress = _doubleClick = false;
bool newlevel = digitalRead(pin);
if(!_longPressLatch)
{ _longPress = on() && ((millis() - pushedTime) > longPressDelay); // true just one time between polls
_longPressLatch = _longPress; // will be reset at next switch
}
if(_longPressCallback && longPress())
{ _longPressCallback(_longPressCallbackParam);
}
if((newlevel != level) & (millis() - _switchedTime >= debounceDelay))
{ _switchedTime = millis();
level = newlevel;
_switched = 1;
_longPressLatch = false;
if(pushed())
{ _doubleClick = (millis() - pushedTime) < doubleClickDelay;
pushedTime = millis();
}
if(_pushedCallback && pushed())
{ _pushedCallback(_pushedCallbackParam);
}
else if(_releasedCallback && released())
{ _releasedCallback(_releasedCallbackParam);
}
if(_doubleClickCallback && doubleClick())
{ _doubleClickCallback(_doubleClickCallbackParam);
}
return _switched;
}
return _switched = 0;
}
bool Switch::switched()
{ return _switched;
}
bool Switch::on()
{ return !(level^polarity);
}
bool Switch::pushed()
{ return _switched && !(level^polarity);
}
bool Switch::released()
{ return _switched && (level^polarity);
}
bool Switch::longPress()
{ return _longPress;
}
bool Switch::doubleClick()
{ return _doubleClick;
}
bool Switch::longPressLatch()
{ return _longPressLatch;
}
void Switch::setPushedCallback(switchCallback_t cb, void* param)
{ /// Store the "pushed" callback function
_pushedCallback = cb;
_pushedCallbackParam = param;
}
void Switch::setReleasedCallback(switchCallback_t cb, void* param)
{ /// Store the "released" callback function
_releasedCallback = cb;
_releasedCallbackParam = param;
}
void Switch::setLongPressCallback(switchCallback_t cb, void* param)
{ /// Store the "long press" callback function
_longPressCallback = cb;
_longPressCallbackParam = param;
}
void Switch::setDoubleClickCallback(switchCallback_t cb, void* param)
{ /// Store the "double click" callback function
_doubleClickCallback = cb;
_doubleClickCallbackParam = param;
}
unsigned long Switch::pushedDuration() {
if (on()) {
unsigned long dur = millis() - pushedTime;
if (!dur) {
dur = 1; // minimum 1ms
}
return dur;
} else {
return 0;
}
}