Experiment 3: Analogue to Digital Conversion

Authors
Affiliation

Dr Timothy Davies

Department of Electronic and Electrical Engineering

Dr Chris P. Jobling

Department of Electronic and Electrical Engineering

Published

October 25, 2024

Analogue to Digital Conversion

It has been said many times that we live in a digital world. This is not true! We live in an analogue world, filled with voltages, currents, temperatures, pressures – all quantities which vary continuously and can be measured with great accuracy. The digital world wants everything neat and tidy, on or off, hot or cold, zero or one: which is not necessarily compatible with the analogue world. In order to access analogue information in a digital system, an Analogue to Digital Converter (ADC) is needed.

Analogue to Digital Conversion.
Figure 23.1: Analogue to Digital Conversion

The transfer characteristic of a 10-bit ADC is shown in the Figure 23.1 above. Let us suppose that the analogue input voltage, Vin, can be anywhere between zero Volts and Vref. As \(V_\mathrm{in}\) increases, the binary output varies from all zeros when \(V_\mathrm{in} = 0\), and all ones when \(V_\mathrm{in} = V_\mathrm{ref}\).

Now, the previous statement is only 99.9% true, as will be explained. Suppose \(V_\mathrm{ref} = 5\) V. Then each step shown on the graph above, is equivalent to \((5\,\mathrm{V} / 1024)\) which is (nearly) 5 mV. So the maximum voltage that can be measured is not, strictly, \(V_\mathrm{ref}\), it is \(V_\mathrm{ref}\) minus one step! In our example, that will be \((5\,\mathrm{V} - 5 \mathrm{mV})\) which is a tiny fraction over 4.995 V.

The primary characteristic of an ADC is this figure N, the number of bits. It tells us the RESOLUTION of the ADC. Another important characteristic is the conversion time, which determines how many conversions can be performed per second.

Some examples of ADCs. Suppose we want an ADC to convert high quality digital audio signals. Then the minimum value of N would be 16, in order to give an acceptable resolution. With N = 16, there will be 216 steps on the conversion graph, which is 65,536. The conversion speed is related to the audio bandwidth required. Most computers and tablets use ADCs which give 48,000 samples per second, which is \(22\,\mu\mathrm{s}\) per conversion. This is a high specification, as it is necessary in order to produce clean digitised audio with a high bandwidth.

That was the “Rolls-Royce” ADC. Suppose we need an ADC capable of digitising audio for a telephone line. The bandwidth of the audio signal on telephone lines is typically 3.5 kHz, and the internationally agreed conversion speed is 8000 conversions per second, corresponding to 125 us per conversion. The resolution need only be 8 bits to give acceptable telephone quality, corresponding to 28 = 256 steps. So the ADC needed for telephone quality has a much lower specification than the one for high quality digital audio. We shall not extend the metaphor of the make of motor car, in case of legal action.

The ADC inputs on our Arduino Nano are 10 bits resolution and can be sampled at a maximum of about 10 kHz, so they easily meet the specification for telephone lines on speed and resolution but are a bit short of the resolution and speed for high quality audio.

Reading an Analogue Input

The Analogue to Digital Converter on the Arduino Nano has six inputs which are shared with other functions, and two inputs which are exclusively analogue inputs. The command to read from an analogue input is of the form analogRead(), where the brackets contain an expression which specifies the analogue input. Note that the hardware only permits one conversion at a time, so if we want to read the value from all eight inputs this will require eight separate analogRead() instructions. This can be an issue if we need to read several voltages simultaneously, which requires additional hardware external to the Arduino Nano.

If you look in Listing 23.1, you will find a simple program which repeatedly reads from analogue input 6 (A6) and displays the value on the LEDs. The source of the voltage to be measured is from a potentiometer, which is a resistor with a moving contact which can be used to give a fraction of the voltage across the ends. As the wheel on the potentiometer is rotated, the fraction of the voltage varies from zero to 100%.

There is a slight problem. There are only six LEDs connected to Port C, which gives a maximum number of \((2^6 - 1) = 63\). However, the number read from the ADC has a maximum value of \((2^{10} - 1) = 1023\). So, as a “cheat”, the value of analogRead() is divided by 16 so that it fits!

Modify the plug-in breadboard by adding the supplied potentiometer and connecting it as shown in Figure 23.2, using wire links cut from the supplied single-core cable using the wire cutter and stripper. Don’t forget to wear eye protection when cutting the wires!

Circuit layout for Experiment 3.
Figure 23.2: Circuit layout for Experiment 3.

Create an Arduino sketch in the usual way and copy the code from Listing 23.1 into it. Compile and download the code. When the programme is running, turn the potentiometer slowly. You will see the LEDs light up in a binary sequence, so that no LEDs are illuminated when the wheel is fully anticlockwise, and all the LEDs are illuminated when the wheel is fully clockwise. Try and find a position where the LEDs change over from 011111 (31 decimal) to 100000 (32 decimal). This should be exactly half-way between the extreme positions.

Bar Graph Display

