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