# Missing pins

In this tutorial we cover the following topics

Although most of microcontrollers have many input/output pins, there are no problems to spend all of them and find yourselves in a situation when there would be no option to attach enything else. In this part we will show what we can do in case of such a situation. Other words, we will show how to "multiply" our pins.

The voltage divider

Recal voltage divider idea discussed in Voltage divider tutorial. General schema looks like it is showned on the following image

where the formula used to calculate $V_{out}$ takes a form
$$V_{out} = \frac{V_{in}R_{2}}{R_{1}+R_{2}}$$

$$V_{out} = \frac{V_{in}\cdot 0}{R_{1} + 0} = 0$$
$$V_{out} = \frac{V_{in}R_{2}}{R_{1}+R_{2}} = \frac{V_{in}R_{2_{1}}}{R_{1}+R_{2_{1}}} = \frac{V_{in}}{\frac{R_{1}}{R_{2_{1}}}+1}$$
$$V_{out} = \frac{V_{in}R_{2}}{R_{1}+R_{2}} = \frac{V_{in}(R_{2_{1}} + R_{2_{2}})}{R_{1}+R_{2_{1}}+R_{2_{2}}}= \frac{V_{in}}{\frac{R_{1}}{R_{2_{1}}+R_{2_{2}}}+1}$$
$$V_{out} = \frac{V_{in}R_{2}}{R_{1}+R_{2}} = \frac{V_{in}(R_{2_{1}} + R_{2_{2}} + R_{2_{3}})}{R_{1}+R_{2_{1}}+R_{2_{2}}+R_{2_{3}}}= \frac{V_{in}}{\frac{R_{1}}{R_{2_{1}}+R_{2_{2}}+R_{2_{3}}}+1}$$

Examples given in previous subsection show few similar but different dividers. We can combine all of them into on schema.

How it works is explained in a set of images below.

This way we have had created a variable voltage divider called a multiple voltage divider or more often a resistor ladder.

Step 1 -- real test

Now it's time to make a real test.

1. Create circuit given in the schema below
 Left: Schema of resistor ladder. Right: Close to real view of resistor ladder

2. Attach multimeter to our circuit
3. Use the following code to programm Arduino
4. Write down results: voltage displayed on multimeter and analog value readed by Arduino and changed into numerical values by analog-digital converter (ADC in short). In our case we got

 Switchpressed Resistance value of variabledivider part $R_{2}$(for constant $R_{1}=10kO$) Voltage used measured as integerfrom ADC converted to voltsfrom ADC value measured bymultimeter theoreticalvalue 1 0kO 0 0 0.0 0.00 2 $R_{2}$ = 1kO 0.98kO 95 0.46 0.47 3 $R_{2}+R_{2}$ = 1kO+1kO=2kO 1.97kO 180 0.89 0.83 4 $R_{2}+R_{2}+R_{2}$ = 1kO+1kO+1kO=3kO 2.95kO 238 1.16 1.16

This allows us to interprete each reading as a different button being pressed with a few lines of code -- see listing below. Obviously rather than telling the microcontroler to look for the exact values we expect the analog pin to read, we set a range of values that can be interpreted as belonging to a specific button. We do this by calculating the points halfway between each expected ADC reading and set these as as the boundaries of our ranges (see also image)

 Switch Range from to midpoint 1 0 95 47 2 95 180 137 3 180 238 209 4 238 1023 630

 Divide 0-5 voltage range into intervals

The downside is that this can only detect one button press at a time, the button with the lowest resistor value is returned, and the output varies when different voltages are used to power it requiring an update to our software.

Step 2 -- fixing resolution

So far, so good but this soltion has two drawbacks which makes it working only for a project with a small number of buttons.

