Home <<Prev Next>>

Traffic Lights

Here we use input output to simulate traffic lights using three leds of appropriate colour. The leds are connected to pins A0(RED), A1(AMBER) and A2(GREEN)

Step 1: Wire the device to the three leds

Step 2: Cut and past the following into the editor:

// #include "http://www.byvac.com//mBlib/flb/Library/2016/lib_io.bas"

// The leds are connected to port A pins 1 to 3
constant RED {PORTA(PORT),0}
constant AMBER {PORTA(PORT),1}
constant GREEN {PORTA(PORT),2}

// set the pins to be output
function init()
    io_pinRole(*RED(),OUT,WOFF)
    io_pinRole(*AMBER(),OUT,WOFF)
    io_pinRole(*GREEN(),OUT,WOFF)
endf

terminalok
Fig 1 The Start

The first thing to notice is the // #include at the top of the program, this is a library file which makes input output easier. The 'include' will direct the IDE to place the contents of this file into flash and so will be there semi-permanently.

Lines 4 to 6 relate the hardware to a meaningful name. The syntax may be a little strange but on RED you can see PORTA and 0 making it reasonably obvious. The only function so far is init() which will set the lines to output.

Step 3: Send the text over to the device using the |A

IMPORTANT wait until it is completed, this will take a little longer the first time as the library is being loaded into flash. Subsequent loads will detect the presence of the library and will not load it again. Note the numbers at the top of the terminal.

datatypes
Fig 2 Counter indicates loading progress

Step 4: type init()

Step 5: type io_pinSet(*RED(),1) (note the * before the RED())

This will illuminate the RED led if not illuminated already, if not check the wiring, do the same for the AMBER and GREEN, io_pinSet(*RED(),0) will switch it off.

variables
Fig. 3 Syntax updated

See how the syntax is updated, this actually refers to the syntax colouring used in the editor. To see the effect of this press the reset highlight button, see fig. 4

variables

Fig. 4 Highlight button

variables

Fig. 5 Highlight effect

Traffic Light States

There are just 4 states that a set of traffic lights can be in that is:

variables

Fig. 6 Traffic light states

We can model this is a function.

Step 6: Add the text below to the editor under the init() function, don't forget the blank line at the end:

function light_state(n)
    select(n)
        case(1)
            io_pinSet(*RED(),1)
            io_pinSet(*AMBER(),0)
            io_pinSet(*GREEN(),0)
        case(2)
            io_pinSet(*RED(),1)
            io_pinSet(*AMBER(),1)
            io_pinSet(*GREEN(),0)
        case(3)
            io_pinSet(*RED(),0)
            io_pinSet(*AMBER(),0)
            io_pinSet(*GREEN(),1)
        case(4)
            io_pinSet(*RED(),0)
            io_pinSet(*AMBER(),1)
            io_pinSet(*GREEN(),0)
    endselect
endf

Step 7: Send to the device using |A

Step 8: type:

This will test all of the states

Timing

There are a few options we could use here, lets say we want the following:

(1) RED:    15 seconds
(2) RA:      2  seconds
(3) GREEN  15 seconds
(4) AMB     4 seconds

Method 1 a simple delay

Step 8: Copy and paste text below into the editor below the last function

function method1()
    init()
    print "Running\r\n"
    while comkey?(2) = 0
        light_state(1) // red for 15 seconds
        wait(15000) // 1000 = 1 second
        light_state(2) // red and amber for 2
        wait(2000)
        light_state(3) // green for 15 seconds
        wait(15000)
        light_state(4) // amber 10 seconds
        wait(10000)
    wend
endf

The above uses simple a simple wait to go onto the next state. The 'comkey?(2)' is reading the input from UART2 to which the terminal is connected, when a key is received from the terminal comkey?(2) will NOT be zero anymore and so the loop will finish. NOTE that is is only read at the start of the sequence so pressing a key at the terminal will only stop the loop when the sequence has fished, this could take up to 42 seconds given the above timings.

The big disadvantage with this method is that the device cant do anything else as the wait() function will tie the device up, known as a blocking function. If the device was needed to do other things then another method is needed.

Method 2 Using Tasks

Built into ByPic is a task scheduling system that is very useful for handing of a job so that we can get on with something else. A task will run a function on a timed interval which is more or less what is needed. We could set up a task for each light however if the timing drifts a bit off then the lights will get out of sequence so we create a function called traffic_ir.

Step 9: copy the traffic_ir function below and add to the end of the existing code.

dim current_seconds

function traffic_ir()
    if current_seconds > 40 then
    current_seconds = 0
    endif

    if current_seconds = 0 then // red
        light_state(1)
    endif
    if current_seconds = 15 then // red+amber
        light_state(2)
    endif
    if current_seconds = 20 then // green
        light_state(3)
    endif
    if current_seconds = 35 then // amber
        light_state(4)
    endif
    current_seconds = current_seconds + 1 // update count
endf

Note that there is also a variable defined called current_time, this will keep track of the number of seconds that have passed, see as a particular value is reached it changes the state of the traffic lights.

Step 10: Add the code below to the end of the file

function method2()
    init()
    current_seconds = 0
    taskadd("traffic_ir()",1,1000,1)
endf

Type method2() This uses the built in scheduler to run the sequence. Not that you can still type into the terminal and even disrupt the sequence. Try print current_time to see where it is up to.

Method 3 Using a Timer

This is a bit more complex but will allow other operations when the program is running, similar to the task. Times are more accurate than the task and so should be reserved for accurate timings. This method uses a timer and interrupt, the timer will trigger the interrupt every second and a global variable will keep track of the seconds

Step 9: Add the two lines below to the top of the file, above the lib.io.bas include file.

// #include "http://www.byvac.com//mBlib/flb/Library/2016/lib_tmr.bas"
// #include "http://ww.byvac.comm//mBlib/flb/Library/2016/lib_ir.bas"

And this text to the end of the current program

function method3()
    init()
    current_seconds = 0
    print "Running\r\n"
    tmr_init(*TIMER23(),7,312500) // 1 second
    ir_set(*TIMER23(),3,"traffic_ir")
endf

Step 10: IMPORTANT type reset before loading the above program. This will clear the schedule as it will still try to do its scheduling whilst downloading is taking place and this will interfere with the download process. Use |A to send the whole thing over again.

Step 11: Type method3()

This concluded the traffic light program. Again to send any additional text using |A or |S then because the timer and interrupt are going , type reset first.

Home <<Prev Next>>