Connecting a switch(es) in an energy efficient way

How to connect a handful of switches – actually approx. 20 to Arduino Mega in an energy efficient way?

Some of the switches will be momentary ones some of them will be flip-switches (i.e. staying permanently closed or open until flipped again).

Specifically – I’m NOT looking for some CD74HC4067 multiplexer nor am I in the market for advice how to connect multiple (usually 4) switches to one analog pin and distinguish between them via different resistor value connected to each.

I want to have each switch a digital pin of their own. It is clear I must use pull-down or a pull-up resistor and that can be either internal or external one.

Some of the flip-switches will most likely be for most of the time closed while other opened throughout the lifetime of the project. The momentary ones (just as their name suggests) will be closed only from time to time for fragments of seconds.

Now how to connect them properly to be as nice to Arduino as possible (not to stress it unnecessarily)? It most probably folds down to being energy-efficient i.e. to draw as small current as possible in overall.

E.g. pull-up resistor for momentary switches and flip-switches expected to be open most of the time and pull-down for the flip-switches expected to be closed most of the time? Or it does not matter? And external or internal or again it does not matter?

If I get the concept right, then a connection through a pull-up resistor (say 10k for a start) will bring 5V to the Arduino’s pin when the switch is open but the current – thanks to a high value of the resistor – will be very very small one. When pushed (closed) the circuit is shorted, and the PIN reads LOW.

If I follow the logic right further on – to answer one of my questions – it does not matter whether pull-up or pull-down is used – the current goes anyhow either to the pin or to the ground (and vice versa) and the fact that the current consumed is minimal is delivered by a relatively high value of the resistor.

However: I intend to connect quite a lot of switches and a hundred times nothing killed the donkey. And some of the switches will be connected over longer wires (10-20 meter) so forums suggest (esp. in electrically noisy environment) to use smaller value of the resistor to cut out the noise.

BTW, if e.g. pull-up resistor is used, and switch is open – 5V is brought to the digital pin. Does the small current flow all the time or only when pin is tested (read)?

Sorry for this novice question – but many posts look at how to properly connect one switch. Connecting a bunch of them in an energy efficient way is a name of the game for today.

In view of the long wires to the switches, you will simply have to experiment with the value of the pullup/pulldown resistor.

Use the highest value that results in no false switching from environmental electrical noise. It helps a great deal to use shielded, twisted pair wiring.

Just connect and use the internal (30K to 50K pullups).
Even the remote ones; they are not switching at high speeds, and unless your wire is really high resistance, the chip will read a low properly. Add a 10K pullup if you see any erratic behavior.

The small current is only 1uA when high, and thru the internal pullup will be 5V/30K = .17mA, having 20 low is only 3.3mA, that is not stressing anything.

CrossRoads:
Add a 10K pullup if you see any erratic behavior.

And/or use a 10-100n ceramic capacitor from pin to ground (close to the Arduino).
That kill all sorts of RF noise that could trigger the pin.
Leo..

I did see a nice diagram once about efficient switching but I cannot find it again.
But this post on another forum
https://www.avrfreaks.net/forum/multiplex-several-switches-one-external-interrupt
and diagram

Gives the same idea.

Basically the buttons are connected to an interrupt pin and a digital Read pin.
Thus the Arduino could be put to sleep and be efficient on power.
The Interrupt would wake the Arduino and trigger the reading of the input pins to find which button was pressed.
Not sure how that would work with flip switches

Interrupt pin? Puhleeze, that’s a really, really bad idea. For many reasons.

Could also turn pull up on with code just before reading the pin, and turn off after that.
That, and sleeping a Mega, seems a bit silly though.
Leo..

Silly is the OP insisting the solution use 20 wires and a Mega and then ask about energy efficiency.

Sort of like asking people to do their best work with one arm behind their back and both eyes closed, right? Right?

Zed42:
E.g. pull-up resistor for momentary switches and flip-switches expected to be open most of the time and pull-down for the flip-switches expected to be closed most of the time? Or it does not matter? And external or internal or again it does not matter?

It reads as if you think there are internal pullUPs and pullDOWNs; only pullUPs are available internally.

WattsThat:
Interrupt pin? Puhleeze, that’s a really, really bad idea. For many reasons.

That's a pretty common design for things like TV remotes where energy efficiency is extremely important. A small battery can last several years sitting on the couch if the processor is shut down almost all the time and only wakes up when an interrupt pin is triggered.

