EP1000

Analog Inputs & Outputs

In this session, we will improve our skills in Arduino Programming and the understanding of the Arduino Uno capabilities. We will cover

Review of switch configurations

Switch Configurations

There are two common methods of connecting a switch to a microcontroller

If we use the internal pull-up resistor, we don’t need an external resistor, however, we are limited to a Normal HIGH, Closed LOW configuration.

Debouncing a switch

Switches are mechanical devices. When a switch is closed, the mechanical components sometimes do not close perfectly and causes the switch signal to switch from the OFF to ON states multiple times until the switch closes completely. If we were to examine the signal through an oscilloscope, this might be the signals we get

Switch bouncing

We can reduce the effects of switch bouncing using a hardware circuit or software. We will show how you can use a simple delay routine to reduce the bouncing effects of the switch.

Task:

Read a switch and make it toggle the LED.

If we examine this problem, we find that we have 2 states

The switch toggles the states.

Here are 3 solutions

  1. simple reading of the switch without debouncing
  2. debouncing the switch using the delay() function
  3. debouncing the switch using the millis() function.

Deboucing should be done whenever you read a mechanical switch to minimize the errors. If the program requires the use of interrupts (an advanced topic), then the millis() function should be used, otherwise the delay() function would do.

For further discussion and reference, see Brainy Bits How to debounce switchs on the Arduino, which has a nice follow-up video explanation.

The code can be found here:

  1. Toggling an LED with a switch without debuncing
  2. Toggling an LED with a switch with debouncing using the delay()
  3. Toggling an LED with a switch with debouncing using the millis()

Ref: Debouncing a switch

Great videos:

  1. Brainy Bits How to debounce switchs on the Arduino
  2. Electronics lab Arduino button debouncing

Explanations

  1. Arduino Reference Debounce
  2. Arduino Getting Started Button Debounce
  3. Programming Electronics Academy Debouncing a Switch

State Diagrams

In the previous session, we looked at a problem using a switch as an input. By pressing the switch we changed the display of the LEDs on the board. With each press of the switch a different “state”, If we name the states, we can get a better picture of what is happening.

Ref: Wikipedia Finite State Machines

State Effect Next State
0 All LEDs OFF, this is the start state 1
1 RED LED on, others off 2
2 YELLOW LED on, others off 3
3 GREEN LED on, others off 4
4 All LED ons 0

Looking at the above table we have altogther 5 states. Pressing the switch moves from one state to another. So let’s write down what we need to do:

  1. Initialise LED and Switch ports
  2. Start with state 0, all LEDs are off.
  3. If the switch is pressed
    1. we change the state
    2. apply the changes to the LEDs
    3. have some delay so that we don’t read the switch so quickly
    4. go back to checking the switch (3.1)

We will use an int variable to indicate the state which we are in, and use the condition statement to test for the state. In C/C++ there is a statement which best suits our purpose - the switch(). The syntax of the switch() is as follows:

    switch( intValue ){
        case N : <statement 1>;
                 <statement 2>;
                 ...
                 break;
        case M : <statement 1>;
                 <statement 2>;
                 ...
                 break;
    }

The switch() statement uses a parameter which must be an int or char, and will execute if it matches one of the case conditions. It is easier than using nested if statements.

The final program for the Arduino Uno can be found here: Uno with Sw and 3LEDs

Ref:

  1. Tutorials Point C++ switch statement
  2. W3schools C++ switch
  3. Arduino Switch..case

 

Analog signal conversion

Analog input with the Arduino Uno

The Arduino Uno board (ATMel ATMega328) has 6 analog inputs (A0-A5). Each input is connected to a 10-bit Analog-to-digital converter with a Vref of 5V. You can use the analog inputs to read and convert analog voltages (of up to 5V) using these inputs.

To read an analog input, - use the analogRead() function - enter the port A0-A5 as the parameter to the function - the function returns an integer (0~1023) depending on the value of the analog input.

A variable resistor or potentiometer has the ability of changing the value of the resistor though a knob or screw. The variable resistor has three legs, the whole resistance is available across two of the legs, however, if the resistance is taken over the middle and one of the other legs, we get a fraction of the total resistance. This provides us a voltage divider if we connect the variable resistor as follows:

