CONTENTS | |||
---|---|---|---|
Introduction | 1.1 | ||
Hardware overview | 1.2 | ||
Powering up | 1.3 | ||
SOFTWARE | HARDWARE | ||
About FORTH | 2.1 | Instructions for using Z-cards | 11 |
Understanding FORTH | 2.2 | Available modules | 11.1 |
Structure of FORTH | 2.3 | Z-card bus | 11.2 |
Getting Started | 2.4 | Input-output addressing | 11.3 |
Interfacing with the outside world | 3 | Basic robot I/O (input/output) | 11.4 |
Mixed precision and Trigonometry | 4 | Serial ports | 11.5 |
Saving on Disk | 5 | Electric Gripper drive | 11.6 |
Supervisory software | 6 | Power Supply | 11.7 |
Turnkey operation | 7 | General purpose I/O expansion | 11.14 |
Interrupts | 8 | Analog and Digital I/O card | 11.15 |
Memory Map | 9.1 | I/O signal conditioners | 11.16 |
TIL Characteristics | 9.2 | Remote E-stop circuit | 11.17 |
Information block | 9.2.8 | Connector Pin-outs | 12 |
FORTH Glossary | 10 | ||
Terminal and Input/Output Words | 10.2 | ||
Data Words and Constants | 10.2 | ||
Arithmetic Words | 10.4 | ||
Defining Words | 10.5 | ||
Control Words | 10.6 | ||
Timing Words | 10.7 |
The K11R robot controller is modular system based on the eZ80L92 pipelined 16-bit microprocessor. Memory is static RAM which is loaded from flash EPROM upon power up or reset. All the I/O devices and RAM run at the full processor clock speed without wait states and there are no system interrupts unless you create them. So input/output oriented software runs much faster. The controller's language is an implementation of FORTH called Tiny FORTH or TIL (Threaded Interpretive Language) which is concise and efficient. It has the dual advantages of speed and very low memory usage which has made it possible to get a highly complex system into the controller's minimal address space.
The controller comprises a bench top rack style enclosure containing all power supplies, motor drives and logic cards. There are two logic cards, the CPU and the DSP plugged into an internal bus with space for 2 more cards.
Communication with the computer is via an RS232 connector on the front panel and the teach pendant also connects there. All other connections are to the rear panel. If your computer has USB but not RS232 then ST will supply a converter.
There are two relays in the the enclosure: one is a reservior discharge relay as required for CE safety marking and the other is the E-stop extension relay whereby all external E-stop devices are in series and if any device breaks a connection the relay drops out and sends a signal to the software to stop all motors. The circuit runs via a rear jack socket and the controller has a jack plug in that socket with its two terminals linked. Therefore if the jack is removed the robot can not run.
Now connect the computer and switch on the power. The PC should display a message which includes the words "COLD START". The key may now be turned (with power on or off) to the warm start position once you have USAVED your program. If you leave it in the cold start position then any programming you do will be lost when power is next switched on. Note that pressing the reset button is the same as switching power off/on. Cold start could be re-selected deliberately, however, to erase all programs e.g. after a practice session.
Enter ROBOFORTH and press return.
All the key-words and commands in FORTH are organised as a linked list or "dictionary". With each word in the dictionary is kept its definition, as with a conventional dictionary. Each word in the command line is looked up in the dictionary and its "meaning" is executed. If FORTH cannot find the word and it is not a number the word is rejected and the rest of the line ignored.
At its lower levels FORTH can be somewhat cryptic, but it does allow access to the whole machine, like assembly language, yet permits the generation of very high level functions. Programming the machine is done by adding new words to the dictionary, defined in terms of existing words, Yet user software is semi- compiled so is much faster than an interpreter. This combination of speed and high level power makes FORTH particularly suited to the control of machinery. It is also concise and compact (i.e. occupies less memory).
If you already know about FORTH please skip this section. Go directly to 3. Interfacing with the Outside World
Without wishing to embark on a tutorial on FORTH, I would just like to outline the fundamentals of FORTH for the benefit of readers not acquainted with the language.
Note: In all my examples of exchanges between man and machine I will show text typed in by the user in green and underlined. I won't keep mentioning the need for the RETURN (or ENTER) key. The computer's response will be in upper case, and not in green. My comments will be in lower case.
There are probably five fundamental characteristics-
Commands and numbers are typed in by the user, separated by spaces, finishing with return. FORTH then scans the user's line acting on each word, and if everything works out OK then FORTH types OK.
All arguments are passed between procedures on a data stack. A stack is an area of memory into which values are placed temporarily on a last-in first-out basis. Variables are used, but not as much as in other languages.
Part of the reason for this is to maximise the performance of the system. Suppose you wish to add 4 and 5 together and print the result:- In the BASIC statement PRINT 4 + 5 the operator '+' gets one of its "arguments" (values) from its left, and the other from its right. This may seem logical to humans but a machine must first organise its arguments before it can do arithmetic, and almost any language will first convert a formula to items on a stack. The equivalent in FORTH is therefore:-
>4 5 + . (return) 9 OK
FORTH scans the user's input line and first puts 4 on the stack, then puts 5 on the stack. The FORTH word '+' then takes two values off the stack ( 5 and 4 ). adds them together and puts the answer back on the stack, the value 9. The FORTH abbreviation '.' then prints it. This is sometimes called post-fix notation.
There is now nothing on the stack. If we try to print again we get the message "STACK UNDERFLOW!" which is not OK.
But the FORTH data stack doesn't exist to make everyone think like a machine. At worst post-fix notation is a minor inconvenience. Imagine that we wish to calculate the total content of two tanks of chemical. Each tank has a transducer in it with a complicated service routine, as follows:-
1 Select the transducer and energise.
2 Allow the signal conditioners to settle.
3 Read the ADC.
4 Scale the result according to the calibration factor of the
transducer.
5 Leave the scaled result on the stack.
Each tank has it's own service routine, called LEFT-TANK and RIGHT-TANK. The total of both tanks is given by:-
LEFT-TANK RIGHT-TANK +
Now LEFT-TANK and RIGHT-TANK are not values! Nor variables. We are not doing PRINT X + Y. They are whole procedures which leave their results on the stack. There can even be other words between LEFT-TANK and RIGHT-TANK as long as they don't take off or put on extra items on the stack for example:-
LEFT-TANK BLA-BLA RHUBARB RIGHT-TANK + .
Though the stack is used extensively to pass arguments, variables also exist and are handled with the words ! ("store") and @ ("fetch"). ! means "store the second value down on the stack into the address which is the top item on the stack. @ means "fetch the contents of the address on the stack and leave it in its place".
Instead of a handful of keywords as in, for example BASIC, there are hundreds of words, which are organised in a "dictionary". FORTH interprets a user's word by searching down the dictionary until it finds it, then carries out the activity which is in the "definition" of the word. If the word isn't in the dictionary then FORTH tries to convert it as a number. If it isn't a valid number either then FORTH declares it an error.
Most LOW level words in FORTH tend to be abbreviations, or single characters, for example the FORTH word for "print" is just a dot (.) whereas higher level procedures tend to have highly descriptive names. Abbreviations have agreed pronunciations, e.g. dot (.) is pronounced "print", ! is pronounced "store", @ is pronounced "fetch" etc. Pronunciations will be given as they arise.
This principle is fundamental to FORTH users. It is the building-block approach to programming.
FORTH, in its basic form, consists of a "kernel" of some 150 or
so "words" or commands, most of which are "primitives" i.e. they
directly execute machine code whenever they are used. The
programmer must define new words in terms of words already in the
kernel. He/she can then define higher level words in terms of
words he/she has already defined plus words from the kernel as
necessary. These new words are added to the existing dictionary.
Hence the programmer begins by defining short concise procedures
which can be tested individually. In this way the user builds up
a range of fully tested modules which are then used to construct
more powerful procedures, and so on until the final application
programme is complete, which can be just one word. The modular
approach imparts a very high degree of confidence to the final
application.
New procedures are created using a colon sign, followed by the name of the procedure, then the definition ending with a semi- colon, for example-
: TANKS? LEFT-TANK RIGHT-TANK + . ;
Now all you have to do is type TANKS? to yield the total in both tanks, or alternatively TANKS? can be included in the definition of some grander procedure.
Note that in this version of FORTH all words are stored in the dictionary as a length figure followed by the first 5 characters only of the word. Sometimes ambiguity has to be avoided, for example LATHE1 and LATHE2 have the same lengths and the same first 5 characters so 1LATHE and 2LATHE are better words.
Because the K11 CPU (but not its DSP) is a byte (8-bit) oriented machine values are stored in two successive 8-bit
memory locations. The highest value 8 bits occupies the highest memory address. The word @ fetches
both bytes as a 16 bit value and the word ! writes back two 8-bit values in succession.
To obtain the necessary memory space the K11 has two banks of 64k 8 bit memory. These
are addressed using one 16 bit address and a value in a location called BANK. When
BANK is 0 this refers to the frst 64k and when BANK is 1 this refers to the second 64k.
8-bit (single byte) values can be manipulated using FORTH words like C@ C! C1SET
(the C is historical and stands for character i.e. byte) and IN and OUT.
These values occupy 16 bit stack entries, with the highest 8 bits all zero.
There is also a 32-bit precision occupying 4 locations and accessed with 2@ and 2!
(2 for double precision).
For extended memory the words are E@ and E! These fetch or store from 2 successive locations in
memory bank 1.
The structure of a FORTH word is as follows:-
First there is a header. This is the dictionary entry containing the spelling of the word plus a link to the previous word in the dictionary. The dictionary is a linked list of words which enables any word to be found by following the links. Next is the code field. This is the 16-bit address of some machine code which determines what the word is actually going to do.
Next is the parameter field. This is a list of 16-bit values
which may be data, as in an array, or only one value for a
variable or a constant. If you had defined the word as a
procedure in terms of other words then the parameter list would
comprise a list of the other words' code field addresses. These
other words may also comprise lists of other words and so on, and
this is why FORTH is called a "threaded interpreter". Whenever a
word is executed the threads are followed deeper into the
dictionary until machine code is found.
Please see TIL Characteristics
Consider the example:
>42 CONSTANT STAR OK
The header contains the word "STAR". The code field points to
some machine code which takes the contents of the parameter field
and puts it on the stack for following words to use, e.g.
>STAR EMIT * OK
The parameter field is 2 bytes long and contains the value 42.
Words defined with the defining-word VARIABLE leave the address
of their parameter fields on the stack, so that the contents of
the parameter fields can be fetched using the @ sign, or values
can be stored back using the ! sign. e.g.
>VARIABLE STAR OK
>42 STAR ! OK
>STAR @ . 42 OK
To define a procedure the defining-word used is the colon sign (:) which puts the system into compile mode so that words which follow in the definition are looked up in the dictionary, and their code field addresses are added to the PARAMETER list of the new word. The value put into the CODE field is the address of some machine code which, when the new word is executed, will begin the process of following the threads and executing the machine code found at the bottom of each thread. The machine code which follows the threads down and back up, keeping track of where it has got to in each word, is called the "inner interpreter". Code at the end of each list tells the inner interpreter to end this word and return to the next level up. The inner interpreter is concise and efficient to ensure fast execution of high level definitions. The "outer interpreter" is itself a word which gets the users commands and executes them, checking for errors etc.
When the system is cold-started (see powering up) it automatically adopts the hexadecimal numbering system. This is frequently more appropriate for controlling binary entities such as analog-to-digital converters, memory and port addresses etc. but real engineering units are best handled in decimal, so before anything else enter:
>DECIMAL OK
It is now ESSENTIAL to read a recommended book as it is beyond the scope of this manual to include a full tutorial. In the absence of such a book then refer to the GLOSSARY before continuing. By way of advice programming should begin by thinking out a control problem from the top down, i.e. try to decide the program flow at the highest level, and then break it down into smaller parts as you think out the problems of interfacing with external machinery etc. Then begin to code the lowest levels. Where possible try to use the stack and not variables because this can save alot of execution time in lower level words.
The word PULSE is not part of FORTH or ROBOFORTH so you would add
it thus:
: PULSE OVER OVER ON 1000 MSECS OFF ;
Let us trace its operation on the values PA 2 e.g. PA 2 PULSE
Stack | Instruction | Index PA | PA | PA 2 | 2 | PA 2 PA | OVER | PA 2 PA 2 | OVER | PA 2 | ON | (uses up one set of PA 2) PA 2 1000 | 1000 | PA 2 | MSECS | (uses up the 1000 for 1sec delay) | OFF | (OFF uses up the remaining PA 2)
The following examples apply to the basic I/O which is part of the CPU card. Additional I/O cards such as 11-48 and 11-56 are similar but have different port names.
The CPU has three ports which are called PA PB and PC.
TO OUTPUT connect to PA as indicated on connector pinout. Suppose there were an air solenoid connected to PA 4. You could turn it on with:-
PA 4 ON
and off with:-
PA 4 OFF
A better idea would be to define AIR as follows:-
: AIR PA 4 ;
Now you can type (or include in a higher level definition):-
AIR ON and AIR OFF
TO INPUT connect to PB as indicated on connector pin-out.
Suppose there were a switch on PB bit 4 which made PB 4 logic
zero when closed, but logic '1' when open (see connector pin-
outs) You could define a word:-
: SWITCH PB 4 BIT? ;
This can be tested thus:
SWITCH . 16 (meaning switch is open) (note 16 decimal = 10 hex)
SWITCH . 0 (meaning switch is closed)
Suppose you would like to synchronise some activity to an pushbutton connected to PB 4. For the purposes of words like IF and UNTIL any value is TRUE and zero is FALSE. Using the FORTH building block approach definitions could be built up as follows:-
: HI BEGIN PB 4 BIT? UNTIL ; -or- : HI BEGIN SWITCH UNTIL ;
BEGIN ... UNTIL is a loop which executes all the words between
BEGIN and UNTIL. A condition (true of false) must be on the stack
before UNTIL. If the condition is false (zero) then the program
loops back to BEGIN but if it is true (non-zero) it drops through
to the next word.
: LO BEGIN SWITCH 0= UNTIL ;
The word 0= takes a stack value and if it is zero leaves a true
(non-zero) which satisfies UNTIL. This is similar but the signal
must be zero to drop out of the loop.
So HI waits for the incoming signal to go high and LO to go low.
: WAIT-PB LO HI ; waits for the pulse to go low then high i.e.
the button must be pressed then released.
Suppose you wanted to scale a measurement from the analog-to-
digital converter by a factor of, say, 0.514 . You would expect
to do this in FORTH as follows:
ADC 514 * 1000 /
The trouble is that if the ADC output is any larger than 63 the
multiplication will produce NUMERIC OVERFLOW because the result
would have been larger than 32767. We therefore need the
precision of 32 bits for the multiplication only and so the
correct expression is:
ADC 514 M* 1000 M/
M* multiplies two 16 bit values and leaves a 32 bit value. M/ divides a 32 bit value by a 16 bit value and leaves a 16 bit answer. 32-bit values occupy two stack levels, with the most significant 16 bits on the top of the stack.
Although all values are integers they can have implied decimal
points. For trigonometry all angles are in degrees with two
implied decimal points, for example the value 1234 represents
12.34 degrees; 90 degrees is entered as 9000. The result of a
sine or cosine is a fraction with 4 implied decimal points. Note
that hexadecimal numbering is not appropriate.
Examples:
>DECIMAL OK
>6000 COS . 5000 OK i.e. the cosine of 60 degrees is 0.5.
>5000 ASIN . 3000 OK i.e. the arc-sine of 0.5 is 30 degrees.
Functions included are SIN (sine) COS (cosine) ASIN (arc-sine)
ACOS (arc-cosine).
TAN is not included but TAN is SIN/COS. You could define your own
function thus:
>: TAN DUP SIN 10000 M* ROT COS M/ ; OK
5. SAVING ON DISK
5.1 Using ROBWIN click file, open (or file, new) to open a text file. To download this to the controller click file, download current. If you edit the text remember to FORGET the first word in the text before reloading. It is best that this word be a USER variable (see 10.5) because FORGETting a USER variable also recovers the data area as well as dictionary space.
5.2 LOW LEVEL DATA TRANSFER PROTOCOL
The host must be connected via its serial port set up for 19200 baud, no parity, 8 bits, 1 stop bit. The baud rate can be changed to higher (or lower values) (see 11.5. An extremely simple protocol is employed:
UPLOADING
To initiate uploading from the controller to the host the host
must send an ENQ (5) character to the controller. The controller
has first been given the TRANSMIT command and the host computer
must also be in some routine to upload and write data to disk,
with the file already open.
The controller then sends an STX (2) to the host followed
immediately by one block of 256 (100hex) bytes of data.
The controller then waits for the host to send another ENQ and
sends another STX(2) and the next block of 256 bytes. This
repeats until all blocks are sent. When all data is transfered
the controller's answer to ENQ is not STX but ETX (3). When the
host receives ETX instead of STX it finishes the routine and
closed the file.
DOWNLOADING
To initiate downloading from host to controller the host sends an
ENQ and waits for STX from the controller. The controller must
first have been given the RECEIVE command and the host must also
be in some routine to read data from disk and download it.
The host then sends one block (256 bytes) to the controller.
The host then sends another ENQ and waits for another STX then
sends the next block. This repeats until all the blocks have been
downloaded.
The host then sends sends ETX instead of ENQ meaning no more data
and the host then stops.
BANK SELECT
Before using either of the above commands you must specify which of the two memory banks you want to read/load. All coordinates data is in bank 1 so before sending TRANSMIT or RECEIVE use
BANK C1SET
Or, if the data is in low memory use
BANK C0SET
then TRANSMIT or RECEIVE
The host computer can control the controller by sending commands down the RS232 serial link. The host software should start by opening the serial channel e.g.
OPEN "COM1:19200,N,8,1,CS,DS,CD" AS #1
The commands can then be PRINTed to the controller e.g.
PRINT#1,"PURGE". Each character you send to the controller is echoed back (unless you are in HIDE mode) until the 0D (return) is sent then the controller sends back a space character (20h). There is then no response until the controller has completed the command. All these echoed characters can be allowed to accumulate in the input buffer.
After executing the command the response should always end in a sequence of 5 characters:
O K cr lf >
This response may come (a) immediately, (b) after some unkown
time, (c) not at all (in the case of some task which never ends).
The host software should look for the >. The preceding string
should therefore be OK, if not then there was some error message.
In case (c) the host can continue some other task without
waiting.
Suggested flow chart for communication with the controller:
NOTE: All characters which come back from the controller must be used up or "buffer overflow" will occur.
In many cases it is desirable to have a program run as soon as power is switched on rather than have to type something every time. In these cases the program to run is a single word, or you might have to generate a new word e.g.:-
: DEMO INITIALISE MAIN-PROG ;
The word DEMO can be made to execute immediately on power-up by setting the switch on the front panel to the auto position (see diagram 2) and entering:-
AUTO DEMO and follow with USAVE to save to flash ROM.
Before ever DEMO is forgotten, or words below it re-compiled the key switch must be put back to warm start position until AUTO is used again.
The interrupt vector table has only two entries, both to the same interrupt code:
Interrupt from external signal.
A PB input (usually PB 6) should be connected to TP1 on the CPU card.
Look for TP1 on the top side of the board and insert a short piece of tinned copper wire through the hole. Solder one side. Turn over the card and put a length of insulated wire from TP1 to PB 6 (or any PB you prefer). A large orange wire was used in the picture below for visibility but normally a thin prototype wire would be used.
If enabled the chosen word in Intvec will execute upon change of state of PB 6 from high to low.
Enable interrupts with a jump to enh (see Information block). Disable with a jump to dish (see information block).
In RoboForth see section 8.5
On an interrupt occurring further interrupts are disabled. The jump to intret re-enables interrupts. Using a jump to xintret (see Information block) instead of intret leaves interrupts disabled.
Timer interrupt.
A CPU timer can be set to interrupt every n milliseconds. Every n mSecs the chosen word in Intvec is executed. The maximum time is 500 mSecs. To start the timer put the value in mSecs times 125 on the stack and jump to entim (see Information block). To stop the timer jump to distim (see Information block). On an interrupt occurring further interrupts are disabled. The jump to intret re-enables interrupts.
Because of interrupt conflicts do not use the word USECS in any interrupt definition.
You should find it easier to use higher level RoboForth commands
NMI (non maskable interrupt) works as before. Any NMI will cause a call to 66hex and place the value 80hex in INTFLAG at address 9D03 (only one byte). It is up to ROBOFORTH programming to read INTFLAG (with INTFLAG C@) and take any necessary action.
Byte | Function |
1 | length of word string plus control bit |
2-6 | first 5 characters of word |
7,8 | link address i.e. address of next word down in list |
9,10 CODE FIELD ADDRESS (CFA) found by FIND |
If a primitive: a pointer to the next 2 bytes where machine code starts If CREATEd or a VARIABLE: a pointer to routine which puts the address of the parameter field on the stack If a CONSTANT: a pointer to code which will put the contents of the parameter field on the stack. If a word definition: a pointer to the inner interpreter to start interpretation of the parameter list (colon). If a word defined by a defining word: a pointer to code following DOES> |
11 on PARAMETER FIELD (PFA) found by ' (single quote - "tick") |
If a primitive: machine code.
If a CONSTANT: value of constant. If word definition: parameter list i.e list of codes of compiled words, finishing with a pointer to the inner interpreter to stop (semi-colon). If a VARIABLE: stored value of the variable. If a USER variable (see 10.5): it is the address of the actual RAM location of the value. |
From above you may see that ambiguous word names are possible
because the word is represented as a length plus only the first
five letters. If you type VLIST the entire vocabulary will be
listed, and the missing characters are printed out as dots. Some
FORTHs have variable length headers but the fixed length makes for a
faster dictionary search resulting in faster compilation of new words.
If a new word has the same 5 starting letters as a previous word
then check the lengths. If same then choose a new name.
Some words in TIL behave differently from their equivalents in FIG ( Forth Interest Group ) or FORTH '79 standard. These words are listed below:
DUMP (and EDUMP) - prints contents of memory in hexadecimal The start of the dump is rounded down with the actual address indicated by an asterisk in the top line. In other FORTHs this has two arguments: memory address and number of bytes to dump. In TIL only the address is required. Press space bar for the next line of 16 bytes, press return to stop the dump.
LOAD - in other FORTHs n LOAD loads the screen n from disk. In TIL n is a memory address. v15 up - disabled.
VLIST - in other FORTHs this lists the entire vocabulary across the screen, unformatted. In TIL, VLIST lists the vocabulary in the following format: address of dictionary entry i.e. header, not CFA or PFA; length of word name; word name, with any characters after the fifth printed as dots. See variant 'VLIST below. VLIST will print "0 words" when tried the first time with un-initialised memory - repeat the command.
<# # #S and #> work with 16-bit numbers only.
Words which do not exist in other FORTHs are:
ASK CODE C0SET C1SET EDBUF EDLOAD INKEY INC IOFLAG MSQ MSQR
PURGE SIN ASIN COS ACOS USER and UVP 'VLIST #. U. <>
See section 10.
Some words exist in the system but cannot be used:
FREEZE - sets the cold start parameters for example pointer to the top of the basic (kernel) dictionary when powered up in cold start mode. Has no effect because these parameters are in EPROM.
SETFORTH - sets the boundary of the FORTH vocabulary at cold start. Has no effect because this is also in read only memory.
DOS - exit TIL to SSD disk operating system which is not installed.
DLOAD, READ, WRITE, DLIST, DLOOK - disk commands - would apply only to the solid state disk system if installed.
If you use up a stack value when there is none the message is "STACK UNDERFLOW". This check is not made until your word has fully executed and command mode is re-entered, so too much stack underflow in your word can crash the system.
"NUMERIC OVERFLOW" - result of signed multiply exceeding 32767 or 7FFF hex, or unsigned multiply exceeding FFFF hex or the result of M* exceeding 7FFF FFFF hex.
"DIVIDE BY ZERO" - also fatal error i.e. program cannot continue through such an error.
"ILLEGAL" means you used a compile-only word e.g. a control word or sem-colon (;) when not in compile mode.
"NO DOS" no disk operating system installed.
"DISK ERROR" worse!
While compiling there are no syntax checks in TIL to make sure you use the same number of opening control words as closing control words - e.g. same number of IFs and THENs. During compilation of control loops starting words push addresses to the stack, which are then popped off when ending words are compiled. Thus if loop starts are not matched with loop ends then stack errors will occur:
"STACK UNDERFLOW" - indicates more ending words than starting words eg. more THENs than IFs.
After a definition try X. You should, of course, get the stack underflow message, so if you do not then it is an indication of more starting words than ending words.
If there is no response at all to typing X. then you are still in compile mode (missing semi colon).
Unexplained errors such as unwelcome cold starts or total crashes are usually the result of mis-matched IFs and THENs, or AN IF- THEN or DO-LOOP or BEGIN-UNTIL loop which is physically longer than 127 bytes after compilation. (Remember that each word in a definition reduces to 2 bytes.) Use of ! or any word containing it with incorrect or missing arguments could store some unknown value in some unknown part of memory, for example in the middle of your dictionary. This condition can be corrected by doing a cold start and re-entering or re-loading your software.
New words are linked to the FORTH vocabulary but form part of the
user's vocabulary. Searches start from the top of the dictionary
downwards, so if the user creates a word identical to that in
the original FORTH then only the new definition will be found.
ROBOFORTH and the user's dictionary are treated as one vocabulary.
There is a boundary between words in the original FORTH vocabulary
and the ROBOFORTH plus user vocabulary. By typing FORTH searches
will begin at this boundary; by typing ROBOT then searches will
start from the top of the dictionary.
EXAMPLE:-
HEX : ASPACE 2A ; : TEST ASPACE EMIT FORTH ASPACE EMIT ROBOT ASPACE EMIT ; TEST * *OKTEST uses ASPACE in two contexts, and prints two asterisks separated by a space.
: Q 1- DUP 0 > IF Q THEN ;
Q will recursively decrement the value on TOS to zero. Unfortunately the second Q will not compile, being not yet part of the vocabulary until after the definition is complete (semi- colon). The line would, therefore, be entered as follows:
: Q 1- DUP 0 > IF LATEST Q THEN ;
The following addresses are significant:
FORTH
0400 : start of FORTH kernel, cold start entry point.
0417 : High byte of address of start of RAM area.
0418 : FORTH vocabulary boundary.
041A : Version number.
041B : Maximum number of characters stored for each word.
041C : Low byte address of upper limit of dictionary area.
041D : High byte address of upper limit of dictionary area.
041E : Low byte address of outer interpreter.
041F : High byte address of outer interpreter.
0420 : Warm start entry point.
0423 : Auto-start entry point.
042B : Vector to input routines CIN.
042F : Start up number base.
BIOS
A022 : Intvec (address for the CFA of an interrupting word.)
03C4 : Address of the above. To change the address of intvec change the contents of 03C4.*
0360 : entim
0363 : distim
0366 : enh
0369 : dish
036C : intret
036F : xintret
* note that the values in these addresses are in a protected part of memory and can not be saved to flash. Any changes to these values are lost if the system resets.
Note: TOS means top of stack.
Note: 1 byte variables must be moved with C@ or C!
Back to Contents
HERE - puts dictionary pointer on stack.
STATE (1 byte) - puts address of mode byte to stack (contents: 1 = compile, 0 = interpret).
DP - puts address of dictionary pointer to stack.
UVP - puts address of user variable pointer to stack.
UVP @ is the next address for the next user variable.
CONTEXT - puts address of context pointer to stack. This contains
the address of the word at which the dictionary search starts.
CURRENT - puts address of current pointer to stack. This contains
the address of the word to which any newly created word is linked.
DEFINITIONS - causes new words to be added to the current vocabulary
FIND (word) - returns address of code field of the word following
FIND. If not found leaves zero.
' (word) - ("tick",single quote) - returns address of parameter field of the word following tick. If not found then aborts.
EXECUTE - (addr) EXECUTE - executes the word whose code field address is on the stack.
BASE (1 byte) - contains ruling number radix.
DECIMAL - converts number system to base 10.
HEX - converts number system to base 16.
CALL - (addr) CALL - calls code at address (addr) which must end in RET if it is intended to return to FORTH. Do not use EXX as FORTH needs those registers, also do not use the IY or IX registers. (unless you save them first)
( - comment. All text after "(" is ignored, until a ")"
character is encountered.
FORTH - makes the FORTH vocabulary the context vocabulary, by-
passing user's vocabulary.
ROBOT - makes the ROBOT vocabulary the context vocabulary.
LATEST - makes the LATEST vocabulary the context vocabulary including the word currenty being defined. (see Vocabularies and Recursion)
'S - puts the address of the start of the data stack onto the
stack.
S0 - puts the address on the stack of a pointer to a location of
the value of the stack pointer, i.e S0 @ X. yields stack pointer.
.S - prints out the contents of the stack without losing them.
>IN - address of the variable holding a pointer to the position
in the line input buffer currently being read.
PAD - a constant location of RAM used by text input and output.
TOP - a constant, value is the address of the top of the RAM area
used for user variables, system variables and stacks.
QUIT - restarts outer interpreter.
EDIT - OBSOLETE - do not use (jumps to an editor which is no longer installed).
FREEZE - sets cold start parameters for a cold start. (dead)
SETFORTH - sets FORTH boundary to top of dictionary. (dead)
(n) SAVE - writes RAM to FLASH ROM. n is a sector number 0 to 7, where a sector is 4000hex. Sectors 0-3 are in bank 0 and 4-7 are in bank 1. Sector 0 is protected EPROM.
DICLEN (constant) - number of characters stored in a dictionary
entry (see information block)
AUTO (word) - makes the following word execute on power up.
TURNKEY - variable containing the code-field-address of the word
which is executed on power up.
BANK - pseudo-variable containing bank number - 0 is first 64k, 1 is 2nd 64k and so on.
(n) JUMP - jump to address n. Re-enter FORTH at 420hex. Do a cold start with ORG JUMP
or 0 JUMP.
CR - carriage return and line feed.
X. - (n) X. - prints (n) in hex, 4 digits followed by space.
KEY - wait for key to be pressed, leaves its ASCII value on stack
EMIT - (n) EMIT - send (n) to screen.
BEEP - beeps computer (sends ASCII 7)
OUT - (n) (port) OUT - sends (n) out via port address.
IN - (port) IN - reads port address (n), leaves value on TOS
." ("dot-quote") - syntax: ."(space) (text)" types text as
written including any inbedded control characters up to " mark.
Note: CAN ONLY BE USED WITHIN A COLON DEFINITION
TYPE - (addr) (n) TYPE - types out (n) characters from address
(addr). Printing will stop if an ETX (3) is encountered.
EXPECT - (addr) (n) EXPECT - waits for (n) characters to be typed
by the user, these are directed to a string address (addr).
Terminates when return key is pressed. The string will end with
ETX (3). All positions in the string from when return is pressed
until (addr)+(n) are filled with space characters. (see NUMBER)
The rules for entering type string are the same as for entering
commands. Control characters are: rub-out or back-space = delete
last character typed, control-Y = delete entire line, return =
enter the line, esc key = abort whatever is happening and go to
command level.
WORD - (n) WORD (word or string) - reads further along the input
buffer and copies the next word in the buffer to HERE and leaves
its address on the stack. (n) is the ASCII value of the character
at which copying will stop ( normally 20 hex (space)). The first
byte at the address (HERE) is a character count, followed by the
actual characters, followed by a space character. No use in
immediate mode because as overwritten by next command.
NUMBER - (addr) NUMBER - where (addr) is the address of a numeric
string. If the first byte is a character count this will be
ignored. The string delimiter will be any non-numeric character.
COUNT - (addr) COUNT - taking a string at address (addr) which
starts with a character count it leaves the count on the stack
with the address of the string itself (addr+1) below that.
LOAD - (addr) LOAD - reads text from the RAM address given into
the line input buffer as if it had been typed. The delimiter for
the edit buffer text is the byte FF hex. v15 up. (discontinued)
IOFLAG (1 byte) - bit 7 set means read disk buffer, lower 4 bits
are device no. for prints and EMIT.
? - immediate examination of a variable, pseudo-variable or any memory address in bank 0.
Addresses and pseudo-variables in high memory must be examined with E@ .
EDBUF - constant, leaves address of edit buffer. (discontinued)
EDLOAD - compiles edit buffer contents - as EDBUF LOAD (discontinued)
INTERPRET - acts on next word in input stream (line buffer).
INKEY - tests the terminal to see if a key has been pressed. If
so leaves the ASCII value; if not leaves zero on TOS. Does not
wait for key to be pressed.
(n) LINES - line feeds n times
?TERMINAL - test the terminal to see if escape has been pressed.
If so leaves true (1) else leaves zero on TOS.
CTRL-C - test the terminal to see if control-C has been pressed.
If so leaves true (1) else leaves zero on TOS.
control-C is ETX (end of text) code 3 (See STX and ETX below)
ASK - gets a signed number from user straight to stack in ruling
number system. If number is invalid a zero is returned.
DUMP - (addr) DUMP - dumps memory contents of low memory (bank 0) starting at (addr), 16
bytes per line advanced by space bar. Return key to stop dump.
EDUMP - (addr) EDUMP - dumps memory contents of hi memory (bank 1) starting at (addr), 16
bytes per line advanced by space bar. Return key to stop dump.
. ("dot") - (n) . - prints (n) from the stack according to ruling number base
preceded by sign or space and followed by one space. Use of .(dot) resets BANK to zero.
SGN - flag used by <# and SIGN, used for "dot".
SPACE - prints one space character.
SPACES - (n) SPACES - prints (n) spaces.
The following words are for formatted print. They are the same as
FORTH '79 but work with single length numbers not double length.
<# - prepares PAD for number conversion, used in . (dot).
HOLD - inserts character into PAD, during . (dot).
# - converts one digit from TOS to PAD.
#S - converts all TOS to digits in PAD, destroys TOS.
SIGN - inserts sign into PAD during . (dot).
#> - finishes number conversion and leaves the number of characters on TOS and the address of them at TOS-1.
#. - prints TOS in an 8 character field including a space and a negative sign if negative
(n) HEXDIGIT - prints (n) as a hexadecimal digit, 16 > (n) > 0
VLIST - lists entire (selected) vocabulary in the format: address of
dictionary entry ( 6 bytes less than CFA ), character count, word
spelling up to 5 characters, excess (unknown) characters as dots.
When VLIST is used the first time, i.e. with un-initialised
memory, it may only yield "0 words". Simply repeat the command.
'VLIST (word) - (pronounced tick-vee-list) lists all words in the
dictionary of a particular type, follow with an example of
the type of word. For example if SPEED is a variable then
'VLIST SPEED will list all variables.
ASPACE - pushes a space character to stack - i.e. a constant of
value 20 hex.
0 - A constant of value 0
1 - A constant of value 1
STX - A constant of value 2
ETX - A constant of value 3
ENQ - A constant of value 5
! ("store") - stores TOS-1 into address on TOS. Both removed from stack.
@ ("fetch") - gets data from address on TOS and replaces TOS.
+! - adds TOS-1 to location given at TOS ie. the expression b=b+a would be written a b +!
C! ("see store") - stores 1 byte of TOS-1 at TOS address. Both removed from stack.
C@ ("see fetch") - gets 1 byte from address at TOS and replaces TOS with it.
E! ("E-store") - stores TOS-1 into address in high memory on TOS. Both removed from stack.
E@ ("E-fetch") - gets data from address in hi memory on TOS and replaces TOS.
EC! ("E-C store") - stores 1 byte of TOS-1 at TOS address in high memory. Both removed from stack.
EC@ ("E-C fetch") - gets 1 byte from address at TOS and replaces TOS with it.
X! ("X-store") - stores TOS-1 into address on TOS in low or high memory depending on the value
in BANK. Both removed from stack.
X@ ("X-fetch") - gets data from address in low or high memory depending on the value in BANK on TOS and replaces TOS.
X+! ("X-plus-store") - adds TOS-1 into address on TOS in low or high memory depending on the value
in BANK. Both removed from stack.
2! ("two-store") - stores TOS-2 into address on TOS and TOS-1 into the next address.
2@ ("two-fetch") - fetches data from address on TOS and next address leaving data from the address
on TOS-1 and data from address+2 on TOS.
DUP ("doop") - a DUP --> a a.
DROP - removes top of stack.
SWAP - a b SWAP --> b a
OVER - a b OVER --> a b a
ROT - a b c ROT --> b c a
PICK - (n) PICK - picks the nth item from the stack and places a copy on top of stack, e.g. a b c d 2 PICK leaves a b c d c.
C0SET - changes byte at location given at TOS to zero.
C1SET - changes byte at location given at TOS to 01.
1+ - increment TOS.
1- - decrement TOS.
2+ - increment TOS twice (adds 2 to TOS).
2- - subtract 2 from TOS.
2* - multiply TOS by 2, unsigned (shift left).
2/ - divide TOS by 2, unsigned (shift right).
R> - move top of return stack to top of data stack.
>R - move top of data stack to top of return stack.
R - copies top of return stack to top of data stack.
= syntax: a b = leaves 1 if a=b or 0 if not (1=true).
> syntax: a b > leaves 1 if a greater than b
< syntax: a b < leaves 1 if a less than b
<> ("not equal") syntax: a b <> leaves 0 if equal, 1 if not equal.
0= - removes TOS and leaves true if TOS was zero
OR - 16 bit inclusive OR.
XOR - 16 bit exclusive OR.
AND - 16 bit and.
INC - increments contents of address on stack.
CMOVE - moves data block from one memory area to another,
syntax: (source) (destination) (number of bytes) CMOVE.
ECMOVE - moves data block from one memory area to another both within high memory (bank 1), syntax: (source) (destination) (number of bytes) ECMOVE.
The destination and source data must not overlap.
MOVUP - moves data block from low memory to high memory,
syntax: (source in bank 0) (destination in bank 1) (number of bytes) MOVUP.
MOVDN - moves data block from high memory area to low memory,
syntax: (source in bank 1) (destination in bank 0) (number of bytes) MOVDN.
FILL - (n)(a)(b) FILL - fills memory from (a) to (b) (inclusive) with value (n)
Back to Contents
+ - adds TOS to TOS-1, replaces both with answer.
- - subtracts TOS from TOS-1, replaces both with answer.
* - multiplies TOS * TOS-1, replaces both with answer.
U* - as above but with unsigned 16 bit integers.
ABS - changes TOS if negative to positive.
/MOD - TOS-1 divided by TOS: TOS is answer, TOS-1 is remainder.
U/MOD - as above but with unsigned integers.
M* - as * but leaving 32 bit answer; TOS= high 16 TOS-1= low.
D+ - adds 2 32-bit values leaving 32-bit answer.
D- - subtracts 32-bit value from 32-bit value, answer 32 bits.
D< - compares 2 32 bit values, leaves true if TOS-3,TOS-2 less than TOS-1,TOS.
D= - compares 2 32 bit values (4 stack entries) and leaves true if equal else false (1 stack entry).
/ - TOS-1 divided by TOS, replace both with answer.
U/ - as above but with unsigned integers.
M/ - divides a 32 bit value (TOS-1 & TOS-2) by 16 bit value (TOS) leaving a 16 bit value.
MSQ - squares a 16 bit value leaving 32 bit answer.
MSQR - takes square root of 32 bit value leaving 16 bit answer.
SIN - converts angle in degrees to 2 decimal places to sine
fraction to 4 decimal places.
COS - as SIN but cosine.
ASIN - takes arcsine of fraction to 4 decimal places to angle in
degrees to 2 decimal places.
ACOS - as ASIN but arc-cos.
(b) BIT - leaves numeric value of bit number (b) i.e. 2^b
: ("colon") - this is the main defining word for defining a new
word. Must be followed by the new word. Puts system into
compile mode.
; ("semi colon") - end of definition (immediate word - means will
act immediately when system is in compile mode).
CONSTANT - syntax: (value) CONSTANT (name).
VARIABLE - syntax: VARIABLE (name) reserves 2 bytes in the
dictionary for a variable.
USER - syntax USER (name) - like VARIABLE but creates a new user
variable in the RAM area, incrementing UVP by 2. When invoked the
address of the variable is pushed to the stack. The advantage of
a USER variable over the normal VARIABLE is that after editing
and re-compiling the dictionary the value of a USER variable will
not have changed. When a USER variable is used it resets BANK to zero. To use the variable enter (value) (name) ! and (name) @ etc.
USARRAY - syntax (n) USARRAY (name) - is an array in the user variable area of (n) elements (n * 2 bytes). To use the array enter (value) (element-number) (name) ! and (element-number) (name) @ etc.
IMMEDIATE - makes a new word just defined operate immediately and
only when in compile mode, ie. when inside a : --- ; construct.
FORGET (word) - removes word and all subsequent words from
dictionary. Resets the DP (dictionary pointer) to the position previously occupied by the word.
If the word is a user variable then UVP is set back to the address previously occupied by the variable, recovering the user variable space.
(RoboForth only) If the word is a PLACE or ROUTE then NEXT is set back to the address previously occupied by the place or route, recovering the data space.
, ("comma") - incorporates the 2-byte value on the stack into
dictionary. Advances the DP by 2.
C, ("see comma") - incorporates the low byte from the stack into
the dictionary. Advances the DP by 1.
LITERAL - incorporates that value which is on the stack into the
word being compiled as if it were a constant.
ALLOT - (n) ALLOT - change no. bytes allotted to a variable,
where (n) is added to the two bytes already reserved for the
variable. syntax: VARIABLE (name) (no. extra bytes) ALLOT
[ ("bracket") - switch to immediate mode
] - switch back to compile mode. When in compile mode these allow
insertion of words which are executed immediately and not
compiled.
['] ("bracket-tick-bracket")- like ' but for use in a definition. It compiles the PFA of
following word as a literal.
[COMPILE] - compiles the following word even if it is an
immediate word.
CREATE (word) - creates an INCOMPLETE dictionary entry for the
new word. Adds a new 8-byte header to the dictionary plus the
first 2 bytes of the parameter field. DP is advanced by 10.
When (word) is invoked the PFA address is pushed to stack.
DOES> - within the definition of a new defining word DOES> marks
the start of the run-time activity of the words which will be
defined using the new defining word.
Syntax:
(starts with colon) : (defining-word name) CREATE (activity when defining-word is used) DOES> (activity when final defined word is used) ; (ends with semi-colon)
When the defining word is used the CREATE part of it adds the defined word to the dictionary. When the final created word is used its PFA goes on the stack and the
words after DOES> should make use of this value or DROP it.
CODE - generates header for machine code.
Follow with the name of the code then the machine code installed
by C, or , then finish with the code for PCIY.
For example a word
REVERSE (definition : REVERSE MEP C@ MDP C! ;)
could be coded LDA
MEP STA MDP PCIY e.g. in machine code:-
CODE REVERSE 3A C, MEP , 32 C, MDP , E9FD ,
( Or you can use the word PCIY instead of E9FD )
WARNING: All control loops are implemented using conditional short jump machine instructions. This means there is a maximum number of words between the beginning and end of a loop or decision tree of approximately 63 words. If exceeded the system will crash.
notes:
a (condition) is true if it is non zero (any value, not just 1), false if zero.
control words can not be used in immediate mode, only compiled into definitions.
: P-CHECK PRESSURE 1000 > IF VALVE OFF THEN ;
Form 2 syntax:
(condition) IF
(words executed if true)
ELSE
(words executed if false)
THEN
for example
: P-CHECK PRESSURE 1000 > IF VALVE OFF ELSE VALVE ON THEN ;
: P-CONTROL BEGIN PRESSURE 1000 > UNTIL VALVE OFF ;Form 2 syntax:
: P-CONTROL BEGIN HEATER ON TEMPERATURE 800 < WHILE INCREASE-HEAT REPEAT HEATER OFF ;
USER COUNTER : EX1 0 COUNTER ! 10 0 DO COUNTER INC LOOP COUNTER ? ; EX1 10 OK
Form 2 syntax:
(upper limit) (lower limit) DO
(function)
(step) +LOOP
This counts from (lower) to (upper) in increments of (step) and finishes when the index equals or exceeds the upper limit. Then this value of index is NOT executed within the loop.
for example
USER COUNTER : EX2 0 COUNTER ! 10 0 DO COUNTER INC 2 +LOOP COUNTER ? ; EX2 5 OK
In the case
5 0 DO
BLAH
2 +LOOP
The loop exits when the index reaches 6 which is greater than the upper limit. blah is executed only for indexes 0, 2 and 4 and not for 6.
In the case
6 0 DO
BLAH
2 +LOOP
The loop exits when the index reaches 6 which is equal to the upper limit. blah is executed only for indexes 0, 2 and 4 and not for 6.
In the case
7 0 DO
BLAH
2 +LOOP
The loop exits when the index reaches 8 which is greater than the upper limit. blah is executed for indexes 0, 2, 4 and 6.
: EX3 10 0 DO I . LOOP ; EX3 0 1 2 3 4 5 6 7 8 9 OK : EX4 5 0 DO I . 2 +LOOP ; EX4 0 2 4 OK : EX5 4 1 DO CR 3 0 DO J . I . LOOP LOOP CR ; EX5 1 0 1 1 1 2 2 0 2 1 2 2 3 0 3 1 3 2 OKcounting backwards - example
: EX6 0 10 DO I . -1 +LOOP ; EX6 10 9 8 7 6 5 4 3 2 1 0 OK : EX7 0 10 DO I . -2 +LOOP ; EX7 10 8 6 4 2 0 OK
LEAVE - syntax:
(upper limit) (lower limit) DO
(words)
(condition for leaving) IF LEAVE THEN
(maybe more words)
LOOP
On executing LEAVE the loop terminates when, and not until, LOOP is next executed. This means that any more words after THEN will be executed before the loop is left.
Example
: EX8 HEATER ON 100 0 DO TEMPERATURE 500 = IF LEAVE THEN 100 MSECS LOOP HEATER OFF ;This word will run for 10 seconds (100 * 100mS) but if the temperature reaches 500 (e.g. 50.0 deg C) befofre the 10 secs are up then there is one more 100mS delay before the heater is turned off.
EXIT - leaves the entire word if executed- i.e. effectively jumps
to the semi-colon.
syntax: (condition) IF EXIT THEN.
Not to be used within a DO - LOOP.
WARNING: All control loops are implemented using conditional short jump machine instructions. This means there is a maximum distance between IF and THEN or BEGIN and UNTIL etc. of 127 bytes (approximately 63 words). If exceeded the system will crash.
Note: these words exist in K11 but will not function unless the RAMDISK solid state disk system is installed. This system is based on an obsolete but highly efficient North Star DOS and is designed for rapid transfer of data to and from SD card to main memory, for example overlaying matrix coordinates without delaying robot activity as would be the case if data were transferred from PC.
DLOAD (filename) - loads file of FORTH text to edit buffer then
reads into line buffer as if typed. The filename must be the
last word in the command line. Extra words are ignored. Each
file may DLOAD another file (last line).
READ disk to memory.
(memory addr) (disk addr) (no. of blocks) (drive no.) READ
WRITE memory to disk.
(memory addr) (disk addr) (no. of blocks) (drive no.) WRITE
DLIST (disabled) - directory of RAMDISK.
DLOOK (disabled)
(address of string which is the filename, ending in return (0D)
or space (20) ) - DLOOK --> leaves address of location in DOS of
the directory entry + 8 i.e. to 2 bytes which contain the disk
address. The next 2 bytes are the file length.
DOS (disabled) - enter DOS command area.
CPU card: carries eZ80L92 processor, RAM memory, flash/rom memory and basic I/O. It carries the PB inputs, the PA buffered outputs and interfaces with the teach pad. It also carries main RS232 channel for the terminal and one spare RS232.
This card is part of basic K11 system.
DSP card: carries the DSP which controls the motor drives and also reads back from the encoders.
This card is part of basic K11 system.
MULTI-I/O card: Provides 48 lines of I/O programmable as input or output, a 4-channel analog-to-digital converter and a 2-channel digital-analog converter.
8-LINE BUFFER CARD: has 8 opto-isolated inputs or 8 opto-isolated outputs.
16-line opto-isolated I/O card providing 8 opto-isolated inputs and 8 opto-isolated and buffered outputs.
The cards conform to the ST bus which is roughly equivalent to
the Z80 pin-out except that it serves I/O only. EZ80L92 extended address and data lines, clock and other signals are not brought out on to the bus.
All signals which are low true are prefixed with
'-' e.g. -WR meaning not-write.
(a) (c) ---------------------------------------------------- 1 +15v | 1 A0 2 -15V | 2 A1 3 0V DIGITAL | 3 A2 4 -WAIT | 4 A3 5 -HALT | 5 A4 6 -M1 | 6 A5 7 -RFRSH | 7 A6 8 -WR | 8 A7 9 -RD | 9 A8 10 n/c | 10 -RESET IN 11 -IORQ | 11 IOSEL 12 +5V | 12 +5V 13 n/c | 13 n/c 14 -NMI | 14 -PF ( -POWERFAIL ) 15 OV ANALOG | 15 OV ANALOG 16 -BUSRQ | 16 n/c 17 -INT | 17 n/c 18 -RESET ( OUT ) | 18 n/c 19 -BUSAK | 19 n/c 20 -INTAK | 20 n/c 21 n/c | 21 n/c 22 RESET ( OUT ) | 22 n/c 23 0V DIGITAL | 23 0V DIGITAL 24 n/c | 24 n/c 25 n/c | 25 n/c 26 n/c | 26 SERIAL OUT (slot 1 only) 27 n/c | 27 SERIAL IN (slot 1 only) 28 n/c | 28 n/c 29 D7 | 29 D6 30 D5 | 30 D4 31 D3 | 31 D2 32 D1 | 32 D0
Pins 26 and 27 c are not 'bussed but are reserved for signals unique to particular cards. The CPU card should be fitted in the lowest slot because of its unique RS232 connections. The remaining cards can occupy the remaining slots in any order.
I/O cards are all addressed with address lines A0 to A7 only as
per original INTEL 8080 convention, plus -WR , -RD , -IORQ from the eZ80L92
CPU. Every card has a board address which is a multiple of 10
hex. The address of any device is NX where N is the board
address and X is the address of the device within the card.
ST FORTH has certain words such as ADC which are
pre-coded device routines which expect to find certain cards at
certain addresses, although the device routines themselves are
given below and may be re-coded to different addresses. The
normal address for each card is given with the card details
below.
MODULE ADDRESSES NORMALLY EMPLOYED
0x | Reserved |
1x | DSP |
2x | Multi-function I/O card primary |
3x | General purpose opto-isolated cards |
4x | |
5x | |
6x | |
7x | |
8x | |
9x | Reserved for PA, PB and PC I/O addresses |
Ax | Reserved for PD I/O address |
Bx | |
Cx | |
Dx | |
Ex | |
Fx |
There are 4 ports which are called PA, PB, PC and PD whose addresses are 96, 9A, 9E, A2.
An output bit may be controlled by the words ON and OFF e.g. PA 0
ON will energise the gripper.
The robot gripper is controlled by bit 0, all other outputs are available to the
user.
To turn any output bit on i.e. to a logic '1', say bit 1 of port
PA, the syntax is e.g.:-
PA 1 ON OK
which sets PA 1 to '1' but leaves all other bits unchanged.
PA 1 OFF OK turns it off again.
The electric gripper uses PA 0 and PA 1 (see Roboforth manual).
Suppose this were a pump, you could define PUMP:-
: PUMP PA 1 ; (which is the same as : PUMP 96 1 ;) thereafter use
PUMP ON and PUMP OFF.
How to use open collector outputs:
Using open collector outputs with an external supply:
IMPORTANT: When using an external power supply and loads are
inductive (e.g. solenoids) then flywheel diode must be fitted.
Inputs may be read back with PB IN e.g.
PB IN .
An input bit may be interrogated
with the word BIT? e.g. PB 0 BIT? leaves true if the input is at
a '1'. This may be used in decision constructs e.g. PB 0 BIT? IF
How to use inputs:
The teach box is connected to PC, whose upper 4 bits are
programmed as outputs and PD lower 4 bits programmed as inputs. The teach box
is arranged as a matrix between outputs and inputs giving 16
combinations which are decoded by the software. Diodes are fitted
in case a user presses two keys together.
Changing baud rate on port 0
The Baud rate always defaults to 19200 on a cold start. But you can change the baud rate temporarily.
The Baud rate factor is in location 9D44 named BAUD. The value of this factor is 2,000,000 divided by the required baud rate. So the default value is 2,000,000 / 19,200 = 104 (round to nearest integer) or 68 hex. So if you type:
HEX BAUD ?
you should see 68
To change the baud rate enter a new value into BAUD then call the bit of code that programs the port to the new baud rate then change ROBWIN to the same baud rate.
For example to change to 56,000 (factor 2000/56 = 36 or 24 hex):
24 BAUD !
BA CALL (reprograms port)
You will lose communication with the controller. Click Comm, configuration and select 56,000 in the drop-down menu. Communication restores at 56k. If you mis-enter the baud rate and get lost simply press reset on the controller and restore RobWin to 19200. The fastest practical speed is 256,000 baud, using HEX 8 BAUD ! BA CALL
Note that this may only work using the USB converter. The standard serial port may not go that fast.
If you USAVE then switch off the controller, then switch on with the key in warm start position then the higher baud rate remains. Cold start resets the baud rate to 19200.
Second serial port
You will first need to initialize the port using a value calculated as above to set the baud rate. Put the value on the stack then jump to location 001F, for example
HEX 68 1F JUMP
will initialize the port to 19200 baud.
To access the second serial port change the value of IOFLAG from 0 to 1 with
IOFLAG C1SET
From this point on you can only communicate with the controller through the second serial port. Therefore make sure you issue all commands to end with
IOFLAG C0SET
e.g.
IOFLAG C1SET ASPACE EMIT IOFLAG C0SET
will send a space character out of serial port 1 then return control to port 0.
IOFLAG C1SET KEY IOFLAG C0SET
will wait for a character into serial port 1 then return control to port 0.
You could define, say
: KEY1 IOFLAG C1SET KEY IOFLAG C0SET ;
This word will of course hang until a character arrives. You may wish to check the status of the port before you change to channel 1.
You can do this:
HEX CODE K2? D9 C, ( EXX 3E C, 0 C, ( LD A,0 ED C, 38 C, D5 C, ( READ FLAG F5 C, ( PUSH FLAG TO STACK D9 C, ( EXX PCIY , ( ENDThis leaves 4 on the stack if there is no character and 0 if a character has arrived at the port.
3A 1FE2 C! 06 1FE3 C! A0 1FE4 C! C3 1FE5 C! C7 1FE6 C! 05 1FE7 C!This should be typed all on one line at one time. Hit enter at the end.
Port, function | HE-14 pin | 9w D if fitted |
port 0 TX | 1 | |
port 0 RX | 2 | |
ground (0v) | 3 | |
port 1 TX | 4 | 2 |
port 1 RX | 5 | 3 |
ground (0v) | 6 | 5 |
+5v | 9 |
Wiring colors for electric gripper drive module: | |
Yellow/orange | signal IN |
Red | Power +12-18v |
Black | Ground |
White/Grey | Outputs to motor |
To change the AC voltage setting remove the controller lid and locate a 6-way screw terminal block. The mains power is connected on one side of the block and the other side has all the transformer taps. Refer to the diagram below. Choose as near to your AC voltage as possible.
"Live" and "Neutral" refer to power where one side is at the line voltage and the other side is around earth potential. For US 110v supplies neither side is neutral but each is 55v AC around earth potential. For this reason there are 2 fuses fitted in the IEC power connector at the rear of the controller.
OUTPUTS (SA/TA) | INPUTS (SB/TB) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
AN pin (25w D socket) |
J2 pin |
Function |
1 |
1 |
Gnd |
14 |
2 |
Gnd |
2 |
3 |
In 0 |
15 |
4 |
Gnd |
3 |
5 |
In 1 |
16 |
6 |
Gnd |
4 |
7 |
In 2 |
17 |
8 |
Gnd |
5 |
9 |
In 3 |
18 |
10 |
Gnd |
Address offset |
Write function |
Read function |
0 |
Write any data to select ADC channel 0 | Start Convert and latch address
for next conversion |
1 |
Write any data to select ADC
channel 1 |
|
2 |
Write any data to select ADC
channel 2 |
Read most significant byte |
3 |
Write any data to select ADC
channel 3 |
Read Least significant 4 bits on D4 to D7, 0 on D0 to D3 |
AN pin (25wD socket) |
J3 pin |
Function |
6 |
1 |
Gnd |
19 |
2 |
Gnd |
7 |
3 |
Output B |
20 |
4 |
Gnd |
8 |
5 |
Output A |
21 |
6 |
Gnd |
9 |
7 |
Gnd |
22 |
8 |
Gnd |
10 |
9 |
Gnd |
23 |
10 |
Gnd |
Address offset |
Write function |
Read function |
0 |
Write DAC A input latch least significant byte | Load DACs A & B from respective input latches |
1 |
Write DAC A input latch most significant 4 bits on D0 to D3 | |
2 |
Write DAC B input latch least significant byte | |
3 |
Write DAC B input latch most significant 4 bits on D0 to D3 |
ROBOFORTH CODE The base board address is usually 20hex. This is defined in ROBOFORTH as a constant IOBASE
DECIMAL IOBASE 2 + CONSTANT DABASE IOBASE 6 + CONSTANT ADBASE : ADC ( read ADC onto stack ADBASE + 0 SWAP OUT ADBASE IN DROP 25 USECS ADBASE IN DROP 25 USECS ADBASE 2 + IN 128 XOR 16 * ADBASE 3 + IN 16 / + ; : ADPRINT ADC . CR ; : DACA ( output stack to DAC channel A DUP DABASE OUT 256 / DABASE 1+ OUT DABASE IN DROP ; : DACB ( output stack to DAC channel B DUP DABASE 2 + OUT 256 / DABASE 3 + OUT DABASE IN DROP ;NOTE: ALL THESE WORDS ARE ALREADY PART OF ROBOFORTH - the definition is shown here for information only.
J4, J5, J6 pin (on the card) |
QQ, QR, RR pin (25 w D) |
J4 & QQ function |
J5 & QR function |
J6 & RR function |
1 |
1 |
QB0 |
QA0 |
RC0 |
2 |
14 |
QB1 |
QA1 |
RC1 |
3 |
2 |
QB2 |
QA2 |
RC2 |
4 |
15 |
QB3 |
QA3 |
RC3 |
5 |
3 |
QB4 |
QA4 |
RC4 |
6 |
16 |
QB5 |
QA5 |
RC5 |
7 |
4 |
QB6 |
QA6 |
RC6 |
8 |
17 |
QB7 |
QA7 |
RC7 |
9 |
5 |
+5V |
+5V | +5V |
10 |
18 |
GND |
GND | GND |
11 |
6 |
QC0 |
RB0 |
RA0 |
12 |
19 |
QC1 |
RB1 | RA1 |
13 |
7 |
QC2 |
RB2 | RA2 |
14 |
20 |
QC3 |
RB3 | RA3 |
15 |
8 |
QC4 |
RB4 | RA4 |
16 |
21 |
QC5 |
RB5 | RA5 |
17 |
9 |
QC6 |
RB6 | RA6 |
18 |
22 |
QC7 |
RB7 | RA7 |
19 |
10 |
+5V |
+5V | +5V |
20 |
23 |
GND |
GND | GND |
HEX : PROGPIA 83 IOBASE 0B + OUT 83 IOBASE 0F + OUT ;If you wanted, for example to change QA to input and QB to output you could add a new definition thus:
HEX : PROGPIA 92 IOBASE 0B + OUT 83 IOBASE 0F + OUT ;
(port) WATCH (e.g. QB WATCH) will display 8 bits from the specified port as 1s and 0s (see PP in Roboforth manual)
IP Modules | O/P modules | Inputs | Outputs |
3 | 0 | 24 | 0 |
3 | 1 | 20 | 4 |
2 | 1 | 16 | 8 |
2 | 2 | 12 | 12 |
1 | 2 | 8 | 16 |
1 | 3 | 4 | 20 |
0 | 3 | 0 | 24 |
The diagrams show how to use the module to interface to a NPN or PNP proximity sensor or similar device or to a switch.
![]() |
|
![]() |
![]() |
The jack is supplied with the two terminals shorted. You can instead wire this to any number of external normally closed safety devices. The circuit must be closed for the robot to run. If any device breaks the circuit the robot will stop and the software executes the contents of STOPVEC. This is the same as pressing the stop button on the front panel or teach pad. Normally there is an error message. See ROBOFORTH manual section 6.1 for software details.
The jack must not be removed even if you have no external circuit, it is the same as breaking the circuit so the shorted jack must be left in.
Connections from computer to controller are via an RS232 'null modem' cable. The controller has a 25w connector and the computer end is a 9 way connector. If you are using a USB converter it will have a 9 way connector.
Serial (RS232) port interface pinout and signals | |||||
---|---|---|---|---|---|
9 pin # |
25 pin# |
Acronym | Full name | Direction | Mean |
3
|
2
|
TxD
|
Transmit Data |
>>
|
Transmits bytes out of PC |
2
|
3
|
RxD
|
Receive Data |
<<
|
Receives bytes into PC |
7
|
4
|
RTS
|
Request To Send |
>>
|
RTS/CTS flow control |
8
|
5
|
CTS
|
Clear To Send |
<<
|
RTS/CTS flow control |
6
|
6
|
DSR
|
Data Set Ready |
<<
|
I'm ready to communicate |
4
|
20
|
DTR
|
Data Terminal Ready |
>>
|
I'm ready to communicate |
1
|
8
|
DCD
|
Data Carrier Detect |
<<
|
Modem connected to another |
9
|
22
|
RI
|
Ring Indicator |
<<
|
Telephone line ringing |
5
|
7
|
SG
|
Signal Ground |
Teach Pad connections | |||
---|---|---|---|
1 | PD 4 | 6 | PC 6 |
2 | PD 5 | 7 | PC 5 |
3 | PD 6 | 8 | PC 4 |
4 | PD 7 | 9 | screen (0v) |
5 | PC 7 |
|
They can not be used with R12. note 2 This input is shared with robot 6th axis sensors. It can not be used with R12. It is possible to share these inputs with an R17 providing the axis does not reach a sensor while an input state is important. R17 sensors pull down. Also make sure you do not hold down an input shared by a sensor while the robot calibrates. PB 5 may not be used at all with a 6th axis. |