Zed42:
Now how to connect them properly to be as nice to Arduino as possible (not to stress it unnecessarily)? It most probably folds down to being energy-efficient i.e. to draw as small current as possible in overall.

There is no such thing as "nice" for an Arduino. It doesn't care if you ask "Is the button pushed yet?" ten thousand times per second for ten years. (That's a number with twelve zeroes in it.)

You didn't specify your power source. If it's anything bigger than a pair of AAA batteries, then the power consumption of your pullups is immaterial.

WattsThat:
Interrupt pin? Puhleeze, that’s a really, really bad idea. For many reasons.

Please do elaborate?

Because the reference manual attachInterrupt() - Arduino Reference says "Interrupts are useful for making things happen automatically in microcontroller programs, and can help solve timing problems. Good tasks for using an interrupt may include reading a rotary encoder, or monitoring user input."

As this is monitoring user input it seems ideal for using interrupts according to the manual

Mechanical switches bounce - sometimes 100's of times - you get an arbitrary number of interrupts,
not just one, when the switch changes.

Typically you want to reserve interrupts for tasks than need immediate(*) servicing. User input is on timescales
of 10ms or more, for which polling is adequate, and can help with the debouncing (you get debouncing
for free if you poll user inputs every 20ms or so).

Unless you need to wake the processor from a sleep state, interrupts are rather a sledgehammer to
crack a nut for user input. Many switches can just be polled when needed anyway.

Once you start using interrupts you can end up with incompatibilities with libraries that do need interrupt
handling - so that's another point against.

(*) immediate means microseconds rather than human timescales. 3 to 5 orders of magnitude faster than
human response times typically.

MarkT:
Unless you need to wake the processor from a sleep state.

As the request was for efficiency and the suggestion of interrupts was so that user interaction did wake the processor from a low power sleep state then I still feel it was a valid suggestion.

But I understand while there are benefits of interrupts on power consumption there are also drawbacks, one of the biggest in this case is the hardware being used probably does not have enough interrupt capable pins as they are a limited resource to handle all the toggle switches individually.

Thanks to all great inputs/advice.

To better explain the purpose of the inquiry: I don't seek "energy efficiency" due to an intention to power the project from a battery (i.e. not to extend the off-grid life). Vice versa - I plan to power the Arduino Mega through VIN pin with switched source (have acquired MEAN WELL LRS-100-12 = 12V/8,5A, 90W for that purpose).

However there will be quite some input peripherals - besides of switches also 5pcs of inductive proximity sensors, rotary encoder (200 ticks per rotation - this one to be connected via interrupt pin) and some other. And also some outputs - approx. 16 pcs of relay modules for instance.

Nearly all pins of the Arduino Mega shall be depleted despite using CD74HC4067 multiplexer for some of the static switches. I'm OK with programming this however practicalities of electric circuit and its implications are my weak spot. So the implication of the length of cables (approx. 15 meters now) is one. And secondly - while googling for advice I came across a warning that relay modules draw quite some energy => concern about reducing impact of all other elements down as much as possible so I don't "overload" the Arduino.

I want to have some of the switches connected directly (through individual pins) since another concern is Arduino's computing power - will it refresh through the loop function fast enough (with all the processing of the inputs) to give decent user experience on pushing the buttons (i.e. so that the push won't pass by undetected).

So the once concern that led me to starting this thread was an impact of "permanently on" switches and general conclusion I take from the thread is that with a proper pull-up resistor in the path the impact of the el. current consumption is negligible and I should experiment with the of the pull-up in case of erratic behavior due to cable lengths.

In the meantime I hope to have solved the relay riddle too - the array of 16 relays I've acquired has an external power connector too - so it will be powered directly from the power source and not via Arduino (or so I hope).

CrossRoads:
Just connect and use the internal (30K to 50K pullups).
Even the remote ones; they are not switching at high speeds, and unless your wire is really high resistance, the chip will read a low properly. Add a 10K pullup if you see any erratic behavior.

That I don't quite get - other posts suggest that in case of meeting any erratic behavior I should rather decrease the value of the external pull up from 10K down to e.g. 4K. You suggest adding an external 10K one on top of the internals - i.e. increasing it. Or?

Thank you very much for the original answer already - no intention to be ungrateful - just trying to understand.

BTW, I plan using regular UTP Ethernet cable for provisioning the remote connectivity (unless it's a bad idea?)

Two resostors in parallel gives a lower resistance. This may also be called a "stronger" pullup.

The internal pullups are closer to 100k than 10k.