exercises

advertisement
1
LED DISPLAYS
Microcontrollers and Interfacing
week 6 exercises
1
LED displays
Arrays of LEDs in a single package can be arranged into useful patterns for displaying digits and letters.
Seven-segment displays contain seven (or eight) individual
A
LEDs arranged in a pattern that is convenient for displaying
1
10
digits (and maybe some letters too).
Unlike bar graph arrays, each LED in a seven-segment disF
B 9
2
G
play shares one of its terminals with all the other LEDs in
3
8
the package. The shared terminal can be the anode or the
4 E
7
C
cathode. If all the anodes are connected together the arrangement is called common anode; if all the cathodes are connected
5
6
together, the arrangement is called common cathode.
D
DP
A common cathode seven-segment display therefore requires at least 8 pins (seven for the anodes, and a single pin
10 9
7
5
4
2
1
6
for the shared cathode connection). Most seven-segment displays also provide a decimal point (the eighth LED), and an 10mA
additional common connection, making a total of 10 pins.
(-2V)
1.1
A
B
Arduino
D2
Seven-segment display circuit
Modify your circuit from last week to use a seven-segment
display (instead of a bar-graph array). Connect the seven segments as follows:
digital pin 2 →
3→
...
8→
pin 9 →
A segment
B
D3
D4
Remember that each segment is a light-emitting diode
(LED), and so you must use the usual current-limiting
resistors (510 Ω or 330 Ω).
1 of 4
510
510
510
510
D6
510
510
D8
510
D9
510
GND
PIN 1
, 1 Ask the instructor to check your work.
D
E
3,8
D5
D7
G
DP segment
C
F
10
9
7
5
4
2
1
6
G
DP
A
B
C
D
7-segment
display
E
F
G
GND
DP
GND
8
3
1.2
1.2
Seven-segment display software
2
USING A SEVEN-SEGMENT DISPLAY TO SHOW DIGITS
Seven-segment display software
Modify your bar graph sketch to drive the seven-segment display instead. (Because the seven-segment display has
only 8 LEDs, two fewer than the bar-graph display, all you need to do is remove the calls that refer to pins 10
and 11: two calls to pinMode() in setup(), and two calls to digitalWrite() in setLEDs(). (If your setLEDs()
was controlling fewer than 8 LEDs, you will have to add the additional pins to your sketch.)
Test your seven-segment display; e.g., using a loop() that counts in binary, or that turns on each segment one
at a time, etc.
, 2 Ask the instructor to check your work.
2
Using a seven-segment display to show digits
To display a digit we have to turn on the segements in an appropriate pattern. For example, the digit 0 will be
displayed if segments A, B, C, D, E, and F are turned on, corresponding to digital pins 2, 3, 4, 5, 6 and 7 being HIGH,
and pins 8 and 9 being LOW. We can set these pins to their required states in parallel using ‘setLEDs(0b00111111)’.
2.1
Designing the digits
Complete the table on the right to
plan the pattern of segments that
need to be lit for each of the ten
decimal digits, and derive the corresponding argument to setLEDs():
1. Design a pattern of segments
corresponding to the digits 1 to 8.
Using a pencil, fill in the empty
segments in the example displays
to visualise your requirements.
digit
segment
pattern
segments
E D C
B
A
setLEDs()
argument
L
H
H
H
H
H
H
0b0111111 = 0x3F = 63
H
H
L
H
H
H
H
0b1101111 = 0x6F = 111
B
G
0
E
C
D
DP
A
F
B
G
1
E
C
D
DP
A
F
B
G
E
C
D
DP
A
F
B
G
3
E
C
D
3. Finally, convert the H and L values
for each segment into a series of 1
and 0 bits. The equivalent integer
value is the numeric argument for
setLEDs() that will display the
digit.
F
A
F
2
2. Convert your patterns to the
corresponding H (high) and L
(low) values for each segment.
G
DP
A
F
B
G
4
E
C
D
DP
A
F
B
G
5
E
C
D
DP
A
F
B
G
6
E
C
D
DP
A
F
B
G
7
E
C
D
DP
A
F
B
G
8
E
C
D
DP
A
F
B
G
9
E
C
D
DP
, 3 Ask the instructor to check your work.
2 of 4
2.2
Displaying the digits
2.2
2
USING A SEVEN-SEGMENT DISPLAY TO SHOW DIGITS
Displaying the digits
Displaying a digit requires a call to setLEDs() with an argument corresponding to the digit we want to display.
There are several ways to achieve this:
1. Define a numeric constants for each digit. Easy, but
not convenient for converting a numeric value (an
analogue input voltage, for example) into the corresponding DIGIT x value.
2. Write a function displayDigit(unsigned int
digit) that uses switch() to selects one of ten calls
to setLEDs, based on the value of digit (from 0
to 9).
The displayDigit() function is convenient, but
tedious to write (lots of repeated code) and wasteful of precious program memory (ten almost identical
calls to setLEDs()).
const int DIGIT_0 = 0 b0111111 ;
// ... etc ...
const int DIGIT_9 = 0 b1101111 ;
setLEDs ( DIGIT_5 ); // display the digit ‘5’
void displayDigit ( unsigned int digit )
{
switch ( digit ) {
case 0: setLEDs (0 b0111111 ); return ;
// ... etc ...
case 9: setLEDs (0 b1101111 ); return ;
}
}
displayDigit (5); // display the digit ‘5’
A better solution is to store the ten bit patterns in an array, index the array using the digit that we want to
display, and then call setLEDs() with the value read from the array.
Create a new function:
displayDigit(unsigned int digit)
Within the function, declare a static array of 10 integers
to hold the bit patterns for each digit. (An incomplete
example is shown on the right.)
static int bits [10] = {
0 b0111111 , // digit 0
// ... etc ...
0 b1101111 , // digit 9
};
Index your array using the digit argument. (To protect
yourself from accessing beyond the end of the array, use
the modulo operator ‘%’ to make sure the array index can
never be outside the range 0. . . 10.)
Test your function with the following loop() shown on
the right.
void loop ()
{
static unsigned int counter = 0;
displayDigit ( counter ++);
delay (200) ;
}
, 4 Ask the instructor to check your work.
2.3
Mini project
Design some seven-segment patterns for letters. Supporting the entire (Roman) alphabet is difficult (if not impossible)
with only seven segments, but if you design patterns for the letters A to F (for example) then you can display
hexadecimal digits. Use the templates below to design as many additional characters as you want, then add them
to your displayDigit() function.
A
F
A
B
F
G
E
C
D
E
F
DP
F
DP
F
DP
F
DP
F
DP
F
F
3 of 4
DP
F
DP
F
DP
F
DP
F
B
G
C
D
DP
A
B
E
C
D
DP
G
C
D
B
E
A
B
E
F
G
C
D
DP
G
C
D
A
B
E
A
B
E
F
G
C
D
DP
G
C
D
A
B
E
A
B
E
F
G
C
D
DP
G
C
D
A
B
E
A
B
E
DP
F
G
C
D
DP
G
C
D
A
B
E
A
B
E
F
G
C
D
DP
G
C
D
A
B
E
A
B
E
F
G
C
D
DP
G
C
D
A
B
E
A
B
E
F
G
C
D
DP
G
C
D
A
B
E
A
B
E
F
G
C
D
DP
G
C
D
A
B
E
A
B
E
F
G
C
D
DP
G
C
D
A
B
E
A
B
G
E
F
G
C
D
DP
A
F
A
B
G
DP
E
C
D
DP
3
3
DIGITAL INPUT
Digital input
Let’s add two switches to our circuit and use them to count up and down. The current value of the counter will be
displayed on the seven-segment display.
We cannot simply connect a switch to a digital input pin. Just like with analogue inputs, we have to generate a
voltage that the digital input can recognise as HIGH or LOW. The usual way to do this is with a pull-up resistor and
a switch:
5V
When the switch is open (not conducting) the resistor
GND
5V
connects the digital input to 5V and reading the input
56k
switch open
will produce HIGH. The digital input has a very high redigital HIGH
sistance, and so almost no current will flow.
0V
When the switch is closed (conducting) it connects
GND
5V
the digital input to GND and reading the input will pro56k
switch closed
0.1 mA
duce LOW. In this case, the resistor limits the amount of
digital LOW
current that will flow from 5V to GND.
Typical values for the pull-up resistor are between 20k Ω and 100k Ω. Let’s use 56k Ω, a standard value in the
middle of the range. Using Ohm’s law we can calculate that 5 V/56000 Ω ≈ 0.1 mA will flow from 5V to GND when
the switch is closed.
3.1
Digital input hardware and software
Extend your circuit with two switches, including pull-up resistors, as shown below. (Keep your seven-segment display
circuit! We will be using it again shortly.)
56k
56k
Arduino
5V
D2
510
D3
510
D4
510
D5
510
D12
D6
510
D11
D7
510
D8
510
D9
GND
510
10
9
7
5
4
2
1
6
A
B
C
D
7-segment
display
E
F
G
DP
GND
GND
8
3
GND
To make the switches affect the counter, we want to recognise a transition from the switch being open to the
switch being closed. This means the digital input will change from HIGH value to a LOW.
Extend your sketch to read the digital input value from
pins 11 and 12. In setup() set the mode of these two
pins to INPUT. In loop() use digitalRead() to check
if these pins are HIGH or LOW. For each pin we want to
detect a change of input level. If the new level is LOW
then we increment (pin 11) or decrement (pin 12) the
counter.
The code for pin 11 is shown on the right. Begin
by adding just the code for pin 11. Make sure your
seven-segment counter increments each time you press
the switch connected to pin 11.
void setup () {
pinMode (11 , INPUT );
// ... etc ...
}
void loop () {
static unsigned int counter = 0;
static int pin11state = HIGH ;
int newState ;
// process pin 11 ( increment counter )
newState = digitalRead (11) ;
if ( newState != pin11state ) {
if (LOW == newState ) counter += 1;
pin11state = pinstate ;
}
, 5 Ask the instructor to check your work.
Add similar code for pin 12, connected to the other
switch. Make this other switch decrement the counter.
// process pin 12 ( decrement counter )
// ... similar to pin 11...
, 6 Ask the instructor to check your work.
displayDigit ( counter );
}
Do you notice any strange behaviour when you press the switches?
4 of 4
Download