In this session, we will improve our skills in Arduino Programming and the understanding of the Arduino Uno capabilities. We will cover
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.
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
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
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:
Ref: Debouncing a switch
Great videos:
Explanations
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:
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:
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:
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.
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:
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.
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.
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.
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).
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:
Remember to document your work in your blog.
January 2021