Reading the state of DIP-switches via 4017. Something escapes me...

Thread Starter

CesareBrizio

Joined Dec 16, 2018
10
Dear all,
I am an amateur who tries to do things with Arduinos and breadboards, without any background in electronics.
I apologize for a question that shows my incompetence as well as my arrogance - I engage in projects that I deem easy but obviously are not in my grasp.

To make things worse, my English leaves much to desire... :)

I'm using Arduino with three 4017 IC to scan sequentially three packages of 4-bit DIP switches.

The small program running on Arduino is aimed at understanding which switches are in the "ON" position and which are in the "OFF" position. To that purpose, I use a common "output" line for all the DIP packages (that engage the bottom blue line of the breadboard). By closing the switches according to my needs, then applying power to one switch at a time thanks to the 4017, I should read a zero voltage every time I "poll" an open switch, and a non-zero voltage for every switch closed.

Attached please find the circuit.

The circuit works almost as expected, but two things puzzle me.

1) As soon as I close switch 4 in the first (leftmost) or in the last (rightmost) 4-switches DIP package, I begin to get random readings in all the values (the reading of every switch, also those driven by the other 4017's - including the open ones! - is different from zero and apparently randomic).
But this undesirable effect does not show when I close switch 4 on bank 2 (see photo of the board and a screenshot of correct serial output, showing the sequential readings from left to right that I get with the configuration shown in the picture).
It's not a matter of a defect in the DIP switch package, I substituted the DIP switches with as many dupont cables, and the error persists. I'm almost sure that there is something very obvious that escapes me, please accept my apologies for asking you to state the obvious.

2) (Very obviously), even though I power each 4017 individually, the more switches I close (ON position), the lower voltage I read. This tension drop is a consequence of the number of "rivulets" that I open by closing each switch. I wonder which is the easiest way to get an higher tension that would make open/close discrimination safer (currently I think that a threshold of "above 10/1024th" may be taken as "switch closed" and any analog reading below 10 as "switch open"). By "the easiest way" I mean the simplest breadboardable circuit, with the fewest components.

Thanks for your help and again, excuse my clumsiness.

Cesare Brizio
(Email address removed by moderator per current policy.)
 

Attachments

Last edited by a moderator:

dl324

Joined Mar 30, 2015
10,003
Welcome to AAC!

I don't see how the circuit could possibly work. Any switch being closed would give you a HIGH reading on A0.

Could you post a schematic so we don't have to create one from your wiring diagram?

EDIT: After taking a closer look, the circuit can't work. Since only one output from a CD4017 can be HIGH, having multiple switches closed would short outputs that are HIGH to outputs that are LOW. If you're only going to use one Arduino input, you're going to need multiplexer to select the CD4017 output you want to read.
 
Last edited:

dl324

Joined Mar 30, 2015
10,003
This is what I transcribed for a third of what you have wired from the fritzing cartoon:
upload_2018-12-16_7-39-16.png
I got the actual connection to the 4th switch from the breadboard photo. It was wrong in fritzing. The LEDs also look backwards in fritzing; the leadframe bowl is typically the cathode.
 

JohnInTX

Joined Jun 26, 2012
3,976
Since you're reading the switches using a parallel to serial operation, why not use a shift register like the CD4021B or similar? Switches connect to the parallel latch inputs. Strobe the Parallel/Serial control pin to latch the current switch settings then clock it to shift out the stored switch image. Uses the same number of uC pins that @dl324 shows.
 

Attachments

LesJones

Joined Jan 8, 2017
2,501
There is a flaw in the the design. If more than one switch is closed the selected switch will be trying to pull the switch common high but any other switc that was closed would be trying to pull the switch common low. You need a diode between each output of the 4017 and the switch with the cathode end connected to the switch.

Les.
 

Thread Starter

CesareBrizio

Joined Dec 16, 2018
10
Hi Dennis and thanks for your interest.

I'm very ashamed but I don't know how to create a schematic. I tried with Fritzing, attached is what I obtained.

I do in fact want that any switch being closed gives me an high reading on A0. Yet, as long as (at least in my intentions), I am powering just one switch at a time, I am sequentially reading from left to right 12 switches.
The circuit works as expected, except when I close the fourth and the twelfth switch. Just at that moment, all hell breaks loose! :)
 

Attachments

Thread Starter

CesareBrizio

Joined Dec 16, 2018
10
Thanks Les!
It's most probably the basic point that I have been missing.
Out of curiosity, how come that all the 10 closed switches combinations switches work OK, as fas as I do not close the 4th and the 12th switch, while just when I close the 4th and the 12th the problem becomes apparent??
Again thank you!

There is a flaw in the the design. If more than one switch is closed the selected switch will be trying to pull the switch common high but any other switc that was closed would be trying to pull the switch common low. You need a diode between each output of the 4017 and the switch with the cathode end connected to the switch.

Les.
 

Thread Starter

CesareBrizio

