Commanders
Arduino buttons/bus library
ButtonsCommanderSwitch.cpp
1 /*************************************************************
2 project: <Commanders>
3 author: <Thierry PARIS>
4 description: <Switch button with debounce.>
5 *************************************************************/
6 
7 #include <Commanders.h>
8 #include <stdint.h>
9 #ifndef NO_BUTTONSCOMMANDER
10 #ifndef NO_BUTTONSCOMMANDERSWITCH
11 
13 {
14  this->debounceDelay = 50;
15  this->lastSelectedPin = DP_INVALID;
16 }
17 
18 void beginItem(EventPin *inpIdPin)
19 {
20  if (inpIdPin->Pin != DP_INVALID)
21  {
22  pinMode2f(inpIdPin->Pin, INPUT_PULLUP);
23  }
24 }
25 
27 {
28 #ifdef COMMANDERS_DEBUG_MODE
29  if (this->EventPins.pFirst == NULL)
30  Serial.println(F("This switch button have no ID defined : begin() must be called AFTER AddEvent !"));
31 #endif
32 
33  CMDRSCHAINEDLISTITEM<EventPin> *pCurr = this->EventPins.pFirst;
34  while (pCurr != NULL)
35  {
36  beginItem(pCurr->Obj);
37 
38  pCurr->Obj->LastButtonState = HIGH;
39  pCurr->Obj->LastDebounceTime = 0;
40 
41  pCurr = pCurr->pNext;
42  }
43 }
44 
45 unsigned long ButtonsCommanderSwitch::GetId(GPIO_pin_t inPin, COMMANDERS_EVENT_TYPE *apEvent, int *apData) const
46 {
47  CMDRSCHAINEDLISTITEM<EventPin> *pCurr = this->EventPins.pFirst;
48  while (pCurr != NULL)
49  {
50  if (inPin == pCurr->Obj->Pin)
51  {
52  if (apEvent != NULL)
53  *apEvent = pCurr->Obj->Event;
54  if (apData != NULL)
55  *apData = pCurr->Obj->Data;
56  return pCurr->Obj->Id;
57  }
58 
59  pCurr = pCurr->pNext;
60  }
61  return UNDEFINED_ID;
62 }
63 
64 // Returns the index of the new added position.
65 EventPin *ButtonsCommanderSwitch::AddEvent(unsigned long inId, int inPin, COMMANDERS_EVENT_TYPE inEvent, int inData)
66 {
67  EventPin *pIdpin = new EventPin();
68  pIdpin->Pin = Arduino_to_GPIO_pin(inPin);
69  pIdpin->Id = inId;
70  pIdpin->Event = inEvent;
71  pIdpin->Data = inData;
72  pIdpin->LastButtonState = HIGH;
73  pIdpin->LastDebounceTime = 0;
74  this->EventPins.AddItem(pIdpin);
75 
76  return pIdpin;
77 }
78 
79 bool ButtonsCommanderSwitch::HavePinStateChanged(GPIO_pin_t inPin, unsigned long inDebounceDelay, byte *inpCurrentPinState, unsigned long *inpLastDebounceTime)
80 {
81  if (inPin != DP_INVALID)
82  {
83  // read the state of the switch into a local variable:
84  int pinState = digitalRead2f(inPin);
85 
86  // check to see if you just pressed the button
87  // (i.e. the input went from HIGH to LOW, inverted by INPUT_PULLUP), and you've waited
88  // long enough since the last press to ignore any noise:
89 
90  // If the switch changed since last time, start a new timer
91  if (pinState != *inpCurrentPinState)
92  {
93  // reset the debouncing timer
94 #ifdef COMMANDERS_DEBUG_MODE
95 #ifdef COMMANDERS_DEBUG_VERBOSE_MODE
96  Serial.print(F("Pin "));
97  Serial.print(GPIO_to_Arduino_pin(inPin));
98  Serial.print(pinState == HIGH ? F(" high") : F(" low"));
99  Serial.println(F(" debounced !"));
100 #endif
101 #endif
102  *inpLastDebounceTime = millis();
103  *inpCurrentPinState = pinState;
104  return false; // unchanged
105  }
106 
107  if (*inpLastDebounceTime > 0 && (millis() - *inpLastDebounceTime) > inDebounceDelay)
108  {
109  *inpLastDebounceTime = 0;
110  if (*inpCurrentPinState == pinState)
111  {
112  return true;
113  }
114  *inpCurrentPinState = pinState;
115  }
116  }
117 
118  return false;
119 }
120 
122 {
123  CMDRSCHAINEDLISTITEM<EventPin> *pCurr = this->EventPins.pFirst;
124  while (pCurr != NULL)
125  {
126  if (pCurr->Obj->Pin != DP_INVALID)
127  {
128  // Initialize first switch state at start
129  int pinState = digitalRead2f(pCurr->Obj->Pin);
130 
131  if (pinState == LOW)
132  {
133  this->lastSelectedPin = pCurr->Obj->Pin;
134  Commanders::RaiseEvent(pCurr->Obj->Id, pCurr->Obj->Event, pCurr->Obj->Data);
135  }
136  }
137 
138  pCurr = pCurr->pNext;
139  }
140 }
141 
143 {
144  if (this->EventPins.pFirst == NULL)
145  {
146 #ifdef COMMANDERS_DEBUG_MODE
147  if (this->debounceDelay != UINT32_MAX) // If the error message has not been yet shown...
148  {
149  Serial.println(F("This switch button have no ID defined : call AddEvent() and begin() !"));
150  // use it as a debug flag !
151  this->debounceDelay = UINT32_MAX; // The error message has been shown...
152  }
153 #endif
154  return UNDEFINED_ID;
155  }
156 
157  EventPin *pCurr = this->EventPins.pCurrentItem->Obj;
158  this->EventPins.NextCurrent();
159 
160  bool changed = ButtonsCommanderSwitch::HavePinStateChanged(pCurr->Pin, this->debounceDelay, &pCurr->LastButtonState, &pCurr->LastDebounceTime);
161 
162  if (changed == true && pCurr->LastButtonState == LOW)
163  {
164  this->lastSelectedPin = pCurr->Pin;
165  Commanders::RaiseEvent(pCurr->Id, pCurr->Event, pCurr->Data);
166  return pCurr->Id;
167  }
168 
169  return UNDEFINED_ID;
170 }
171 
172 #ifdef COMMANDERS_PRINT_COMMANDERS
173 void ButtonsCommanderSwitch::printCommander()
174 {
175  Serial.println(F(" Switch"));
176 
177  CMDRSCHAINEDLISTITEM<EventPin> *pCurr = this->EventPins.pFirst;
178  while (pCurr != NULL)
179  {
180  Serial.print(F(" Event - Pin: "));
181  Serial.print(GPIO_to_Arduino_pin(pCurr->Obj->Pin));
182  Serial.print(F(" / Id: "));
183  Serial.print(pCurr->Obj->Id);
184  Serial.print(F(" / Event type: "));
185  Commanders::printEventType(pCurr->Obj->Event, true);
186  Commanders::printEventData(pCurr->Obj->Event, pCurr->Obj->Data);
187  Serial.print(F(" / Debounce delay: "));
188  Serial.print(this->debounceDelay);
189  Serial.println(F(""));
190 
191  pCurr = pCurr->pNext;
192  }
193 }
194 #endif
195 #endif
196 #endif
static void printEventType(COMMANDERS_EVENT_TYPE inEventType, bool inDataFollow)
void NextCurrent()
Definition: Chain.hpp:85
CMDRSCHAINEDLISTITEM< T > * pCurrentItem
Definition: Chain.hpp:39
static unsigned long RaiseEvent(unsigned long inId, COMMANDERS_EVENT_TYPE inEvent = COMMANDERS_EVENT_MOVEPOSITIONID, int inData = 0)
Definition: Commanders.cpp:27
EventPin * AddEvent(unsigned long inId, int inPin, COMMANDERS_EVENT_TYPE inEvent = COMMANDERS_EVENT_MOVEPOSITIONID, int inData = 0)
COMMANDERS_EVENT_TYPE Event
COMMANDERS_EVENT_TYPE
Definition: Events.h:25
unsigned long GetId() const
static bool HavePinStateChanged(GPIO_pin_t inPin, unsigned long inDebounceDelay, byte *inpCurrentPinState, unsigned long *inpLastDebounceTime)
CMDRSCHAINEDLISTITEM * pNext
Definition: Chain.hpp:13
unsigned long LastDebounceTime
CMDRSCHAINEDLISTITEM< T > * pFirst
Definition: Chain.hpp:37
void AddItem(T *input)
Definition: Chain.hpp:61
#define UNDEFINED_ID
Definition: Events.h:38
unsigned long Id
static void printEventData(COMMANDERS_EVENT_TYPE inEventType, int inEventData)