1. Every time we change the number of buttons, we have to measure what have changed -- we have to measure ADC values for newly added button(s). Neext we have to update our source code.
2. What is worse, voltage resolution is not constant. The more buttons we have, the shortest voltage ranges we will have.
Adding another switches, each with a 1kO resistor, we obtain results presented in the table below. To make it more visible, also results for 21, 31 and 41 buttons obtained with 10kO resistors instead 10 times 1kO are included.

 Switch Range from to midpoint Midpointdistance 1 0 95 47 --- 2 95 180 137 90 3 180 238 209 66 4 238 294 266 57 5 294 342 318 52 6 342 384 363 45 7 384 424 404 41 8 424 458 441 37 9 458 491 474 33 10 491 518 504 30 11 518 21 682 31 766 41 816 1023 919

and depicted in the image

The situation could be even worse if we use 1kO pull-up resistor

 Switch Range from to midpoint Midpointdistance 1 15 518 266 --- 2 518 687 602 336 3 687 769 728 126 4 769 820 794 66 5 820 853 836 42 6 853 877 865 29 7 877 895 886 21 8 895 909 902 16 9 909 920 914 12 10 920 930 925 11 11 930 21 974 31 990 41 998 1023 1010

Variable and short voltage ranges may lead to errors both in code and in real devices as a result of noise and components tollerance. Anyway, magic numbers are always bad solution and should be avoided whenever possible. If we should somehow predict ADC value based on ADC resolution and number of buttons then we could implement better solution.

So, lets try find out resistors values to have equidistance measured in voltage, based on the following specification:

• $V_{in}=5V$,
• four buttons,
• pull-up resistor $R_{1}=1kO$,
• voltage distance $V_{d}=0.5$, e.g. $V_{S1}=0$ (voltage output for switch $S1$), $V_{S2}=V_{d}$ (voltage output for switch $S2$), $V_{S3}=2V_{d}$, $V_{S3}=3V_{d}$.

We know the input voltage, output voltage, and resistor $R_{1}$, but not $R_{2}$ which should be calculated. Starting from previously given formula
$$V_{out} = \frac{V_{in}R_{2}}{R_{1}+R_{2}}$$
rearranging its components
$$V_{out}(R_{1}+R_{2}) = V_{in}R_{2}$$
$$V_{out}R_{1}+V_{out}R_{2} = V_{in}R_{2}$$
$$V_{out}R_{1} = V_{in}R_{2}-V_{out}R_{2}$$
$$V_{out}R_{1} = R_{2}(V_{in}-V_{out})$$
we finaly obtain formula for missing resistance $R_{2}$
$$R_{2} = \frac{R_{1}V_{out}}{V_{in}-V_{out}}$$

Based on this formula and notation from the following schema we can calculate desired resistances

• Calculations for $R_{21}$ -- in this case $V_{out}$ should be equal to 0.5V
$$R_{2} = R_{21} = \frac{R_{1}\cdot V_{out}}{V_{in}-V_{out}} = \frac{1.0 \cdot 0.5}{5.0 - 0.5} = \frac{0.5}{4.5} = 0.11$$
To get resistance close to theoretical value of 0.11kO which is 110 Ohm, we will use one 100 Ohm resistor and one 10 Ohm so $R_{21}$ would be equal to 110 Ohm.
• Calculations for $R_{22}$ -- in this case $V_{out}$ should be equal to 1.0V
$$R_{2} = R_{21} + R_{22}$$
On the other hand we know that
$$R_{2} = \frac{R_{1}V_{out}}{V_{in}-V_{out}}$$
so in consequence
$$R_{21} + R_{22} = \frac{R_{1}V_{out}}{V_{in}-V_{out}}$$
and then
$$R_{22} = \frac{R_{1}V_{out}}{V_{in}-V_{out}} - R_{21}$$
$$R_{22} = \frac{1.0 \cdot 1.0}{5.0-1.0} - 0.11 = \frac{1}{4} - 0.11 = 0.25 - 0.11 = 0.14$$
To get resistance close to theoretical value of 0.14kO which is 140 Ohm, we will use one 150 Ohm resistor so $R_{21}$ would be equal to 150 Ohm.
• Calculations for $R_{23}$ -- in this case $V_{out}$ should be equal to 1.5V
$$R_{2} = R_{21} + R_{22} + R_{23}$$
On the other hand we know that
$$R_{2} = \frac{R_{1}V_{out}}{V_{in}-V_{out}}$$
so in consequence
$$R_{21} + R_{22} + R_{23} = \frac{R_{1}V_{out}}{V_{in}-V_{out}}$$
and then
$$R_{23} = \frac{R_{1}V_{out}}{V_{in}-V_{out}} - R_{21} - R_{22}$$
$$R_{23} = \frac{1.0 \cdot 1.5}{5.0-1.5} - 0.11 - 0.15 = \frac{1.5}{3.5} - 0.26 = 0.428 - 0.26 = 0.168$$
To get resistance close to theoretical value of 0.168kO which is 168 Ohm, we will use one 120 Ohm resistor and one 51 Ohm so $R_{23}$ would be equal to 171 Ohm.