Joined Dec 16, 2018
10
Thanks JohnInTX, I'll consider refactoring the ccircuit with tha IC that you suggested.
All the best,
Cesare
Since you're reading the switches using a parallel to serial operation, why not use a shift register like the CD4021B or similar? Switches connect to the parallel latch inputs. Strobe the Parallel/Serial control pin to latch the current switch settings then clock it to shift out the stored switch image. Uses the same number of uC pins that @dl324 shows.
 

dl324

Joined Mar 30, 2015
10,003
I'm very ashamed but I don't know how to create a schematic.
You can learn by emulating others.

Well drawn schematics convey the objective of the circuit, not how components are wired. Any schematic that uses pinout order almost guarantees a schematic being difficult to read/comprehend.

In schematics, the customary "flow" is left to right and top to bottom. There are cases where it's more convenient to not follow convention, but those are exceptions to the norm. To accomplish this, symbols for functional blocks tend to have inputs on the left and outputs on the right. Again, there are always exceptions.

This is one option for your circuit. Note that instead of drawing the Arduino on the schematic, I opted to use named inputs and outputs.
upload_2018-12-16_8-52-1.png
Note how there are no wire crossings. We also prefer for wires to be drawn with angles being a multiple of 90 degrees.
 

Thread Starter

CesareBrizio

Joined Dec 16, 2018
10
Thanks, Dennis! Great job!
I'll try to follow your indication for future posts of mine.
Now that you have so clearly represented my circuit, can you see any reason why the 4th and the 12th switch may cause the problem that I described?
I surely intend to adopt the solutions that were suggested, but I can't understand why just two very specific switches may cause the problem, while the other 10 can be set on or off without observing the unexpected behavior.
 

LesJones

Joined Jan 8, 2017
2,501
I don't know why it behaves as you describe. I suggest monitoring the voltage on the switch common and step the program to make just one of the 4017 outputs at a time and note the voltage. It should allways be very close to zero or very close to 5 volts. If you have more than one switch closed I think you will get a reading that is not close to thaise two values. In the first picture of your breadboard you are using outputs 1,2,3,4 In the second picture of your breadboard and schematic you are using outputs 1,2,3,8 Why is this ?

Les.
 

dl324

Joined Mar 30, 2015
10,003
I'll consider refactoring the ccircuit with tha IC that you suggested.
Before you work on implementation details, you should first determine why you want to read switch state.

Shift registers are one possible implementation. Another is to use multiplexers.

With shift registers, you can't access a particular switch directly. With multiplexers, you can.
 

dl324

Joined Mar 30, 2015
10,003
Now that you have so clearly represented my circuit, can you see any reason why the 4th and the 12th switch may cause the problem that I described?
The voltage that you read at A0 depends on the state of the outputs connected to the switches that are closed. If both outputs were HIGH, you'd read something near 5V. If both outputs were LOW, you'd read something near 0V. If one output was HIGH and one output was LOW, the output would likely be somewhere between 0-5V.

If your intention is to have a circuit that allows you to monitor the states of 12 independent switches, you need a different circuit.
 

ebp

Joined Feb 8, 2018
2,332
This is a common problem when trying to "scan" switches. Often switches are arranged as an array as in a keyboard (say 4 rows and 3 columns), but the problems are much the same.

The problem here, as has been mentioned, is that any switch that is closed and connects a LOW output from the counter to the sensing line will be in conflict with a switch that is closed and is trying to put a HIGH on the sensing line.

There are at least two ways to cope with this while keeping the same basic circuit, but both require additional parts.
One way is to add a diode at each switch, anode to the 4017 output and cathode to the switch. That way an output can only "source" current ("conventional current" is considered to flow from positive to negative, so the output is supplying or "sourcing" the current from the ICs positive power supply pin to the resistor that is connected to ground). Outputs that are LOW cannot pull the sense line low. The "forward voltage" of a diode makes a compromise in the voltage level for HIGH, but it should be workable with CMOS at 5 volts. I might cause a problem if you were trying to operate at 3 volts.
Another way is to add an "open drain" inverter to each counter output. An open drain output can only "sink" current - allow conventional current to flow into the output from some positive source. This of course requires that the sense line is pulled high with a resistor and the output of the inverter, when its input is HIGH, will pull the sense line LOW without interference from the other outputs.
Both of these methods require quite a lot of parts since you need one diode or one inverter (you can get 6 in one IC) per switch.

Because of the complexity, it might be better to use a different method such as the parallel-in-serial-out ("PISO") shift register that has been suggested. Another alternative is to use a binary counter and an open-drain (or "open-source") decoder. With this method, you would likely need three ICs - an 8 bit binary counter and two 3-to-8 line decoders arranged as a 4-to-16 decoder. There are some 4-to-16 decoders in one IC, but it will be a big 24 pin package.
 

Thread Starter

CesareBrizio

Joined Dec 16, 2018
10
Thanks Dennis, it was a mistake that I overlooked and that now I have corrected in my Fritzing drawing.
Best,
Cesare
This is what I transcribed for a third of what you have wired from the fritzing cartoon:
View attachment 165906
I got the actual connection to the 4th switch from the breadboard photo. It was wrong in fritzing. The LEDs also look backwards in fritzing; the leadframe bowl is typically the cathode.
 

