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