Example: OBCB counting off events

The following program is a simple example of using the OnBoard Counter B to count off events and trigger some action after a certain accumulated count. In this instance imagine it is counting frozen pizzas as a conveyor moves them into an "outer" carton. For every 12 pizzas it triggers an output that moves the filled carton to a sealing machine.

;Pizza Packer.

        LaunchTask      Count12
        LaunchTask      BoxSealer
        RunTasksForever

;============= Pizza counting task =================================
;The pizza detector is connected to input "iPizzaCount", corresponding
;to OBCB channel "iPizzaCount". For every 12 pizzas we have to send a signal
;to the box Sealer task to generate an output pulse. This is done by
;a GoSub to SealBox

;Pizzas arrive at a rate of about one per second.

iPizzaCount     iEQU    5       ;Define the count channel

Count12:
        OBCB_Start      iPizzaCount
Loop12:
        YieldTask
        OBCB_fRead      iPizzaCount     ;Get the count
        fLoadQ          11
        fSUB                            ;-ve if count >= 12
        fGoIfPos        Loop12
Got12:
        OBCB_fRdClr     iPizzaCount     ;Clear the counter
        GoSub           SealBox         ;Trigger the box Sealer
        GoTo            Count12


;================== Box Sealer task. =================================
;Generate a 5 second pulse on output "oBoxSeal" whenever
;signalled by the pizza counting task. (In practice this task
;could itself be a complex sequence to control the folding
;and taping process).

oBoxSeal        oEQU    3       ;Define the Sealer trigger output

sSeal           defSEM

BoxSealer:
        WaitForST       sSeal           ;Wait for the signal semaphore
        ClrS            sSeal           ;Clear the semaphore for next time
        On              oBoxSeal        ;Start the Sealing sequence
        Pause           500             ;5 seconds for the sequence to complete
        Off             oBoxSeal        ;End the sequence
        GoTo            BoxSealer

;GoSub here to trigger one box Sealing cycle..
SealBox:
        SetS            sSeal
        Return

There are a couple of interesting points to note about this program:

  1. The test for 12 pizzas is done by testing for anything more than 11 pizzas. This is called defensive programming. Defensive programming is a particular form of paranoia that reduces the number of pizzas spilling on the floor if something goes wrong (and it will!).
  2. Because the box sealing and pizza counting functions are relegated to separate tasks, it is perfectly OK for the sealing task to take longer than the interval between two pizzas.

The counting task simply calls a subroutine, that is part of the sealing function, to trigger a sealing operation. It does not know, or care, how the sealing function works. This separation and hiding of function (and data) is a very important principle of structured, object oriented programming.