Page 3

by David Buckley

15 February 2007

See also the original article.

Page 1 | Page 2 | Page 3

Previously we looked at the history of Zero2 then data format of the signals to control Zero2. As we said before this time we will look at the program. Like all programs which work the Zero2 control program started small and grew as more facilities were required. The first requirement was to get Zero2 to move around with simple Turtle style commands, FD BK RT LT. For correct control of the two stepper motors for the wheels, four command bytes in a particular sequence must be sent, one sequence for Forwards another for Backwards another for Right turn and yet another for Left turn. Swapping from one direction to another means jumping from one sequence to another. As explained before these sequences are:

  FD =  5, 0,10,15
  BK = 10, 0, 5,15
  RT =  6, 0, 9,15
  LT =  9, 0, 6,15

One run through a sequence moves each wheel 2mm, ie 4 0.5mm steps. By limiting the resolution to 2mm I didn’t have to worry about where in each sequence Zero2 was, they always ended on 15 which was always the right place to start another sequence.

  eg   FD 2mm, Bk2mm, RT2deg, LT2deg
  is   5,0,10,15,10,0,5,15,6,0,9,15,9,0,6,15

Now since it is necessary to send a sequence of bytes to control the stepper motors it is important to know when one byte command has been done before sending the next one. Unfortunately it is not possible to ask Zero2 ‘have you finished the byte command’ so there had to be a way for the controlling computer, in this case the QL, to wait a little before sending the next command. This could have been done with a ‘ForNext’ loop or similar but then the timing would depend on the speed of the QL, GoldCard-QL, SuperGoldCard-QL etc. One fixed delay when sending commands by RS232 is the time to transmit each byte with its Start and Stop bits. At Zero2’s baud rate of 4800 it takes about 2ms to transmit each byte. By sending the same command byte repeatedly ‘n’ times before sending the next desired command we can ensure a fixed delay of n*2ms between different commands. The individual sequences are stored in $trings. So for an overall delay of 4ms per command byte each byte is sent twice and the $tring for FD is.

  FD  5,5,0,0,10,10,15,15

At the start of the program the user is asked for a speed factor, in practice 4 is the fastest, and 20 really slow. The facor is just the number of time the byte is repeated. The resulting $trings are stored in an array mtrcmd$.

Instead of writing a user interface it seemed reasonable to continue to use the SuperBasic User interface and have all commands as SuperBasic Procedure and Functions.

After the initial set of commands to control Zero2 had been writen it was then decided to have the moves drawn on the screen.
Each of the robot commands has a call to

PROCedure processing_link (cmnd$,cmnd_code,cmnd_value)

which in turn calls all the procedure necessay for updating the screen before handing back control to the robot command procedure.
Later higher level commands such as ‘home’, were built on top of the robot control commands.
These higher level commands include ones to enable the program to remember robot commands in a list, replay the list forard and backwards, single step the list, again forwards and backwards, edit the list, store the list with others in long term memory and to recall any list from long term memory.
The top level is user written commands where they are free to do whatever they want, all Procedures and Functions are available for use.

At present the program has several levels:

  1. initialise variables and build the motorcmnd$ array etc
  2. Turtle robot control commands FD,BK etc
  3. procedures to update the screen
  4. high level robot and map commands
  5. learned lists of robot commands
  6. user written commands

Further levels were planned which would allow Zero2 to:

  • map the location of 2D map objects, black areas, by use of its inbuilt InfraRed line follower sensors.

commands to GOTO a named place or object So far these have not been done.

Volunteers welcome.

The Functions and Procedure list is as follows


