ARDUINO ports: Managing a 4 x 7 segment display

published: 11 June 2019 / updated 23 June 2019

Lire cette page en français

 


The 4 x 7-segment display

It is a 4-digit display in one block. Here is the layout of the connectors of this display:

4 x 7 segment display connector numbers

The physical terminals 6, 8, 9 and 12 must be connected to GND of the ARDUINO board. We'll see further how to proceed, because these four terminals must be managed in a particular way through a specific port.

We will first wire these four physical terminals as follows:

start wiring 4 x 7 segments

Turn on the ARDUINO MEGA card. One of the segments of the display should light up. You can move the red wire to the other connectors and verify that all segments of the display are operational. If you move the black wire on the board to the right, on the next resistor, you go at the second digit.

Connecting the cathodes 6, 8, 9 and 12 to the ARDUINO board

We will connect the physical terminals 6, 8, 9 and 12 of the 4x7 segment display as follows:
  PB0 -> pin 19 -> connector 53 -> pin 6
  PB1 -> pin 20 -> connector 52 -> pin 8
  PB2 -> pin 21 -> connector 51 -> pin 9
  PB3 -> pin 22 -> connector 50 -> pin 12

Connection diagram:

wiring terminals 6, 8, 9 and 12 on the ARDUINO board

We will now check that this wiring is correct. We define, in FORTH:

\ PORT B 
37 constant PORTB 
36 constant DDRB 
35 constant PINB 
: initDDRB ( c DDR ---) 
    $ff DDRB c!   \ set all PORT B bits in output mode 
    ; 

We execute:

initDDRB 
%00000000 PORTB c!   \ met tous les PIN du PORT B à l'état bas 

If you have left the red wire connected to the 5V on the ARDUINO board and on a inputs of the 7-segment display, you should see the same segment on the 4 digits. We will extinguish the rightmost figure:

%00000001 PORTB c!

Setting the low-order bit to 1 turns off the first segment!

%00000010 PORTB c! 

Setting the second bit to 1 turns off the second segment.

The logic of digital pins on ARDUINO cards

On ARDUINO cards, there are two kinds of pins:

The digital pins are activated as inputs (to manage a push button for example), or in outputs to emit an "all" or "nothing" signal:

The low state is related to the mass (GND). The high state delivers a voltage of 5V.

You can turn off all digits of the display like this:

%00001111 PORTB c!

Connecting the other terminals of the 4x7 segment display

Voic les connexions à réaliser sur le PORT A:
  PA0 -> pin 76 -> connecteur 24 -> borne 1 -> segment E
  PA1 -> pin 75 -> connecteur 25 -> borne 2 -> segment D
  PA2 -> pin 74 -> connecteur 26 -> borne 4 -> segment C
  PA3 -> pin 73 -> connecteur 27 -> borne 7 -> segment B
  PA4 -> pin 72 -> connecteur 28 -> borne 11 -> segment A
  PA5 -> pin 71 -> connecteur 29 -> borne 10 -> segment F
  PA6 -> pin 70 -> connecteur 30 -> borne 5 -> segment G

Caution: do not confuse physical connector numbers and pin numbers

On the ARDUINO cards, the physical connectors are marked, some by numbers, others by their function, example: GND, TX, RX, 5V, etc ...

The mapping for associating pin numbers with physical connectors is in this document:
 Pin out map on ARDUINO DUE
 Pin out map on ARDUINO MEGA 2560
 Pin out map on ARDUINO MICRO
 Pin out map on ARDUINO NANO
 Pin out map on ARDUINO UNO
 Pin out map on ARDUINO YUN

For example, the led '13' which is connected to the ARDUINO MEGA board with the physical terminal 13 is related to the PIN 26. In all our texts, the term "pin" will always refer to PIN code XX as referenced in the technical documents of ARDUINO cards. The mention of a physical connector will be done with the term 'terminal'. Example:

  PIN 19 (terminal 53) (penultimate terminal, all at the bottom, left on an ARDUINO MEGA 2560 board)

To learn more about how to program the connectors of the different ARDUINO boards:
Understanding ARDUINO card connectors