Now we can implement more universal method for detecting the pin which was pressed

and measure real voltage and ADC values as it is presented in the table below

 Switchpressed Resistance value of variabledivider part $R_{2}$(for constant $R_{1}=1kO$) Resistancedistance Voltage used measured calculated used as integerfrom ADC converted to voltsfrom ADC value measured bymultimeter theoreticalvalue 0 --- --- --- --- 1023 5.00 4.95 5.00 1 0k$\Omega$ 0 0 0 0 0.0 0.02 0.0 2 $R_{21}$ = 110 $\Omega$ 113 $\Omega$ $R_{21}=111 \Omega$ $R_{21}=110 \Omega$ 100 0.5 0.51 0.5 3 $R_{21}+R_{22}$ = 260 $\Omega$ 260 $\Omega$ $R_{22}=140 \Omega$ $R_{22}=150 \Omega$ 208 1.0 1.04 1.0 4 $R_{21}+R_{22}+R_{23}$ = 431 $\Omega$ 430 $\Omega$ $R_{23}=168 \Omega$ $R_{23}=171 \Omega$ 306 1.5 1.51 1.5

Digital to analog converter

Resistor ladder is perfect for detecting which one (but only one) button of many is currently pressed. With this type of circuit we are unable to detect multiple button pressing. Conversely, we could say, that we can detect one of the following situations

but none of this (except five cases given above)

.
Notice that, treating every 1 as pressed button and 0 as released button, detecting multiple buttons pressing problem is equivalent to changing binary signals into analog. If we look closer to the table given above, we will conclude that all 4-bit combinations are includet in it. So we can reformulate our proble from the form considered so far: how to detect which buttons of a given set of buttons are pressed, to the following form how to convert digital number expressed by sequence of 0's and 1's to analog value. This topic is covered in ADC and DAC part of my tutorials.

Multiplexing

Multiplexing is the generic term used to describe the operation of sending one or more analogue or digital signals over a common transmission line at different times or speeds. The device we use to do that is called a multiplexer and demultiplexer. An electronic multiplexer (also mux or data selector) makes it possible for several signals to share one device or resource, for example, one A/D converter or one communication line, instead of having one device per input signal. It selects between several analog or digital input signals and forwards it to a single output line.

Generally, the selection of each input line in a multiplexer is controlled by an additional set of inputs called control lines and according to the binary condition of these control inputs, one appropriate data input is connected directly to the output. Normally, a multiplexer has an even number of $2^{n}$ input lines and a corresponding number of $n$ control inputs. An electronic multiplexer can be considered as a multiple-input, single-output switch. The schematic symbol for a multiplexer is an isosceles trapezoid with the longer parallel side containing the input pins and the short parallel side containing the output pin. The schematic below shows a 2-to-1 multiplexer (also denoted as 2:1 muliplexer or 2:1 mux) on the left and an equivalent switch on the right.

 Left: 2-to-1 multiplexer. Right: Switch equivalent to 2-to-1 multiplexer

Multiplexers can be either digital circuits made from high speed logic gates used to switch digital or binary data or they can be analogue types using transistors, MOSFET’s or relays to switch one of the voltage or current inputs through to a single output.