100 REMark =============================================
110 REMark *** ZERO_2 Control program ***
120 REMark ver1.0, copyright  David Buckley, 11/1/86
121 REMark ver2.0, copyright  David Buckley, 31/1/86
122 REMark ver2.2, copyright  David Buckley, May 1988
130 REMark ver2.6  see below after CLEAR
140 REMark History
150 REMark -------
160 REMark 2.4 2-6-94  penmtrcmd$ introduced, <20 too fast
161 REMark 2.5 7Aug06 get_cmnd_val gave 0 for cmnd_val$>'999'
162 REMark 2.6 9Dec06 get_cmnd_val test >9999 removed, range test put in FD,BK,RT,LT
163 REMark            homing$, unwinding$ flags added, maxTurn, maxRange added
164 REMark            PROC ErrorMsg added
170 REMark ---------------------------------------------
180 REMark   *          PROGRAM           *
190 :
210 prog_version$ = '2.6'
215 REMark  directory$ ='win1_zero2_'
216 directory$ ='dos2_QL_Z2_'

220 coldinit
230 :
240 REMark   *        END PROGRAM         *
250 REMark ==============================================
260 :
270 REMark           Area for USER procedures
310 DEFine PROCedure demo
530 DEFine PROCedure wiggle
690 DEFine PROCedure squarish (d)
860 DEFine PROCedure test

