Skip to content

Commit 5019028

Browse files
committed
New contructor and drawString() api to print using ROW and COLUMN
1 parent 06894e3 commit 5019028

File tree

6 files changed

+818
-2
lines changed

6 files changed

+818
-2
lines changed
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
/*! \mainpage
2+
* Arduino and Raspberry Pi library for handle button press.
3+
* \section intro_sec Introduction
4+
* This library can be used with Arduino or Raspberry Pi, hardware specific api are performed by pre-processor defines.
5+
*
6+
* Futures:
7+
* -Arduino compliant.
8+
* -Raspberry Pi compliant. Both WiringPi and Pigpio library are supported (see includes comments in DDigitalButton.h)
9+
* -In polling mode, all 8 states and triggers can be read and handled:
10+
* -In event mode, 4 triggers fires callback.
11+
*
12+
* State and triggers:
13+
RELEASE STATE: button is not in StatePressed state.
14+
PRESS STATE: button is in StatePressed state.
15+
PRESSED TRIGGER: press-release after PressedMillis time.
16+
LONG_PRESSED TRIGGER: button is kept pressed for longer than LongPressedMillis.
17+
LONG_PRESSING STATE: after LONG_PRESSED, if button still pressed, the state change in LONG_PRESSING until button is released.
18+
DBL_PRESSED TRIGGER: press-release-press within DblPressSpeedMillis time.
19+
DBL_PRESSING STATE: after DBL_PRESSED, if button still pressed, the state change in DBL_PRESSING until button is released.
20+
RELEASED TRIGGER: release after PRESSED, LONG_PRESSED, DBL_PRESSED.
21+
*
22+
* \section usage_sec Usage
23+
*
24+
* @code
25+
*
26+
* @endcode
27+
*/
28+
29+
#include "DDigitalButton.h"
30+
31+
/**
32+
* @brief Constructor
33+
* @param DigitalPin -> Pin number where button is connected.
34+
* @param PressedState -> Can be HIGH or LOW and it is the pin level for which the button is considered to be pressed.
35+
* @param PullUp -> If true the internal pull-up resistor is connected.
36+
* @param PressedMillis -> Time in milliseconds after which "press and release" is triggered as PRESSED.
37+
* @param LongPressedMillis -> Time in milliseconds after which a "keeping press" is triggered as LONG_PRESSED.
38+
* @param DblPressSpeedMillis -> Time in milliseconds before which "press, release, press" is triggered as DBL_PRESSED.
39+
*/
40+
DDigitalButton::DDigitalButton(int DigitalPin, uint8_t PressedState, bool PullUp, unsigned int PressedMillis, unsigned int LongPressedMillis, unsigned int DblPressSpeedMillis)
41+
{
42+
// User settings
43+
Pin=DigitalPin;
44+
StatePressed=PressedState;
45+
PressedDuration=PressedMillis;
46+
LongPressedDuration=LongPressedMillis;
47+
DblPressSpeedDuration=DblPressSpeedMillis;
48+
49+
// Init timers
50+
ReleaseMs=NowMillis();
51+
PressMs=ReleaseMs;
52+
PressedMs=ReleaseMs;
53+
54+
// Trigger Callback
55+
Callback=NULL;
56+
57+
// Pull-up
58+
if (PullUp) {
59+
SetPinMode(INPUT_PULLUP);
60+
}
61+
else {
62+
SetPinMode(INPUT);
63+
}
64+
65+
// Read current input state
66+
Read();
67+
}
68+
69+
/**
70+
* Enable event mode: set a callback that is called on each TRIGGER state.
71+
* @param EventCallback -> Function to call.
72+
* Callback function must be used in this way:
73+
* @code
74+
* void EventCallback(DDigitalButton::State trigger) {
75+
* if (trigger == DDigitalButton::PRESSED) {
76+
* // Do something
77+
* }
78+
* }
79+
*/
80+
void DDigitalButton::SetEventCallback(DCallback EventCallback)
81+
{
82+
Callback=EventCallback;
83+
}
84+
85+
//! @return the current button State.
86+
DDigitalButton::State DDigitalButton::Read(void)
87+
{
88+
bool Trig=false;
89+
90+
if (PrevState == RELEASED) {
91+
CurrState=RELEASE;
92+
}
93+
if (PrevState == PRESSED) {
94+
CurrState=PRESS;
95+
}
96+
97+
if (ReadPin() == StatePressed) {
98+
PressMs=NowMillis(); // Press time
99+
if (PrevState == RELEASE) {
100+
if ((PressMs-ReleaseMs) > 50) {
101+
CurrState=PRESS;
102+
}
103+
}
104+
else if (PrevState == PRESS) {
105+
if ((PressMs-PressedMs) < DblPressSpeedDuration) {
106+
CurrState=DBL_PRESSED;
107+
Trig=true;
108+
}
109+
if ((PressMs-ReleaseMs) > LongPressedDuration) {
110+
CurrState=LONG_PRESSED;
111+
Trig=true;
112+
}
113+
}
114+
else if (PrevState == LONG_PRESSED) {
115+
CurrState=LONG_PRESSING;
116+
}
117+
else if (PrevState == DBL_PRESSED) {
118+
CurrState=DBL_PRESSING;
119+
}
120+
}
121+
else {
122+
ReleaseMs=NowMillis(); // Release time
123+
if (PrevState == PRESS) {
124+
if ((ReleaseMs-PressMs) > PressedDuration) {
125+
CurrState=PRESSED;
126+
Trig=true;
127+
PressMs=ReleaseMs;
128+
}
129+
else if ((ReleaseMs-PressMs) > 50) {
130+
PressedMs=NowMillis();
131+
}
132+
}
133+
else if (PrevState == PRESSED || PrevState == LONG_PRESSING || PrevState == LONG_PRESSED) {
134+
CurrState=RELEASED;
135+
Trig=true;
136+
}
137+
else {
138+
CurrState=RELEASE;
139+
}
140+
}
141+
142+
PrevState=CurrState;
143+
if (Trig) {
144+
if (Callback != NULL) {
145+
//Serial.println("Callback");
146+
Callback(CurrState);
147+
}
148+
}
149+
150+
return (CurrState);
151+
}
152+
153+
//! Overload operator ==
154+
DDigitalButton::operator DDigitalButton::State()
155+
{
156+
return Read();
157+
}
158+
159+
//! Wrapper function to set mode for pin (INPUT or INPUT_PULLUP)
160+
void DDigitalButton::SetPinMode(uint8_t Mode)
161+
{
162+
#ifdef ARDUINO
163+
pinMode(Pin,Mode);
164+
#else
165+
#ifdef PIGPIO_VERSION
166+
gpioSetMode(Pin,Mode);
167+
#else
168+
pinMode(Pin,Mode);
169+
#endif
170+
#endif
171+
}
172+
173+
//! Wrapper function to read direct pin level.
174+
/**
175+
* @return pin level (HIGH or LOW)
176+
*/
177+
uint8_t DDigitalButton::ReadPin() {
178+
#ifdef ARDUINO
179+
return(digitalRead(Pin));
180+
#else
181+
#ifdef PIGPIO_VERSION
182+
return(gpioRead(Pin));
183+
#else
184+
return(digitalRead(Pin));
185+
#endif
186+
#endif
187+
}
188+
189+
//! Wrapper function for getting arduino "millis()" function value
190+
unsigned long DDigitalButton::NowMillis(void)
191+
{
192+
#ifdef ARDUINO
193+
return(millis());
194+
#else
195+
#ifdef PIGPIO_VERSION
196+
// c++ equivalent of arduino millis()
197+
//extern unsigned int millis (void) ;
198+
return(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
199+
#else
200+
return(millis());
201+
#endif
202+
#endif
203+
}
204+
205+
/*
206+
long millis(){
207+
struct timespec _t;
208+
clock_gettime(CLOCK_REALTIME, &_t);
209+
return _t.tv_sec*1000 + lround(_t.tv_nsec/1.0e6);
210+
}
211+
*/
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#ifndef DDigitalButtonH
2+
#define DDigitalButtonH
3+
4+
#ifdef ARDUINO
5+
// Arduino inlcudes
6+
#if ARDUINO >= 100
7+
#include "Arduino.h"
8+
#else
9+
#include "wiring.h"
10+
#include "WProgram.h"
11+
#endif
12+
#else
13+
// RPi includes
14+
#include <stdint.h>
15+
// include lib which want to use (if both are included, pigpio is used)
16+
#include <pigpio.h>
17+
//#include <wiringPi.h>
18+
19+
#ifndef __WIRING_PI_H__
20+
// for NowMillis()
21+
#include <chrono>
22+
#endif
23+
#endif
24+
25+
// Set arduino compatibily state defines
26+
#ifndef HIGH
27+
#define HIGH 1
28+
#endif
29+
30+
#ifndef LOW
31+
#define LOW 0
32+
#endif
33+
34+
#ifndef INPUT
35+
#define INPUT 0
36+
#endif
37+
38+
#ifndef OUTPUT
39+
#define OUTPUT 1
40+
#endif
41+
42+
#ifndef INPUT_PULLUP
43+
#define INPUT_PULLUP 2
44+
#endif
45+
46+
class DDigitalButton{
47+
48+
public:
49+
enum State {RELEASE, //! Release STATE: button is not in StatePressed state.
50+
PRESS, //! Press STATE: button is in StatePressed state.
51+
PRESSED, //! Pressed TRIGGER: press-release after PressedMillis time.
52+
LONG_PRESSED, //! Long pressed TRIGGER: button is kept pressed for longer than LongPressedMillis.
53+
LONG_PRESSING, //! Long Pressing STATE: after LONG_PRESSED, if button still pressed, the state change in LONG_PRESSING until button is released.
54+
DBL_PRESSED, //! Double pressed TRIGGER: press-release-press within DblPressSpeedMillis time.
55+
DBL_PRESSING, //! Double pressing STATE: after DBL_PRESSED, if button still pressed, the state change in DBL_PRESSING until button is released.
56+
RELEASED //! Released TRIGGER: release after PRESSED, LONG_PRESSED, DBL_PRESSED.
57+
};
58+
59+
typedef void (*DCallback)(State);
60+
61+
DDigitalButton(int DigitalPin, uint8_t PressedState = LOW, bool PullUp = true, unsigned int PressedMillis = 100, unsigned int LongPressedMillis = 1000, unsigned int DblPressSpeedMillis=100);
62+
void SetEventCallback(DCallback EventCallback);
63+
DDigitalButton::State Read(void);
64+
operator DDigitalButton::State();
65+
66+
private:
67+
void SetPinMode(uint8_t pinMode);
68+
uint8_t ReadPin(void);
69+
unsigned long NowMillis(void);
70+
uint8_t Pin;
71+
State CurrState;
72+
State PrevState;
73+
uint8_t StatePressed;
74+
75+
unsigned long ReleaseMs;
76+
unsigned long PressMs;
77+
unsigned long PressedMs;
78+
79+
unsigned long PressedDuration;
80+
unsigned long DblPressSpeedDuration;
81+
unsigned long LongPressedDuration;
82+
DCallback Callback;
83+
};
84+
#endif

0 commit comments

Comments
 (0)