Creating a digital 2-to-1 multiplexer

To start out easy, we’ll create a multiplexer taking two inputs and a single selector line as it was depicted above. With inputs $X_{0}$ and $X_{1}$ and select line $S$, if $S$ is 0, the $X_{0}$ input will be the output $Y$. If S is 1, the $X_{1}$ will be the output $Y$.

The boolean formula for the 2-to-1 multiplexer looks like this (how to get it is given below after truth table)
$$Y= \overline{S} \cdot X_{0} + S \cdot X_{1}$$
or the same as programming logic expression

or in the pseudocode style

Here is what a truth table would look like for such a circuit

 $S$ $X_{0}$ $X_{1}$ $Y$ 0 0 0 0 0 0 1 0 0 1 0 1 0 1 1 1 1 0 0 0 1 0 1 1 1 1 0 0 1 1 1 1

\begin{align} Y = & \overline{S} \cdot X_0 \cdot \overline{X_1} + \overline{S} \cdot X_0 \cdot X_1 + S \cdot \overline{X_0} \cdot X_1 + S \cdot X_0 \cdot X_1 = \\ & \overline{S} \cdot X_0 \cdot (\overline{X_1} + X_1) + S \cdot X_1 \cdot (\overline{X_0} + X_0) = \\ & \overline{S} \cdot X_0 + S \cdot X_1\\ \end{align}
Based on the given above formulas, we can make a corresponding logic circuit

Of course it can be completed also with other set of gates, for example NAND gates. From the previous material, Completeness of NAND gate set, we know that using only NAND gates we can have equivalents of all three basic gates: AND, OR and NOT as it is showned again below.

Using these ,,replacemants'' to the schema with basic set of gates we obtain

This schema could be simplify. Let's introduce some additional symbols

Now we can write
$$Y = \overline{E \cdot F} = \overline{\overline{C \cdot C} \cdot \overline{D \cdot D}}$$
Because in Boolean algebra the following is true
$$X \cdot X = X$$
we can write
$$Y = \overline{\overline{C} \cdot \overline{D}} = \overline{\overline{\overline{A \cdot A}} \cdot \overline{\overline{B \cdot B}}}$$
Again from the law given above we obtain
$$Y = \overline{\overline{\overline{A}} \cdot \overline{\overline{B}}}$$
and applying the following rule
$$\overline{\overline{X}} = X$$
we finally get
$$Y = \overline{A \cdot B}$$
Other words, none of the gate with output $C$, $D$, $E$ or $F$ is needed, so final chema od multiplexer build only with NAND gates looks like below

Creating a digital 4-to-1 multiplexer

We can combine two lower order multiplexers like 2:1 or 4:1 to get higher order multiplexer like 8:1. Now, for example let us try to implement a 4:1 multiplexer using a 2:1 multiplexer. To construct a 4:1 multiplexer using a 2:1 multiplexer, we will have to combine three 2:1 multiplexer together. As it is showned on the image below

The end result should give us 4 input pins ($X_{0}$, $X_{1}$, $X_{2}$ and $X_{3}$), 2 control/select pins ($S_{0}$ and $S_{1}$) and one output pin ($Y$).

Digital demultiplexer

Conversely to multiplexer, a demultiplexer (or demux) and pass through to one of multiple output lines, using a select line to choose which output the input goes to.

The boolean formula for the 1-to-2 demultiplexer looks like this
$$Y_{0}= \overline{S} \cdot X$$
$$Y_{1}= S \cdot X$$
or the same as programming logic expression

or in the pseudocode style

Here is what a truth table would look like for such a circuit

 $S$ $X$ $Y_{0}$ $Y_{1}$ 0 0 0 0 0 1 1 0 1 0 0 0 1 1 0 1

Based on the given above formulas, we can make a corresponding logic circuit

Of course it can be completed also with other set of gates, for example NAND gates

There are a lot of different ready to use (de)multiplexer.

