Skip to content

Commit e5f71c0

Browse files
Added:
Button GarageControl Led List Relay Timer
1 parent d75f3fb commit e5f71c0

File tree

17 files changed

+1491
-0
lines changed

17 files changed

+1491
-0
lines changed

Button.cpp

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
#include "Button.h"
2+
3+
Button::Button(uint8_t pin, uint8_t pressed_value, bool use_pullup) :
4+
m_pin(pin),
5+
m_pressed_is_high(pressed_value == HIGH),
6+
7+
m_debounce_t(0),
8+
m_click_t(0),
9+
m_dbl_click_t(0),
10+
m_click_count(0),
11+
m_last_read(false),
12+
m_current_state(false),
13+
m_held(false)
14+
{
15+
memset(m_handler, 0, ButtonEvent_Count);
16+
17+
pinMode(m_pin, use_pullup ? INPUT_PULLUP : INPUT);
18+
}
19+
20+
Button::~Button()
21+
{
22+
pinMode(m_pin, OUTPUT);
23+
digitalWrite(m_pin, LOW);
24+
}
25+
26+
void Button::attach(ButtonEvent event, ButtonEventHandler handler)
27+
{
28+
m_handler[event] = handler;
29+
}
30+
31+
void Button::fire(ButtonEvent event)
32+
{
33+
if (m_handler[event] != NULL)
34+
{
35+
m_handler[event](*this);
36+
}
37+
}
38+
39+
uint8_t Button::clicks() const
40+
{
41+
return m_click_count;
42+
}
43+
44+
void Button::run()
45+
{
46+
// read the button
47+
bool state = read();
48+
49+
// if latch up
50+
if (state && !m_current_state)
51+
{
52+
m_current_state = state;
53+
m_click_t = millis();
54+
55+
// trigger the pressed event
56+
fire(bePressed);
57+
}
58+
else
59+
// if latch down
60+
if (!state && m_current_state)
61+
{
62+
m_current_state = state;
63+
m_held = false;
64+
65+
// check to see if the button was pressed long enough
66+
// to identify a click
67+
if (millis() - m_click_t <= BUTTON_CLICK_TIMEOUT)
68+
{
69+
m_click_count++;
70+
// trigger the click event
71+
fire(beClick);
72+
73+
if (m_click_count == 1)
74+
{
75+
m_dbl_click_t = millis();
76+
}
77+
else if (m_click_count == 2)
78+
{
79+
m_click_count = 0;
80+
81+
if ((millis() - m_dbl_click_t) <= BUTTON_DOUBLE_CLICK_TIMEOUT)
82+
{
83+
// trigger the double click event
84+
fire(beDblClick);
85+
}
86+
}
87+
}
88+
else
89+
{
90+
m_click_count = 0;
91+
}
92+
93+
// trigger the released event
94+
fire(beReleased);
95+
}
96+
97+
if (m_current_state)
98+
{
99+
if (!m_held && ((millis() - m_click_t) > BUTTON_HELD_TIMEOUT))
100+
{
101+
m_held = true;
102+
// trigger the held event
103+
fire(beHeld);
104+
}
105+
}
106+
else
107+
{
108+
if ((millis() - m_dbl_click_t) > BUTTON_DOUBLE_CLICK_TIMEOUT)
109+
{
110+
m_click_count = 0;
111+
}
112+
}
113+
}
114+
115+
bool Button::read()
116+
{
117+
// store the current state
118+
bool state = m_current_state;
119+
120+
// read the button
121+
bool current_read =
122+
m_pressed_is_high ?
123+
(digitalRead(m_pin) == HIGH) : (digitalRead(m_pin) == LOW);
124+
125+
// if the button state changed
126+
if (current_read != m_last_read)
127+
{
128+
// reset the timer
129+
m_debounce_t = millis();
130+
131+
// save the current read as the last read
132+
m_last_read = current_read;
133+
}
134+
135+
// if the timer has been running long enough
136+
// set the actual state to the current state
137+
if ((millis() - m_debounce_t) >= BUTTON_DEBOUNCE_DELAY)
138+
{
139+
// save the new state
140+
state = m_last_read;
141+
} // endif delay enough
142+
143+
return state;
144+
}