Thread Starter

CesareBrizio

Joined Dec 16, 2018
10
Thanks ebp,
I'm beginning to grasp the mistake, even though it's counter-intuitive that just those very specific two switches cause the mess, that would have gone unnoticed unless I engaged the 4th and the 12th.
I consider the problem solved.
Among the solution that were suggested an that you summarized, for now I'll probably stick to the one-diode-per-switch approach, that will allow me to complete the prototype with just a simple modification.
As soon as my "quick and dirty" prototype works, I'll consider the more effective but more complex alternatives, such as adding other IC's.
Best,
Cesare

This is a common problem when trying to "scan" switches. Often switches are arranged as an array as in a keyboard (say 4 rows and 3 columns), but the problems are much the same.

The problem here, as has been mentioned, is that any switch that is closed and connects a LOW output from the counter to the sensing line will be in conflict with a switch that is closed and is trying to put a HIGH on the sensing line.

There are at least two ways to cope with this while keeping the same basic circuit, but both require additional parts.
One way is to add a diode at each switch, anode to the 4017 output and cathode to the switch. That way an output can only "source" current ("conventional current" is considered to flow from positive to negative, so the output is supplying or "sourcing" the current from the ICs positive power supply pin to the resistor that is connected to ground). Outputs that are LOW cannot pull the sense line low. The "forward voltage" of a diode makes a compromise in the voltage level for HIGH, but it should be workable with CMOS at 5 volts. I might cause a problem if you were trying to operate at 3 volts.
Another way is to add an "open drain" inverter to each counter output. An open drain output can only "sink" current - allow conventional current to flow into the output from some positive source. This of course requires that the sense line is pulled high with a resistor and the output of the inverter, when its input is HIGH, will pull the sense line LOW without interference from the other outputs.
Both of these methods require quite a lot of parts since you need one diode or one inverter (you can get 6 in one IC) per switch.

Because of the complexity, it might be better to use a different method such as the parallel-in-serial-out ("PISO") shift register that has been suggested. Another alternative is to use a binary counter and an open-drain (or "open-source") decoder. With this method, you would likely need three ICs - an 8 bit binary counter and two 3-to-8 line decoders arranged as a 4-to-16 decoder. There are some 4-to-16 decoders in one IC, but it will be a big 24 pin package.
 

LesJones

Joined Jan 8, 2017
2,501
I have only just realised that you are using an analogue input. What value in your table represents 5 volts on the switch common (Analogue input.) ? Once you have it working with the analogue input you could change to using a digital input. That would make the program simpler.

Les.
 

Thread Starter

CesareBrizio

Joined Dec 16, 2018
10
Thanks Les,
unfortunately there was a discrepancy between the real breadboard and the Fritzing schema, that fortunately Dennis brought to my attention.
the output of each 4017 that I'm sequentially reading are in fact 2,4,7,10 as per the correct schematic by Dennis, and they are connected to switches 1-4 in each package of 4.

It's now clear that my circuit needs some serious refactoring, and I'll purchase some diodes to see whetheer or not they solve the problem, before resorting to other solutions requiring more IC's and a more intricate breadboard cabling.

About the voltage: with one or few switches closed, it's very close 5V (readings around 1000), and it drops geometrically with the number of closed switches. With 6 switches closed (as per my 1st post, photo + "serial monitor" picture), readings are of just around (5/1023)*50 = 0.25V.


I don't know why it behaves as you describe. I suggest monitoring the voltage on the switch common and step the program to make just one of the 4017 outputs at a time and note the voltage. It should allways be very close to zero or very close to 5 volts. If you have more than one switch closed I think you will get a reading that is not close to thaise two values. In the first picture of your breadboard you are using outputs 1,2,3,4 In the second picture of your breadboard and schematic you are using outputs 1,2,3,8 Why is this ?

Les.
 

dl324

Joined Mar 30, 2015
10,003
Here's a circuit that will read the states of 16 switches directly using 4 address lines (D0-3), and one Arduino input:
upload_2018-12-16_9-46-50.png
When D3 (MSB) is LOW, you can directly address the states of the switches in S1 and S2. When D3 is HIGH, you access switches in S3 and S4.

When the CD4051 analog multiplexers are inhibited with a logic HIGH, the outputs float, so the outputs of the two multiplexers can be wire OR-ed.

EDIT: I just noticed that the CD4051 symbol doesn't show the VEE connection (pin 7). It would be connected to GND (pin 8) in this case.
 
Last edited:

Thread Starter

CesareBrizio

Joined Dec 16, 2018
10
Well said, Les!
Unfortunately, there are some limitations on the way digital HIGH or LOW readings can be obtained, from the point of view of coding & breadboard complexity I opted for an analog reading. Yet, you are very right in stating that using digital I/O I could have written a much shorter program!
Best, Cesare

I have only just realised that you are using an analogue input. What value in your table represents 5 volts on the switch common (Analogue input.) ? Once you have it working with the analogue input you could change to using a digital input. That would make the program simpler.

Les.
 
Top