Revisited management of traffic lights

published: 2 November 2019 / updated 30 November 2019

Lire cette page en français

 


Preamble

The management of traffic lights has already been treated here:
  ARDUINO ports: manage a trafic light

The primary purpose of this article is to explain how to manage the ARDUINO ports. Traffic light management is simply used to illustrate this management of ports.

In this article, words similar to those defined in the C language library have been exploited too much for ARDUINO, example: digitalWrite HIGH LOW etc...

To too much want to imitate these libraries C, one creates a code in FORTH language overloaded with tests and manipulations useless.

The primary philosophy of the FORTH language is to create short, efficient, robust definitions. We choose voluntarily to work without security. That is, for all the definitions that follow, there is no presence test of the expected parameters. If you test some definitions and forget one or more parameters, the application may hang.

Conversely, we create simple words, easy to test via the interpreter. Each tested word becomes a black box which will be integrated into the definition of the following words.

By rewriting this traffic light management, the compiled code is almost twice as compact as the initial code.

Traffic light management

The management of traffic lights is a classic of programming exercises for ARDUINO cards. Here is the shema of connection of the LEDs for ARDUINO MEGA:

mounting of the LEDs for the traffic lights
Here is the schema of connection of the LEDs for ARDUINO NANO:

mounting of the LEDs for the traffic lights

Ports and LEDs definition

for ARDUINO MEGA

The ports actually used are defined: PORTB and DDRB. The word PINB is commented out because it is not used later:

decimal 
\ PORTB 
37 constant PORTB	\ Port B Data Register 
36 constant DDRB	\ Port B Data Direction Register 
\ 35 constant PINB	\ Port B Input Pins - unused 

for ARDUINO NANO

decimal 
\ PORTB 
43 constant PORTD	\ Port D Data Register 
42 constant DDRD	\ Port D Data Direction Register 
\ 41 constant PIND	\ Port D Input Pins - unused 

We create the word defLED: which is a new definition word. The word defLED: then allows us to define the yellow and green red LEDs: LED.red LED.yellow LED.green. These words are more explicit than was the word pin13 for example.

for ARDUINO MEGA

: defLED: ( PORTx mask ---  |  --- mask port) 
    create 
        , ,             \ compile PORT and mask 
    does> 
        dup @           \ push pin mask 
        swap 2+ @       \ push PORT 
  ; 
 
\ définition LED.xx 
eeprom 
PORTB $80 defLED: LED.red 
PORTB $40 defLED: LED.yellow 
PORTB $20 defLED: LED.green 

for ARDUINO NANO

\ définition LED.xx 
eeprom 
PORTD $10 defLED: LED.red 
PORTD $08 defLED: LED.yellow 
PORTD $04 defLED: LED.green 
 

LEDs management

The two words led.ON and led.OFF are almost useless. They define aliases for mset and mclr. The purpose of words led.ON and led.OFF is to make the future code more readable.

: led.ON (  ---) 
    mset  ;    \ turn pin ON 
: led.OFF (  ---) 
    mclr  ;    \ turn pin OFF 

Before turning on and off the LEDs, the PORT managing the LEDs is initialized. Word init.LEDs retrieves the masking bits of the yellow and green red LEDs, in fact sum it up and define the DDRB register:

for ARDUINO MEGA

: init.LEDs ( ---) 
    LED.red     drop 
    LED.yellow  drop + 
    LED.green   drop +  DDRB mset  ; 

for ARDUINO NANO

: init.LEDs ( ---) 
    LED.red     drop 
    LED.yellow  drop + 
    LED.green   drop +  DDRD mset  ; 

Three cycles traffic light

A three cycle sequence is defined with the word traffic.lights. Each line indicates which LED is lit for a given time before turning it off.

Then we integrate the word traffic.lights in an undetermined loop in the definition of the word lights.loop:

: traffic.lights ( ---) 
    LED.green   led.ON   3000 ms    LED.green   led.OFF 
    LED.yellow  led.ON    800 ms    LED.yellow  led.OFF 
    LED.red     led.ON   3000 ms    LED.red     led.OFF  ; 
\ trafic.lights execute one light cycle 
 
: lights.loop ( ---) 
    init.LEDs 
    begin 
        traffic.lights 
    key? until ; 

Four cycle traffic light

In some countries, fires use an additional sequence. This sequence turn on the yellow and red light:

four cycles traffic lights

Just insert this sequence, which is done in the word D.traffic. This word D.traffic is then executed in the definition of the word D.lights.loop:

\ german trafic light style 
: D.traffic ( ---) 
    LED.green   led.ON   3000 ms    LED.green   led.OFF 
    LED.yellow  led.ON    800 ms    LED.yellow  led.OFF 
    LED.red     led.ON   3000 ms     
    LED.yellow  led.ON    800 ms  
    \ simultaneous red and yellow ON 
    LED.red     led.OFF  \ simultaneous red and yellow OFF 
    LED.yellow  led.OFF  ; 
\ trafic.lights execute one light cycle 
 
: D.lights.loop ( ---) 
    init.LEDs 
    begin 
        D.traffic 
    key? until ; 

The complete listing and documented is available here.