The next demonstration program is of a bar graph display. Instead of illuminating in a binary sequence, the LEDs light progressively from one end to the other in the same way as the volume indicator on digital record and playback equipment. The number from the ADC has a maximum value of 1023, and there are only six LEDs. So the number from the ADC must be scaled. Let us pretend that 1024/6 = 170.

ADC = 0; no LEDs lit.

ADC = 1 to 170: one LED lit.

ADC = 171 to 341: two LEDs lit.

ADC = 342 to 512: three LEDs lit.

ADC = 513 to 683: four LEDs lit.

ADC = 684 to 853: five LEDs lit.

ADC = 854 to 1023: six LEDs lit.

How are we to implement this set of decisions in code? One solution would be to use a series of if() statements, however some slight additions are needed. We actually need anif() … else statement, so that only one of the conditions causes a write to the LEDs. If you look at the program in Listing 23.2, you will see that it begins its tests with the highest threshold and progresses down in steps of 170 until zero.

A flow-chart of this decision tree which is inside the loop subprocess in Listing 23.2 is given in Figure 23.3.

The setup subprocess is almost the same as that used in Figure 21.2 and is not reproduced here.

The partially complete decision tree for the bar-chart display.
Figure 23.3: The partially complete decision tree for the bar-chart display.

Copy/paste the program in Listing 23.2 into an Arduino sketch, compile and test. As you rotate the wheel on the potentiometer clockwise, progressively more LEDs will light. If you balance the setting so that it is just changing over from three LEDs to four, this is exactly halfway on the potentiometer (arrow pointing upwards).

An Exercise for the Reader

Now that we are familiar with the concept, let us write a program to illuminate all twelve LEDs as a bar graph. The following changes will need to be made to the program in Listing 23.2:

Both Port B and Port C will need to be updated after each if()statement, e.g.

PORTC = 0b00000011; 
PORTB = 0b00111111; 

will result in the top two LEDs off, all other LEDs on.

The threshold numbers will go up in steps of \((1024 / 12)\) which is approximately 85.

Create a new Arduino sketch and modify the program from Listing 23.2. When you test it, the LEDs should light progressively as the potentiometer is rotated clockwise. When the potentiometer is at the extreme anticlockwise position, all LEDs will be out.

Assessment of Experiment 3

Add a sub-title “Experiment 3” to your lab diary, and include the following:

  • A photo of the modified breadboard, with the potentiometer added. Don’t forget to include identification.
  • A truncated flow-chart of the modified decision tree for 12 LEDs which should include the decision at
    the centre1 of the range.
  • A listing of your program for An Exercise for the Reader above, with comments as appropriate.

Code listings

Listing 6: Simple application of analogRead().

Listing 23.1: Simple application of analogRead()
// the setup function runs once when you press reset or power the board

word ADCval = 0;

void setup() {

    // initialize Ports B and C pins 0-5 as outputs.

    DDRB = 0b00111111;
    DDRC = 0b00111111;

    PORTB = 0; // both ports start from zero
    PORTC = 0;
}

// the loop function runs over and over again forever

void loop() {

    PORTC = (analogRead(A6)) / 16; // and that’s the active bit of the programme!
}

View or download code from GitHub Gist analog.ino.

Bar Graph display with six LEDs

Listing 23.2: Bar Graph display with six LEDs
// the setup function runs once when you press reset or power the board

word ADCval;

void setup() {

    // initialize Ports B and C pins 0-5 as outputs and set them to zero initially

    DDRB = 0b00111111;
    DDRC = 0b00111111; // may as well put them on the same line

    PORTB = 0;
    PORTC = 0; // and these statements too
}

// the loop function runs over and over again forever

void loop() {

    ADCval = analogRead(A6);

    if (ADCval >= 854) {
        PORTC = 0b00111111;
    } // all six LEDs on
    else if (ADCval >= 684) {
        PORTC = 0b00011111;
    } // five LEDs on
    else if (ADCval >= 513) {
        PORTC = 0b00001111;
    } // four LEDs on
    else if (ADCval >= 342) {
        PORTC = 0b00000111;
    } // three LEDs on
    else if (ADCval >= 171) {
        PORTC = 0b00000011;
    } // two LEDs on
    else if (ADCval >= 1) {
        PORTC = 0b00000001;
    } // one LED on
    else {
        PORTC = 0; // all LEDs off
    }
}

View or download code from GitHub Gist bar_graph.ino.

Wokwi simulation of bar graph display with six LEDs

You can run a wokwi simulation of this circuit which was created by EEE project student Yousef Alsayegh (class of 2024-2025). The link is Lab 6: Bar graph display with six LEDs and it uses the code from Listing 23.2. You can copy and edit this to create your own simulation the bar Graph display with twelve LEDs.

If you do, it would be useful to provide links to the simulations in your lab diary.

Photographs

The following photograph (Figure 23.4) has been provided by Dr Davies who created this experiment.

Photograph of the plug-in breadboard after completing Experiment 3.
Figure 23.4: Photograph of the plug-in breadboard after completing Experiment 3.

  1. At the centre point PORTC = 0b00000000 and PORTB = 0b11111111.↩︎

Copyright © 2021-2024 Swansea University. All rights reserved.