890 REMark ==============================================
910 REMark =============================================
930 REMark ---------------------------------------------
940 DEFine PROCedure    init_globals
1630 DEFine PROCedure    coldinit
1760 DEFine PROCedure    zinit              :REMark USER entry
2180 REMark =============================================
2190 REMark   ***   ERROR RECOVERY   ***
2200 REMark ----------------------------------------------
2210 DEFine PROCedure    oops               :REMark USER entry
2460 REMark =============================================
2470 REMark   ***   USER ASSISTANCE   ***
2480 REMark ---------------------------------------------
2490 DEFine PROCedure    QUIT               :REMark USER entry
2550 DEFine PROCedure    help               :REMark USER entry
2760 DEFine PROCedure    exit_help
2820 DEFine FuNction    fn_wait_key$(msg$)
2930 DEFine FuNction    strip_spaces$ ( word$ )
3040 DEFine PROCedure    alert              :REMark USER entry
3100 DEFine PROCedure    buzz               :REMark USER entry
3150 REMark =============================================
3160 REMark   ***   PROCESSING LINK   ***
3170 REMark ---------------------------------------------
3180 DEFine PROCedure processing_link (cmnd$,cmnd_code,cmnd_value)
3190 REMark link robot control procedures to other processes
3270 REMark =============================================
3280 REMark   ***    ROBOT-CONTROL PROCEDURES   ***
3290 REMark ---------------------------------------------
3300 DEFine PROCedure   robot_whereabouts (cmnd_code, cmnd_value)
3310 REMark calculate robots new co-ordinates
3450 REMark ---------------------------------------------
3460 REMark   *   USER PROCEDURES   *
3470 REMark ---------------------------------------------
3480 DEFine PROCedure    home               :REMark USER entry
3780 DEFine PROCedure    unwind             :REMark USER entry
3940 DEFine PROCedure    ihome              :REMark USER entry
4050 DEFine PROCedure    sb(cmnd_value)     :REMark USER entry
4130 DEFine PROCedure    jc                 :REMark USER entry
4430 DEFine PROCedure    FD(cmnd_value)     :REMark USER entry
4560 DEFine PROCedure    BK(cmnd_value)     :REMark USER entry
4690 DEFine PROCedure    RT(cmnd_value)     :REMark USER entry
4820 DEFine PROCedure    LT(cmnd_value)     :REMark USER entry
4950 DEFine PROCedure    peninit            :REMark USER entry
5100 DEFine PROCedure    pd                 :REMark USER entry
5190 DEFine PROCedure    pu                 :REMark USER entry
5280 DEFine PROCedure    rl(cmnd_value)     :REMark USER entry
5440 DEFine PROCedure    ll(cmnd_value)     :REMark USER entry
5600 DEFine PROCedure    ls(cmnd_value)     :REMark USER entry
5720 DEFine PROCedure    hl(cmnd_value)     :REMark USER entry
5880 DEFine PROCedure    hh(cmnd_value)     :REMark USER entry
6040 DEFine PROCedure    ho                 :REMark USER entry
6130 DEFine PROCedure    hn(cmnd_value)     :REMark USER entry
6250 DEFine PROCedure    wt(cmnd_value)     :REMark USER entry
6330 DEFine PROCedure    hoot( cmnd_value ) :REMark USER entry
6510 DEFine PROCedure    flsh( cmnd_value ) :REMark USER entry
6690 DEFine PROCedure    flht( cmnd_value ) :REMark USER entry
6840 REMark =============================================
6860 REMark ---------------------------------------------
6870 DEFine PROCedure    learn              :REMark USER entry
6950 DEFine PROCedure    nolearn            :REMark USER entry
7030 DEFine PROCedure    forget             :REMark USER entry
7110 DEFine PROCedure    remember_move (cmnd$)
7190 DEFine PROCedure    rlist              :REMark USER entry
7240 DEFine PROCedure    ralter             :REMark USER entry
7460 DEFine PROCedure    rfix               :REMark USER entry
7550 REMark =============================================
7570 REMark ---------------------------------------------
7580 DEFine PROCedure    replay             :REMark USER entry
7630 DEFine PROCedure    bplay              :REMark USER entry
7680 DEFine PROCedure    do_steps ( direction )
8140 DEFine PROCedure    rstep              :REMark USER entry
8600 DEFine PROCedure    unlearn            :REMark USER entry
8750 REMark =============================================
8770 REMark ---------------------------------------------
8780 DEFine PROCedure      mlist            :REMark USER entry
8900 DEFine PROCedure    list_cmnds (title_msg$, cmnd_list$)
9250 DEFine PROCedure    exec_cmnd (cmnd_string$)
9670 DEFine FuNction    get_cmnd_num ( cmnd$, name_len )
9820 DEFine FuNction    get_cmnd_val (cmnd$,cmnd_num,name_len)
9970 DEFine PROCedure    exec_reverse_cmnd (cmnd_string$)
10330 REMark =============================================
10340 REMark   ***   LONG-TERM-MEMORY PROCEDURES   ***
10350 REMark ---------------------------------------------
10360 DEFine PROCedure    mnames            :REMark USER entry
10410 DEFine PROCedure    mexec             :REMark USER entry
10650 DEFine PROCedure    exec_routine (cmnd_num)
10790 DEFine FuNction    get_routine_start ( cmnd_num )
10910 DEFine FuNction    get_routine_length (cmnd_num )
10980 DEFine PROCedure    mget              :REMark USER entry
11130 DEFine FuNction     get_cmnd_list$ (name$)
11290 DEFine PROCedure    rsave             :REMark USER entry
11660 DEFine PROCedure    get_routines
11840 REMark =============================================
11860 REMark ---------------------------------------------
11870 DEFine PROCedure    init_windows
12820 DEFine PROCedure    display_moves(cmnd$)
12890 DEFine PROCedure    learning_screens (state)
13140 DEFine PROCedure    learning_msg
13230 DEFine PROCedure    no_learning_msg
13290 DEFine PROCedure    help_scrn
13360 DEFine PROCedure    help_scrn_1
13620 DEFine PROCedure    help_scrn_2
13850 DEFine PROCedure    help_scrn_2a
14000 DEFine PROCedure    help_scrn_3
14190 DEFine PROCedure    help_scrn_3a
14440 DEFine PROCedure    imap              :REMark USER entry
14720 DEFine PROCedure    cmap              :REMark USER entry
14920 DEFine PROCedure    drg_scrn
14980 DEFine PROCedure    draw_move (cmnd_code, cmnd_value)
15110 DEFine PROCedure    print_robot_position
15280 DEFine PROCedure    draw_robot
15605 DEFine PROCedure ErrorMsg(errortxt$,errorval)           :REMark [2.6]


Updated 15 February 2007
Part2 – In the table of motor commands RF and LF should have read

RF   mL  mR    only left wheel moves forward 2mm, ie rotation of 1deg.
LF   mL  mR    only right wheel moves forward 2mm, ie rotation of 1deg.

Page 1 | Page 2 | Page 3