1 - 7-Segment Display Intro

The 7-Segments

A, B, C, D, E, F, G - These comprise the 7 segments of a 7-Seg display. The decimal point isn't used in the creation of letters or shapes, which may be why it's not counted. So yes, technically their are 8 segments but these are referred to as 7-Seg displays.

By controlling which segments are active, you can display 0-9 and most letters of the alphabet.

Common-Cathode / Common-Anode

LEDs (Light Emitting Diodes) only allow current to pass in one direction, much like a check-valve. The arrow-shape of the LED symbol indicates which direction current is able to pass through it; entering through the anode and exiting through the cathode.

The cathodes of LEDs D1 and D2 are tied together, this is referred to as common-cathode. Switches SW1 and SW2 can be thought of as digital pins on our microcontroller; we have a limited number of them so we should strive to use as few of them as possible by finding clever ways to control lots of LEDs.

Each digit in a 7-Segment display is wired as a common-cathode group.

Having a common-cathode doesn't mean much if you don't design your circuit to take advantage of it. Here's a design for a 4-digit 7-seg display but it requires 32 I/O pins and 32 resistors. Our Pico doesn't even have enough I/O pins to support this drive configuration.

This is how you make the most of common-cathodes, you use them as a single point for making or breaking the connection to ground. This allows us to share the circuitry used for driving the anodes! Notice how all of the "A" LEDs have their anodes tied together? Each segment (e.g. A, B, C, etc.) are wired as common-anode and each digit is common-cathode! Now we're able to control all 32 LEDs with just 12 switches and only 8 resistors! You would be correct to point out that only 1 digit can be lit at a time but therein lies the clever thing we're going to do; if you cycle through each digit fast enough, your eyes will perceive them as all being lit at the same time!

This schematic is from the manufacturer datasheet, describing the internal wiring of our display.

We opted to create a less complicated symbol to represent the display in our schematic.

Interactive Falstad Simulation

Writing the Code

You won't need to look at the schematic to start programming. We've labeled which GPIO (General Purpose I/O) pins are connected to each segment and peripheral.

Let's start with something simple. We're going to light up the 'A' segment and cycle through each digit, one at a time.

Since we're just simply turning things on and off, we'll use DigitalInOut objects. We'll name our object 'A' and connect it to GP10 by using the board module.

We'll have to do the same for each digit. The IC (DIP Chip) we see here is responsible for connecting the common-cathode of each digit to ground. When we set GP6 to HIGH, DIG1 (Digit 1) gets connected to ground. We only ever want one digit activated at a time.

By default, our DigitalInOut objects are inputs. We need to tell them to become outputs if we want to turn them on or off, set them as True or False, 1 or 0, 3.3V or Gnd. Because they are DigitalInOut objects they have a built in method called switch_to_output() that makes this really easy.

With the initial setup out of the way, we can set 'A' to 3.3V by writing True to A's value attribute. Now the the anode of every 'A' segment is connected to 3.3V, but none of them will light up because none of the digits have a path to ground yet.

We'll create a while loop that runs forever and we'll have it turn each digit on sequentially, one at a time.

...wait a sec, they're all on at the same time? Well, not actually; we forgot to put any delays in our code so our microcontroller is cycling through each digit so quickly that our eyes, and the camera in the case, perceive every digit as being lit simultaneously.

In order to use delays, we need to import the time module.

Now we can use the sleep method from the time module to tell our microcontroller to do nothing for 0.5 seconds after activating each digit.

Video

Code

import board
from digitalio import DigitalInOut
import time


A = DigitalInOut(board.GP10)
A.switch_to_output()

D1 = DigitalInOut(board.GP6)
D1.switch_to_output()

D2 = DigitalInOut(board.GP7)
D2.switch_to_output()

D3 = DigitalInOut(board.GP8)
D3.switch_to_output()

D4 = DigitalInOut(board.GP9)
D4.switch_to_output()


A.value = True

while True:
    D1.value = True
    time.sleep(0.5)
    D1.value = False
    
    D2.value = True
    time.sleep(0.5)
    D2.value = False
    
    D3.value = True
    time.sleep(0.5)
    D3.value = False
    
    D4.value = True
    time.sleep(0.5)
    D4.value = False

Last updated