Voltage divider

In the following example we use a variable resistor (Vr) to provide an analog voltage of between 0~5V. Based on the analog input voltage (Vin), we use the analog input to display on the Serial monitor the equivalent digital value. If we change the value of Vin, we can see that the Serial monitor displays a corresponding change in the output value.

analogInput

 

Analog Output with the Arduino Uno

Usually in order to obtain analog voltages from a digital system, a DAC (Digital-to-Analog Converter) is used. The DAC works in a similar way as the ADC execpt that it takes a digital value and converts it back to an Analog voltage. Unfortunately, the Arduino Uno does not have an in-built DAC. Instead it uses Pulse Width Modulation to produce an equivalent analog voltage.

Ref:

  1. Arduino PWM
  2. Sparkfun Pulse Width Modulation
  3. Electronics Coach Pulse Width Modulation - a more comprehensive electronics explanation

Pulse Width Modulation is a term used for describing a digital signal (OFF/ON) which has different widths. By changing the widths of the pulse (the amount of time ON vs the amount of time OFF, we can change the “average” amount of voltage supplied.

Changing the pulse width is similar to changing the Duty Cycle of a square wave signal. The Duty cycle is defined as a percentage of how long a pulse is in the “ON” state vs the “OFF” state.

Duty Cycle

Ref: Arduino Reference PWM

The proportion of “ON” time gives the equivalent voltage being output if averaged over a period of time. Hence, we are able to produce “analog” voltages dependent on the duty-cycle of the square wave signal.

The Arduino Uno has 6 PWM output ports. They are digital ports (3, 5, 6, 9, 10 and 11). On the Uno board they are indicated with a “~” in front of the port number.

When set into PWM mode using the function analogWrite(), the ports output a square wave of frequency 490 HZ (pins 5 and 6 at 980Hz).

To obtain a PWM signal we use

The following example shows how an analog input voltage (produced by the variable resistor) is used to light up an LED with varying brightness using PWM.

Analog Input Output

The map function is used to map the value of the variable reading (ranges from 0~1023) to the PWM duty-cycle value of 0~255. This value is stored in the variable val and output through the PWM port.

In this way, as you turn the variable resistor, you are changing the input analog voltage. The Uno reads this analog voltage and converts it to a PWM duty-cycle value to be output. This changes the brightness of the LED.

Uno Analog Input & Output

You can observe the simulation of the circuit using TinkerCAD (Uno Analog Input & Output). An oscilloscope is added to show the 490Hz waveform which is Pulse Width Mddulated (PWM).

 

Assignment 13

In this assignment, you will attempt to replicate the tasks above as well as look into the use of the Light Dependent Resistor to determine light levels.

I have provided approximate timings for you so that you do NOT spend all your time (doing something you like and neglecting other modules!)

Time Task
30 min Read/watch the deboucing tutorial on Brainy Bits How to debounce switchs on the Arduino
30 min Wire up and test the variable resistor and led using analog inputs and outputs
30 min Investigate the reading the LDR using analogRead()
30 min Investigate the use of the RGB Led using digitalWrite()

This assignment may require the wiring of the circuitry using the Arduino Uno board and breadboard with other components. You may need to consult your lecturer during the breakout sessions regarding troubleshooting of the circuitry.

Complete the following programming assignments:

Programming assignments

  1. Wire up a variable resistor/potentiometer on the analog input and an LED. Write a program to use the Uno to read the variable resistor to control the brightness of the LED using PWM.
  2. You are provided with a LDR (Light Dependent Resistor).
    • Wire up the LDR as in the circuit diagram below.
    • Use the serial comms to display the values read
    • Can you think of an application that can use the LDR ?

    Light Dependent Resistor

  3. Can you use the Variable Resistor to control the colors that are generated by the RGB LED? You will need to do some research on this matter
    • How do you connect the RGB LED?
    • What colors do you want to display? How do you store them?
    • Write a program to demonstrate your application.

Remember to document your work in your blog.

 

January 2021