chiffre ---
--
PA6
G
PA5
F
PA4
A
PA3
B
PA2
C
PA1
D
PA0
E
0 00111111
1 00001100
2 01011011
3 01011110
4 01101100
5 01110110
6 01110111
7 00011100
8 01111111
9 01111110

Only the decimal point is not wired:

wiring segments to the ARDUINO board

FORTH multiplexing

We will now define the parameters of PORT A and the matrix bitmap to handle segments representing numbers:


Notice: Undefined variable: ff in /home/arduinofom/www/articles/pages/FORTH/FlashForth/gestionAfficheur4x7segments.phtml on line 293
\ PORT A 
34 constant PORTA	\ Port A Data Register 
33 constant DDRA	\ Port A Data Direction Register 
32 constant PINA	\ Port A Input Pins 
: initDDRA ( c DDR ---) 
     DDRA c!   \ set all PORT A bits in output mode 
    ; 
create digits  ( --- addr) 
    %00111111 c,    \ digit 0 
    %00001100 c,    \ digit 1 
    %01011011 c,    \ digit 2 
    %01011110 c,    \ digit 3 
    %01101100 c,    \ digit 4 
    %01110110 c,    \ digit 5 
    %01110111 c,    \ digit 6 
    %00011100 c,    \ digit 7 
    %01111111 c,    \ digit 8 
    %01111110 c,    \ digit 9 
    %00000000 c,    \ display off 
: >7seg ( n ---) 
    digits +        \ increase addr with value n 
    c@              \ fetch c that will be send to 7 segments display 
    PORTA c! ;      \ send value to display 

The 3 >7seg sequence displays 3 on the 7-segment display.

The word >7seg can only be preceded by a value between 0 and 9. Any other value will cause a random effect...

End of the code managing the 4x7 segment display:

5 constant DELAY    \ time to display 1 digit before next digit 
 
ram 
create valToDisp    \ 4 bytes array 
    4 allot         \ for 4 digits to display 
 
flash 
: displayLoop ( ---) 
    begin 
        valToDisp 0 + c@ >7seg 
        %00001110 PORTB c! DELAY ms 
        valToDisp 1 + c@ >7seg 
        %00001101 PORTB c! DELAY ms 
        valToDisp 2 + c@ >7seg 
        %00001011 PORTB c! DELAY ms 
        valToDisp 3 + c@ >7seg 
        %00000111 PORTB c! DELAY ms 
    key? until 
    $ff PORTB c! ; 
 
: nDisp ( n ---)    \ display value n on 4 x 7 segments 
    0               \ convert n to d 
    4 for 
        10 ud/mod   \ leave modulo and quotient in double integer  
    next 
    2drop           \ drop rest of quotient 
    4 for 
        valToDisp   \ store each digit in array valToDisp 
        r@ + c! 
    next 
    displayLoop     \ display content of valToDisp 
 ; 

The word displayLoop has been deliberately unoptimized to remain understandable. Its definition takes each successive byte contained in the variable valToDisplay and inject this byte into port A via the word >7seg. For each digit, one segment is active at a time. 5 milliseconds delay is defined in the DELAY constant. Too big a value causes a flickering effect.

The word nDisp displays any value between 0 and 9999 on four digits. The value n is converted to a double precision value. Then in the first loop for..next, the sequence 10 ud/mod leaves on the stack the quotient and the rest of the division of this value divided by 10. Example, treat 1972:

1972  ok<#,ram> 1972 
0  ok<#,ram> 1972 0 
10 ud/mod  ok<#,ram> 2 197 0 
10 ud/mod  ok<#,ram> 2 7 19 0 
10 ud/mod  ok<#,ram> 2 7 9 1 0 
10 ud/mod  ok<#,ram> 2 7 9 1 0 0 
2drop  ok<#,ram> 2 7 9 1 

The second loop for..next in the word nDisp stores byte byte the values thus decomposed in the variable valToDisp. valToDisp is actually an array of 4 bytes. It's as simple as that.

Finally, we launch the display of the injected value to nDisp which executes displayLoop

1234 nDisp  \ affiche 1234 sur afficheur 4x7 segments 
7654 nDisp  \ affiche 7654 sur afficheur 4x7 segments 
55 nDisp    \ affiche 0055 ...