Timer Programming - 1

<= Back to Co-Processor page

Let's do a sequence of actions A, B, C, and D, with each followed by a delay as below. It is shown as a mixed PBASIC and Pseudo-code -


Main:
Do action A'do some action - move a servo etc.
PAUSE 200'delay 200 milliseconds
Do action B'do some other action - move a different servo etc.
PAUSE 600'delay 600 milliseconds
Do action C'do some action - pulse the Sonar etc.
 PAUSE 500'delay 500 milliseconds
 Do action D'do some action - move the servos back etc.
 PAUSE 100'delay 100 milliseconds
 GOTO Main'restart the loop


What is wrong with it?

Nothing really, as long as you don't need to be doing anything else at the same time!
While the PAUSE instruction is executing, the Stamp is incapable of doing any other processing.

If you have to do a few quick things, you can put subroutine calls before each PAUSE, or you can use a PAUSE type subroutine as shown below -


pawsVAR    BYTE'variable for PAUSE routine
iVAR    BYTE'loop counter
 
Initialize the program
 
Main:
 Do action A'do some action - move a servo etc.
 Paws = 2'delay 200 milliseconds
 GOSUB Wait4it'do the delay in sections while doing other stuff
 Do action B'do some action - move a different servo etc.
 Paws = 6'delay 600 milliseconds
 GOSUB Wait4it'do the delay in sections while doing other stuff
 Do action C'do some action - pulse the Sonar etc.
 Paws = 5'delay 500 milliseconds
 GOSUB Wait4it'do the delay in sections while doing other stuff
 Do action D'do some action - move the servos back etc.
 Paws = 1'delay 100 milliseconds
 GOSUB Wait4it'do the delay in sections while doing other stuff
 GOTO Main'restart the loop
 
Wait4it:
 FOR I = 1 TO paws
     IF (something) THEN Skip'If not needed, skip action E
     Do action E'do some action needing done while waiting
Skip:    PAUSE 100'delay 100 milliseconds
 NEXT
 RETURN


That works except -

  1.   The smallest increment of time for pausing is 100 ms.
 
  2.   Action E can only be done at 100 ms times.
 
  3.   If action E takes a while, it throws off the delays set with paws. Worse, if action E sometimes takes a long time and sometimes is skipped, the delays get unpredictable.
 
  4.   The processor is STILL STOPPED during the actual PAUSE instructions so the processor performance is severely hit. In this case, 1.4 seconds is wasted each time through the Main loop.
 
  5.   If you have multiple strings of sequences trying to happen all at once, the code gets really complicated if not impossible.
 

Now let's try it again, but this time using a timer.

The timers are labeled 0 through 7 so we'll pick timer 1. The timers count in increments of 20 ms so we'll change the paws values accordingly. Timer 0 has an extra feature but we don't need that for this job. The other 7 timers are all the same so timer 1 is as good as any other.



pawsVAR    BYTE'variable for PAUSE routine
 
Initialize the program
 AUXIO'2p40 only
 SEROUT 10, 1021, [116]
 SEROUT 10, 1021, [116]'Reset Co-Processor
 
Main:
 Do action A'do some action - move a servo etc.
 Paws = 10'delay 200 milliseconds
 GOSUB Wait4it'do other stuff while wait for timer_complete
 Do action B'do some action - move a different servo etc.
 Paws = 30'delay 600 milliseconds
 GOSUB Wait4it'do other stuff while wait for timer_complete
 Do action C'do some action - pulse the Sonar etc.
 Paws = 25'delay 500 milliseconds
 GOSUB Wait4it'do other stuff while wait for timer_complete
 Do action D'do some action - move the servos back etc.
 Paws = 5'delay 100 milliseconds
 GOSUB Wait4it'do other stuff while wait for timer_complete
 GOTO Main'restart the loop
 
Wait4it:
 SEROUT 10, 1021, [129,paws]'load Co-Proc Timer 1 for paws*20ms
delay1:IF (something) THEN SkipE'If not needed, skip action E
 Do action E'do some action needing done while waiting
SkipE:Do_LOTS_more_stuff'a program's work is never done!
  'Have lots of time to do other things!
check_timers:'Let's see if any timers are finished.
 INPUT 11'Timer_Complete input from Co-Processor
 IF IN11 = 0 THEN delay1'jump back if timer not finished
  'At least one timer completed, let's find
  ' out which one.
 SEROUT 10, 1021, [119]'Send the byte command
  ' to read timeout alarm byte and clear it
  ' It gives timeout status of all 8 timers
 
 'Don't put any instructions between the SEROUT and the SERIN
 SERIN 9, 1021, [SerDIn]'Data comes back into SerDIn
 RETURN'we are only using timer 1 so it is not really
  ' necessary to see if it could have been other
  ' timers too.


What's different?

  1.   The increment of delay timing is 20 ms but that is unrelated to how often Action E can get executed.
 
  2.   Action E can happen very often during the delay. The total execution time of Action E is unrelated to the delay time except once on the last loop. (It might delay the testing of Input 11 that one time.)
 
  3.   There is no PAUSE statement where the processor is stopped and wasting time. - The only time cost is the SEROUT done once at the start of the Wait4it subroutine and the INPUT 11 and the testing of pin 11 inside the loop.
 
  4.   If multiple state machines are setting multiple timers (up to 8), they can run at the same time with little interaction unless the main CPU starts to run out of processing power. Test each timer bit separately to see if the state of the corresponding state machine gets incremented. The state machines will then know what to do at any point in time.
 
<= Back to Co-Processor page

Copyright © 2002 Blue Bell Design, Incorporated. All rights reserved.