• The basic trio of analog multiplexers stems from the venerable 4000-series CMOS logic chips: the 4051 is a single eight-way multiplexer, the 4052 has two four-way multiplexers, and the 4053 has three two-way switches.
• The 74HC405x series chips with higher switching speed or low-voltage analog multiplexers meant for battery-powered use: 74LV405x.
• The high-speed and low-resistance 3251, 3252, and 3253 series chips: CBT3251, FST3252, SN74CBT3253, etc.

In most cases multiplexer can work also as a demultiplexer, so further we will use the term multiplexer in both meanings.

4051, 4052, 4053 family

4051

In this part we will show how to work with CD4051B and CD4052B chip (CD4051B, CD4052B, CD4053B datasheet ).

CD4051 is an eight (8) channel multiplexer and has three control input named as A, B and C. These inputs connect only 1 out of 8 channels to the output in order to obtain the desired output. Channel I/O terminals became outputs and common O/I become input terminals when CD 4051 is used as a demultiplexer. Pinous for all chips from this family are depicted on the image below and for CD4051 chip is summarized in the following table

 Left: Pinouts of 4051 chip. Middle: Pinouts of 4052 chip. Right: Pinouts of 4053 chip.
 Pin Meaning A selector line coding first bit of binary channel number B selector line coding second bit of binary channel number C selector line coding third bit of binary channel number 0-7 independent inputs/outputs channels Vee negative supply voltage (connected to ground (GND) in our case) Vss ground (GND, 0V) Vdd positive supply voltage (from 5 to 20 volts) COM AUT/IN common input/output INH enable input active on LOW (connected to ground (GND) in our case)

We start with very basic and unusual example and show how multiplexer can be used as a static hardware switch.

 Left: Basic schema to test CD4051 chip. Right: Close to real view of a circuit schema given on the right.

Let's improve static hardware channel selection case and turn it into static software channel selection example. We show a very basic application accompanied by a very simple code. Connect all the components according to the schema given bellow

 Left: Basic schema to test CD4051 chip. Right: Close to real view of a circuit schema given on the right.

and use the following code.

Now we are going to extend our example: instead of "statically" defined channel we will "scan" the whole range of them. For this purpose we add four switches

 Left: Basic schema to test CD4051 chip. Right: Close to real view of a circuit schema given on the right.

The crucial part of the code designed to work with multiplexer is channel selection function. It doesn't matter if we use it as a multiplexer or demultiplexer, channels are selected the same way. To manipulate bits we can use standard binary operation as well as bitRead() function.

Our goal is to read state of one of many switches (in example we will use 4 switches) using only one input. This will work for one button at the time pressed, and also for multipress combination of buttons.

Inside a loop we select one channel in order 4, 5, 6, 7. This way selected channel is connected to COM OUT/IN pin of 4051 (pin number 3). Our switches are connected to pin corresponding to channels 4, 5, 6, 7. If we press one of them, say switch of channel 5, then digitalRead() will return 1 only when channel 5 is looped as only for this channel we will read HIGH state. This will set switchState for this channel to be high, while rest of channels will be set to LOW. This way, as long as we we keep given switch pressed we should get HIGH state for corresponding channel.

Let's stop for a while and try to understand how it works. We use only "left part" - the one with switches; part with leds is unused.

Inside a loop we select one channel in order 4, 5, 6, 7. This way selected channel is connected to COM OUT/IN pin of 4051 (pin number 3). Our switches are connected to pin corresponding to channels 4, 5, 6, 7. If we press one of them, say switch of channel 5, then digitalRead() will return 1 only when channel 5 is looped as only for this channel we will read HIGH state. This will set switchState for this channel to be high, while rest of channels will be set to LOW. This way, as long as we we keep given switch pressed we should get HIGH state for corresponding channel. This should work also if we press more than one button.

Finally, let's try to have multiple inputs and multiple output. We will try to keep ability to read multiple buttons and in the same time power multiple LEDs. Use the following code to test if it is possible to power all four LEDs at the same time.

Expanders