Button.h

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#ifndef __Button_h_
2+
#define __Button_h_
3+
4+
#include "Arduino.h"
5+
6+
// the amount of time required to identify a latch
7+
#define BUTTON_DEBOUNCE_DELAY 50
8+
9+
// the max amount of time allowed to identify a click / double click
10+
#define BUTTON_CLICK_TIMEOUT 200
11+
#define BUTTON_DOUBLE_CLICK_TIMEOUT 500
12+
#define BUTTON_HELD_TIMEOUT 1000
13+
14+
class Button;
15+
16+
typedef void (*ButtonEventHandler)(Button & button);
17+
18+
enum ButtonEvent
19+
{
20+
bePressed, beReleased, beClick, beDblClick, beHeld, ButtonEvent_Count
21+
};
22+
23+
class Button
24+
{
25+
public:
26+
// CTOR: creates a button object
27+
// pin: the pin that the button is attached to
28+
// pressed_value: either HIGH or LOW; the value indicating the (defaults to HIGH)
29+
// button was pressed
30+
Button(uint8_t pin, uint8_t pressed_value = HIGH, bool use_pullup = false);
31+
~Button();
32+
33+
// setup an event handler
34+
void attach(ButtonEvent event, ButtonEventHandler handler);
35+
36+
// returns the number of clicks that have occurred
37+
uint8_t clicks() const;
38+
39+
// returns the current state of the button accounting for debounce
40+
bool read();
41+
42+
// reads the button and executes events as they occur
43+
void run();
44+
45+
private:
46+
47+
// executes an event
48+
void fire(ButtonEvent event);
49+
50+
Button(const Button & rhs);
51+
Button & operator=(const Button & rhs);
52+
53+
uint8_t m_pin;
54+
bool m_pressed_is_high;
55+
56+
uint32_t m_debounce_t;
57+
uint32_t m_click_t;
58+
uint32_t m_dbl_click_t;
59+
uint8_t m_click_count;
60+
bool m_last_read;
61+
bool m_current_state;
62+
bool m_held;
63+
64+
ButtonEventHandler m_handler[ButtonEvent_Count];
65+
};
66+
67+
#endif // __Button_h_

GarageControl.h

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#ifndef __GarageControl_h_
2+
#define __GarageControl_h_
3+
4+
#if ARDUINO >= 100
5+
#include "Arduino.h"
6+
#else
7+
#include "WProgram.h"
8+
#endif
9+
10+
// This is the list of recognized commands. These can be commands that can either be sent or received.
11+
// In order to receive, attach a callback function to these events
12+
enum GC
13+
{
14+
GC_Acknowledge, // 0
15+
GC_Error, // 1
16+
GC_Temperature, // 2
17+
GC_DoorStatus, // 3
18+
GC_PushButton, // 4
19+
GC_CloseDoor, // 5
20+
GC_OpenDoor, // 6
21+
GC_GetTemperature, // 7
22+
GC_GetDoorStatus, // 8
23+
};
24+
25+
enum DS
26+
{
27+
DS_Unknown, // 0
28+
DS_Open, // 1
29+
DS_Opening, // 2
30+
DS_Closed, // 3
31+
DS_Closing // 4
32+
};
33+
34+
struct Response
35+
{
36+
GC code;
37+
uint32_t value;
38+
};
39+
40+
String toString(DS door)
41+
{
42+
switch( door )
43+
{
44+
case DS_Unknown:
45+
return "Unknown";
46+
case DS_Open:
47+
return "Open";
48+
case DS_Opening:
49+
return "Opening";
50+
case DS_Closed:
51+
return "Closed";
52+
case DS_Closing:
53+
return "Closing";
54+
}
55+
56+
return "??";
57+
}
58+
59+
Print & operator<<(Print & ps, GC e)
60+
{
61+
switch( e )
62+
{
63+
case GC_Acknowledge:
64+
ps.print("GC_Acknowledge");
65+
break;
66+
67+
case GC_Error:
68+
ps.print("GC_Error");
69+
break;
70+
71+
case GC_GetTemperature:
72+
ps.print("GC_GetTemperature");
73+
break;
74+
75+
case GC_Temperature:
76+
ps.print("GC_Temperature");
77+
break;
78+
79+
case GC_GetDoorStatus:
80+
ps.print("GC_GetDoorStatus");
81+
break;
82+
83+
case GC_DoorStatus:
84+
ps.print("GC_DoorStatus");
85+
break;
86+
87+
default:
88+
ps.print("??");
89+
}
90+
91+
ps.print(" (");
92+
ps.print(e);
93+
ps.print(")");
94+
95+
return ps;
96+
}
97+
98+
Print & operator<<(Print & ps, const Response & r)
99+
{
100+
ps.print("code: ");
101+
ps << r.code;
102+
ps.print("; value: ");
103+
ps.print(r.value);
104+
105+
return ps;
106+
}
107+
108+
#endif // __GarageControl_h_

0 commit comments

Comments
 (0)