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