Components and supplies
Arduino UNO
Jumper wires (generic)
Resistor 10k ohm
Toggle Switch, Toggle
Tactile Switch, Top Actuated
Apps and platforms
Arduino IDE
Project description
Code
reading_multiple_switch_types_by_polling.ino
c_cpp
Polling multiple switches, button and/or toggle types, or a mix.
1/* 2 Ron D Bentley, Stafford, UK 3 Feb 2021 4 5 Reading Multiple Switch Types, using simple polling 6 ''''''''''''''''''''''''''''''''''''''''''''''''''' 7 8 This example and code is in the public domain and may be used without restriction and 9 without warranty. 10 11 This sketch will reliably read any number of button and/or toggle switches by polling each of 12 them in turn. Once a switch is activated the main code loop will switch 13 to user provided code to handle the purpose of the switch. This is controlled 14 via a switch control struct(ure) and associated main loop switch-case code. 15 16 The sketch layout is straight forward and process code for each switch can be added 17 where indicated within the main loop, under the respective switch-case section for a 18 button switch. 19 20 Configurability: 21 1. Number of switches - the implementation is such that each switch is 22 allocated to a digital pin. The sketch will therefore support as many 23 switches as a microcontroller can provide digital inputs. 24 This example sketch is configured, 'out-of-the-box' (OOTB),for six switches, 25 3 x button switches plus 3 x toggle swith, but more may be added: 26 27 a. change the macro definition '#define num_switches' to be the total number of 28 switches to be connected 29 b. for each switch, decide its circuit type and allocate it to a digital pin 30 c. in the 'Switch to Pin Macro Definition List' add new switch macro 31 definitions, one for each additional switch, 32 for example: 33 '#define button_switch_? <pin number>', 34 '#define toggle_switch_? <pin number>', 35 etc 36 d. in the 'Switch Control Sruct(ure) Declaration' add further preset data to the 37 'switches' data struct(ure), for example: 38 '...,button_switch_?, circuit_?,...', 39 '...,toggle_switch_?, circuit_?,...', 40 etc. 41 42 For a fuller appreciation of button switch fundementals see the tutorial 'Understanding 43 and Using Button Switches': 44 https://create.arduino.cc/projecthub/ronbentley1/understanding-and-using-button-switches-2ffe6c?ref=platform&ref_id=424_trending___&offset=2 45*/ 46// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 47// These declarations are specifically for defining and controlling the attached switches 48// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 49 50#define circuit_C1 INPUT // switch circuit requires an external pull down 10k ohm resistor 51#define circuit_C2 INPUT_PULLUP // switch type reqires no other components beyond the button switch 52 53#define debounce 10 // number of millisecs to wait for a switch to settle once activated 54#define switched true // signifies switch has been pressed/switch cycle complete 55#define on true // used for toggle switch staus 56#define not_used true // helps self document code 57 58#define button_switch 1 // differentiates switch type 59#define toggle_switch 2 // toggle switches are NOT used in this example sketch - future use 60 61#define num_switches 6 // number of button switches connected 62 63// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 64// % Switch to Pin Macro Definition List % 65// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 66// Associate swithes each with a digital pin. 67// Add further definitions here if adding more switches. 68// Note that digital pins allocated are arbitary, any 69// available pin will do, or remove any not required. 70// The naming convention offered here helps to self 71// document the sketch. 72 73#define button_switch_1 2 74#define button_switch_2 3 75#define button_switch_3 4 76 77#define toggle_switch_1 5 78#define toggle_switch_2 6 79#define toggle_switch_3 7 80 81// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 82// % Switch Control Sruct(ure) Declaration % 83// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 84// Now set up the configuration data for each individual switch to be used by 85// the switch read functions and to generally define the nature of the switch. 86// 87struct switch_control { 88 int switch_type; // type of switch connected 89 int switch_pin; // digital input pin assigned to the switch 90 int circuit_type; // the type of circuit wired to the switch 91 bool switch_on_value; // used for BUTTON SWITCHES only - defines what "on" means, set up in setup() 92 bool switch_pending; // records if switch in transition or not 93 long unsigned int elapse_timer; // records debounce timer count when associated switch is in transition 94 bool switch_status; // used for TOGGLE SWITCHES only - current state of toggle switch. 95} switches[num_switches] = { 96 // Note order of preset entries not relevant, but keep in a tidy order 97 98 button_switch, button_switch_1, circuit_C1, LOW, false, 0, not_used, 99 button_switch, button_switch_2, circuit_C2, LOW, false, 0, not_used, 100 button_switch, button_switch_3, circuit_C1, LOW, false, 0, not_used, 101 102 toggle_switch, toggle_switch_1, circuit_C2, not_used, false, 0, !on, 103 toggle_switch, toggle_switch_2, circuit_C1, not_used, false, 0, !on, 104 toggle_switch, toggle_switch_3, circuit_C2, not_used, false, 0, !on 105 106}; 107// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 108 109void setup() { 110 // Initialise digital input switch pins 111 for (int sw = 0; sw < num_switches; sw++) { 112 // Define the switch circuit type - circuit_type is: 113 // circuit_C1 (INPUT) or circuit_C2 (INPUT_PULLUP) 114 pinMode(switches[sw].switch_pin, switches[sw].circuit_type); 115 // Establish 'meaning' for switch on/off for a button switch, depending on circuit type. 116 // This is used only by button read function, it has no relevance for toggle switches. 117 if (switches[sw].circuit_type == circuit_C2) { 118 // Switch is NOT configured with a pull down switch resistor 119 switches[sw].switch_on_value = LOW; // switch pin goes LOW when switch pressed, ie on 120 } else { 121 // Circuit_type_C1, so switch IS configured with a pull down switch resistor 122 switches[sw].switch_on_value = HIGH; // switch pin goes HIGH when switch pressed, ie on 123 } 124 } 125 Serial.begin(115200); // dont forget to set your serial monitor speed to whatever is set here 126} // end of setup 127 128void loop() { 129 // Poll each connected switch in turn and, if switched, process its associated purpose 130 for (int sw = 0; sw < num_switches; sw++) { 131 if (read_switch(sw) == switched) { 132 // This switch (sw) has been pressed, so process via a case switch 133 if (switches[sw].switch_type == button_switch) { 134 Serial.print("\ 135button switch on digital pin "); 136 } else { 137 Serial.print("\ 138toggle switch on digital pin "); 139 } 140 Serial.print(switches[sw].switch_pin); 141 Serial.println(" triggered"); 142 // Move to switch's associated code section 143 144 switch (switches[sw].switch_pin) 145 { 146 case button_switch_1: 147 Serial.println("case statement 1 entered"); 148 break; 149 case button_switch_2: 150 Serial.println("case statement 2 entered"); 151 break; 152 case button_switch_3: 153 Serial.println("case statement 3 entered"); 154 break; 155 case toggle_switch_1: 156 Serial.println("case statement 4 entered"); 157 Serial.print("switch is "); 158 Serial.println(switches[sw].switch_status); 159 break; 160 case toggle_switch_2: 161 Serial.println("case statement 5 entered"); 162 Serial.print("switch is "); 163 Serial.println(switches[sw].switch_status); 164 break; 165 case toggle_switch_3: 166 Serial.println("case statement 6 entered"); 167 Serial.print("switch is "); 168 Serial.println(switches[sw].switch_status); 169 break; 170 default: 171 // Spurious switch index! Should never arise as this is controlled 172 // by the for loop within defined upper bound 173 break; 174 } 175 Serial.flush(); // flush out the output buffer 176 } 177 } 178 // Pollng of the switches now complete until next cycle, so do other things here as required... 179 180 181 182} // end of main loop 183 184// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 185// Generic switch read function: 186// ''''''''''''''''''''''''''''' 187// Read the switch defined by the function parameter. 188// Function returns a value indicating if the switch 189// has undergone a transition or not. 190// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 191bool read_switch(int sw) { 192 if (switches[sw].switch_type == button_switch) { 193 return read_button_switch(sw); 194 } 195 return read_toggle_switch(sw); 196} // end of read_switch 197 198// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 199// Generic toggle switch read function: 200// ''''''''''''''''''''''''''''''''''' 201// Test the toggle switch to see if its status has changed since last look. 202// Note that, although, switch status is a returned value from the function, 203// the current status of the switch ('switches[sw].switch_status') is always 204// maintained and can be tested outside of the function at any point/time. 205// It will either have a switches[sw].switch_status of 'on' or '!on' (ie off). 206// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 207bool read_toggle_switch(int sw) { 208 int pin_value = digitalRead(switches[sw].switch_pin); // test current state of toggle pin 209 if (switches[sw].circuit_type == circuit_C2) { 210 // Need to invert HIGH/LOW if circuit design sets pin HIGH representing switch in off state 211 // ie inititialised as INPUT_PULLUP 212 pin_value = !pin_value; 213 } 214 if (pin_value != switches[sw].switch_status && !switches[sw].switch_pending) { 215 // Switch change detected so start debounce cycle 216 switches[sw].switch_pending = true; 217 switches[sw].elapse_timer = millis(); // set start of debounce timer 218 } else { 219 if (switches[sw].switch_pending) { 220 // We are in the switch transition cycle so check if debounce period has elapsed 221 if (millis() - switches[sw].elapse_timer >= debounce) { 222 // Debounce period elapse so assume switch has settled down after transition 223 switches[sw].switch_status = !switches[sw].switch_status; // flip status 224 switches[sw].switch_pending = false; // cease transition cycle 225 return switched; 226 } 227 } 228 } 229 return !switched; 230} // end of read_toggle_switch 231 232// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 233// Read button switch function: 234// '''''''''''''''''''''''''''' 235// Generic button switch read function. 236// Reading is controlled by: 237// a. the function parameter which indicates which switch 238// is to be polled, and 239// b. the switch control struct(ure), referenced by a). 240// 241// Note that this function works in a nonexclusive way 242// and incorporates debounce code. 243// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 244 245bool read_button_switch(int sw) { 246 int switch_pin_reading; 247 switch_pin_reading = digitalRead(switches[sw].switch_pin); 248 if (switch_pin_reading == switches[sw].switch_on_value) { 249 // Switch is pressed (ON), so start/restart debounce process 250 switches[sw].switch_pending = true; 251 switches[sw].elapse_timer = millis(); // start elapse timing 252 return !switched; // now waiting for debounce to conclude 253 } 254 if (switches[sw].switch_pending && switch_pin_reading == !switches[sw].switch_on_value) { 255 // Switch was pressed, now released (OFF), so check if debounce time elapsed 256 if (millis() - switches[sw].elapse_timer > debounce) { 257 // dounce time elapsed, so switch press cycle complete 258 switches[sw].switch_pending = false; 259 return switched; 260 } 261 } 262 return !switched; 263} // end of read_button_switch 264
Comments
Only logged in users can leave comments
ronbentley1
0 Followers
•0 Projects
Table of contents
Intro
1
0