You are on page 1of 160

AXCESS Language Tutorial

VERSION 2.1

ADVANCED
AXCESS
PROGRAMMING

Version 2.1
March, 1993

Copyright
AMX Corporation, 1993. All rights reserved. No part of this publication may be reproduced, transcribed,
stored in a retrieval system, or translated into any language in any form by any means without the written
permission of AMX Corporation.

Trademarks
IBM is a trademark of International Business Machines Corporation. M S-DOS is a trademark of Microsoft Corporation. Phoenix is a trademark of Phoenix Terminal Blocks Inc.

Credits
Written by David Hooker and Erik Engstrom.
Illustrated by Erik Engstrom and David Hooker.
Layout and design by Erik Engstrom.
Cover designs by Don Crum.
Special thanks to all at AMX for invaluable input and support.

Printed in USA.
For additional technical support, feel free to call us.
AMX Corporation
11995 Forestgate Drive
Dallas, Texas 75243
(214) 644-3048
(800) 222-0193
(214) 907-2053 FAX

Table of Contents
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix

Unit 1: Using the AXCESS Program


Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Introduction

Necessary equipment

Installing AXCESS onto a hard drive

Video monitors

Connecting the system

Device numbers

Blinking light status

Using the Menus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7


The menu environment

The File menu

The AX File menu


The Diagnostics menu

9
12

The Communications menu

13

The Help menu

15

The Text Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

Table of Contents

Editor basics

17

Blocking

18

Search and replace

18

The Push window

19

Simulated button press

20

Compilation errors

20

iii

Unit 2: Language Basics


Simply the Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Introduction

23

Format of the language

23

Statements and compound statements

24

Comments within the program

25

Identifiers

26

Reserved words

26

Special characters and operators

27

The Definition Sections . . . . . . . . . . . . . . . . . . . . . . . .


Starting a new program

29

29

The device-channel concept

29

Defining devices

30

Defining constants

31

Defining variables

32

Startup code

33

Mainline

33

Using Input and Output . . . . . . . . . . . . . . . . . . . . . . . .


Controlling something over there

35

All about the channel

35

Changing the state of a channel

37

Direct assignment

39

Putting input and output together

39

Channel Characteristics . . . . . . . . . . . . . . . . . . . . . . . .
The parts of an output channel

41

Defining latching

42

Mutually exclusive

43

Defining momentary mutually exclusive

43

Defining mutually exclusive latching

44

Defining mutually exclusive toggling

44

Putting it all to work

45

Programming feedback

46

Grouping feedback statements

47

35

41

Your First Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49


The program and the panel

iv

49

Table of Contents

Unit 3: Conditionals, Loops, and Waits


If and the Boolean Expressions . . . . . . . . . . . . . . . . .
Introduction

57

Boolean expressions

58

The If statement

58

The If...Else set of statements

58

The If...Else If set of statements

59

Nesting

59

The Select...Active statement

60

Trying it out

61

Mutually exclusive variable method

61

The variable assignment method

63

More Boolean operators

65

Reading a Boolean expression table

65

57

Waits and Timer Keywords . . . . . . . . . . . . . . . . . . . . . 67


Controlling time within AXCESS

67

The Wait list

67

Multiple Waits

69

Special uses of Wait

70

Naming Waits

71

Cancelling, pausing, and restarting Waits

71

The Wait_Until keyword

72

Misusing Wait_Until

72

Naming and removing Wait_Untils

73

The timer keywords

73

Using Time, Date, and Day

74

The While Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

Table of Contents

While

77

Long_While

78

Medium_While

78

Unit 4: Levels
Creating Levels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Introduction

81

What is a level?

81

Creating levels

82

Using Levels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Reading levels

85

Making a preset

85

Using bar graphs

86

Connecting levels

86

Unit 5: Arrays, Strings, and Buffers


Arrays and Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Introduction

91

Defining arrays

91

Accessing and storing array values

92

Strings

94

The string expression

94

Arrays as strings

95

String lengths

96

Sending strings and arrays

98

ASCII codes

99

Integer arrays

100

Working with Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . 101


Grouping data

101

Conversion keywords

101

Array manipulation keywords

103

Finding strings

104

Removing strings

104

Uppercase vs. lowercase

105

Setting uppercase and lowercase

106

Using Buffers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107

vi

Communicating to the outside world

107

Receiving strings

107

Creating buffers

107

Storing characters

108

Retrieving characters

108

Clearing a buffer

110

Table of Contents

Two-Dimensional Arrays . . . . . . . . . . . . . . . . . . . . . .
Powerful grouping

111

The anatomy of the two-dimensional array

111

Storing values

112

Retrieving values

113

111

Unit 6: Advanced AXCESS Programming


Using Subroutines . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Introduction

117

Subroutines

117

Defining a subroutine

117

Calling your subroutines

118

Sample program

118

Local Variables and Parameters . . . . . . . . . . . . . . . .


More power for your subroutines

123

Local variables

123

Parameters

124

Passing values back to the caller

125

Include Files and System_Calls . . . . . . . . . . . . . . . . .


Managing large programs

127

Include files

127

System_Calls and library files

129

Factory System_Calls

130

The instance number and name mangling

131

123

127

Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143

Table of Contents

vii

Introduction to AXCESS

What is AXCESS?
The AXCESS system is a microprocessor-based control system capable of controlling the simple to the most complex devices. Its basic function is to give you
complete control of every device in any system. Through a flexible language,
AXCESS can be programmed to handle almost any task. AXCESS can automatically dim lights, increase volume controls to preset levels, turn on video projectors, and much more.
An IBM-compatible computer is required to program the AXCESS system. Not
much memory is needed; even the more complex AXCESS programs can be handled by an average laptop computer. Once the system is programmed, the computer is only needed for diagnostics tests and any loading or saving of programs.

The AXCESS language


We designed the AXCESS programming language to be user-friendly. Although
there are over 90 commands, many are self-explanatory and take little time to
master. If you accidentally make a mistake in your programming, AXCESS finds
the error and reports it to you. As a result, both minor and major changes in programming can be done quickly and easily by you in the field.
AXCESS is not some strange new language that only brilliant engineers can
decipher. On the contrary, anyone with an average knowledge of computers and
presentation devices should be able to understand this manual without any difficulty. An understanding of DOS is not even necessary, except for a few commands involved in the initial installation of AXCESS.

The AXCESS Language Tutorial


This tutorial takes the approach of teaching the language while developing
real-world AXCESS system programs. You will start with the basic commands
and simple control scenarios, and progress on to more complex programming as
you discover new programming functions and techniques.

Introduction to AXCESS

ix

AXCESS Language Tutorial

UNIT 1

USING THE
AXCESS
PROGRAM

Getting Started

Introduction
This unit guides you through the simple installation of the AXCESS system for
both the software and the hardware. In addition, the programming environment
is explained, from the main menus to editing techniques.

Necessary equipment
In order to operate the AXCESS system, you need an IBM-compatible computer,
the AXCESS software, the CardFrame, the Master Card, and an appropriate cable.
The computer should have a minimum of 512K of memory. In addition, it must
be functioning on DOS 2.0 or higher.
AMX provides the necessary software, either on one 5.25-inch disk or one 3.5inch disk. The disk contains a number of files: the editor/compiler program,
support files, pre-written block files, code library files, and documentation
files. To read more information about what is on the disk, insert the disk into
your floppy disk drive, change to that drive (either A: or B:), and type README at
the DOS prompt. Up-to-date information about the contents of the disk along
with any additional information will be displayed for you to read.
The AXCESS PC program can be run from the distribution diskette. To start
AXCESS, change to the disk drive containing the floppy disk. Then simply type
AXCESS at the DOS prompt to start the program.

Installing AXCESS onto a hard drive


To install AXCESS onto the hard drive of your computer, change to the floppy
drive containing the distribution diskette. Then type INSTALL followed by the directory path on the hard drive to which you wish to install AXCESS. For example:

A:\> INSTALL C:\AXCESS

The installation program copies all of the necessary files into the specified directory, in this case C:\AXCESS. If the directory does not exist, the installation
program will create it. The AXCESS system can now be enabled by typing the following command:

Unit 1: Using the AXCESS Program

Getting Started

C:\AXCESS> AXCESS

For more help on the commands used in this section, see your DOS manual.

Video monitors
The AXCESS system automatically detects color or monochrome monitors. However, for a monitor that reports being a CGA monitor but actually has no color
(such as LCD or plasma-type monitors) you must force the AXCESS system into
the monochrome mode. To do this, enable AXCESS by typing the following:

C:\AXCESS> AXCESS/B

Connecting the system


At this point, the AXCESS system should be loaded into the computer. The next
step is to supply power to the CardFrame itself. Plug in the power supply from
the power outlet to the AXCESS system. The green two-pin Phoenix connector
should be plugged into the lower right corner of the back of the CardFrame.
Next, the cable must be connected from the communications port of the computer to the nine-pin connector on the Master Card. Note: if the Master Card is
in slot MC1, the nine-pin connector on the back of the CardFrame may be used.
Figure 1-1

Solving communications problems

What to do when AXCESS is


not responding properly.

Cause

Solution

The baud rate of the AXCESS


system is different than that of
the Master Card.

The AXCESS system baud rate can be found with the


Configure... option in the Communications menu, and an
explanation of setting the Master Card baud rate is in the
AXCESS Installation Guide. Set both to the same setting.

The communications port number of the AXCESS system is


different than that of the communications port in which the
Master Card cable is plugged.

The AXCESS system com port number can be found with


the Configure... option in the Communications menu.
Make sure it matches the correct Master Card
communications port.

The communications settings of


the AXCESS system is different
than that of the Master Card.

The AXCESS system communications settings can be


found with the Configure... option in the Communications menu, and an explanation of changing these
settings for the Master Card is in the AXCESS Installation
Guide. Both should be set to eight data bits, no parity,
and one stop bit.

The connecting cable is not


made by AMX.

Inspect the cables pinout. The cable connection chart in


the AXCESS Installation Guide should help you determine
the solution.

Getting Started

Unit 1: Using the AXCESS Program

Recommended device numbers


CardFrame #

Device #

DIP Switch Settings


1

17

33

49

65

81

97

113

Figure 1-2
Recommended device
numbers for the card in slot
1 of each CardFrame within
the AXCESS control system.

In the bottom left corner of the computer screen is the push window, which
displays the status of your AXCESS connections. It should now display the message AX Present. If it says AX Not Responding, there is a communications
problem. See Figure 1-1 for help. (More uses of the push window are described
later in this unit.)

Device numbers
Each device on AXlink must have a unique device number. The device number of
a card is set by the slot number and the DIP switch setting on the Server Card.
The DIP switch on the Server Card sets the address of the card in slot 1. The card
in slot 2 is the Server Cards DIP switch setting plus 1. As follows, the card in slot
3 is the Server Cards DIP switch setting plus 2. This will continue until slot 16.
For example, suppose the DIP switch on the Server Card is 17. The device
number of card slot 1 will also be 17. Card slot 2s device number will be 18
(17+1), card slot 3s device number will be 19 (17+2), and so on. Card slot 16s
device number will be 32 (17+15).
Each AXlink deviceexcept the AMX Touch Panelhas its own DIP switch to
select its device number. The Touch Panel has a keypad to enter its device number on the protected setup page.
At AMX, we have general rules for setting device numbers. For systems up to
eight CardFrames, we recommend the device numbers in Figure 1-2. These
numbers are only for the card in slot 1 of each CardFrame; for each consecutive
device, add one to the appropriate number.
We also recommend that all panels, infrared receivers, and radio frequency
receivers start on device number 128 and increase with each device.

Unit 1: Using the AXCESS Program

Getting Started

Blinking light status


As you may have noticed, there is a green LED light on the front of the Master
Card. Once the Master Card is plugged in and power is supplied to the
CardFrame, this LED turns on. There is a series of three different flash patterns
that tells you the current status of the AXCESS system.
One blink per second: the system is operating normally.
Two blinks per second: the devices specified within the program do not
match the devices found on AXlink. For a full description, check the Compare current devices... option in the Diagnostics menu (this is explained in
the next chapter).
Three blinks per second: there is an AXlink communications error, probably
due to a wiring problem. Check all the AXCESS wiring, making sure that
each cable is firmly connected.
When the green LED is on but not flashing, there is no AXlink activity. This
usually indicates that the Master Card has no AXCESS program loaded.

Getting Started

Unit 1: Using the AXCESS Program

Using the Menus

The menu environment


Programming AXCESS requires full knowledge of the menus that appear at the
top of the computer screen. This chapter explains the full spectrum of options
available to you in each of the five main menus.
To select an option in any of the menus, press the menus function key and
use the cursor keys to move up and down. Highlight the needed option and
press <Enter> to select it. To exit out of the menu and return to the text editor,
press the <Esc> key.
File
Open.. ctrl-O
Open include..
New..
Save
ctrl-S
Compile ctrl-C
Print..
Change dir...
Version...
Exit
ctrl-X

The File menu


Press <F1> to enter this menu. The File menu allows you to open, create, save, or
print an AXCESS program file or include file. (Include files will be discussed later
in the manual.) This menu also has commands for compiling your AXCESS program, changing the current directory, and viewing the current version information. The following is an in-depth look at each option in this menu.

Open..
This option gives you a list of existing AXCESS program files that are in the current directory (files with the DOS extension AXS). Simply move the cursor down
with the arrow keys and select the file you would like to open by pressing <Enter>. You can find your file more quickly by pressing the first letter of your filename; your cursor will appear before the files whose names begin with that same
letter. Once you are within the text editor, changes can be made to your program.
Listed below are special functions available with the Open.. option. They
appear at the bottom of the screen when you are in this menu.
<F1>

File information

<F2>

Delete file

<F3>

Rename file

<F9>

Open a non-program file

When <F1> is pressed, some basic information about the file you highlighted is
displayed. This information includes the filename, date and time the file was last

Unit 1: Using the AXCESS Program

Using the Menus

modified, and the file size. <F2> allows you to delete an unwanted file. Simply
highlight a file, press <F2>, and then AXCESS will ask you if you are absolutely
sure about deleting the file. <F3> lets you change the name of a file you highlight. <F9> allows you to bring in any text file to the editor. It does not matter if
the file is not related to AXCESS; you can use the program as a simple text editor.
Pressing <Ctrl-O> also activates the Open.. command.

Open include..
This option is identical to the Open.. command, except the program lists the
available include files that you can edit. An include file is an AXCESS program
file which actually contains a portion of code used by another AXCESS program
file. Include files have the DOS extension AXI.

New..
This option creates a basic new file for you. AXCESS loads the file NEW.OVL
(which must be present in the current directory), inserting a few headings and
comments to help you in your programming. The editor is then ready for you to
begin a new program.

Save
When you select this option, AXCESS asks you to give your file a name. If the file
already has a name, press the <Enter> key to overwrite the old file. To save the
file under a new name, type in a different name and press <Enter>.
To save a new file as an include file, instead of pressing <Enter> after typing
in the filename, press the <F1> key.
Normally in DOS, filenames can consist of a maximum of eight characters (not
including the extension). However, AXCESS allows a maximum of 57 characters,
and spaces are acceptable. This gives you greater flexibility for your file description. AXCESS converts your filename into a unique name that the computer can
recognize, and stores the entire name on the first line of the file with the keyword Program_Name.
It is highly recommended to save often and keep a backup copy of all programs.
Pressing <Ctrl-S> also activates the Save.. command.
Source code
The AXCESS program that
you type and edit.
Executable code
A translated version of the
source code that the AXCESS
system can understand.

Using the Menus

Compile
This option compiles the source code into executable code. Source code is another name for the AXCESS program that you type and edit; executable code is
what the AXCESS system can understand. By compiling your program, the
source code is translated into executable code. After compiling, the file is stored
in the computers memory. (To download this code to the Master Card, use the
Send... option in the AX File menu.)

Unit 1: Using the AXCESS Program

This feature also tells you if the AXCESS system is unable to compile your program. If this is the case, a list of errors are displayed. The cursor appears at the
first error. (For information about correcting these errors, see the next chapter.)
Pressing <Ctrl-C> also activates the Compile command.

Print..
This option sends the source code to the printer if one is available. If this command cannot operate the printer, use the Configure... option in the Communications menu to check the LPT setting. This setting should be the same as the LPT
port number in which the printer cable is connected.

Change dir...
This menu option allows you to change the working directory from where you will
load and save your files. Selecting this option displays a window on the screen
where you can edit the DOS path to a different directory. After a new directory
path is entered, AXCESS rebuilds its lists of available files for the new directory.

Version...
Selecting this option displays a window showing the current version of the
AXCESS PC program you are running, plus information on the amount of
memory available. Simply press any key to go back to the editor.

Exit
This option lets you exit to DOS. AXCESS asks if you want to save the current file
if any changes have not been previously saved.
Pressing <Ctrl-X> also activates the Exit command.
AX File

The AX File menu

Retrieve
Send...
ctrl-p
Source-send
ON
Verify
Create S19 file...
Send w/password...
Options...

Press <F2> to enter this menu. The AX File menu helps you transfer both the executable code and the source code of a file to the Master Card. In addition, you
can retrieve source code from the Master Card.

Retrieve
This option retrieves the source code from the Master Card, if possible. There
are two reasons why the source code was not saved in the Master Card:
There was not enough memory in the Master Card to store the source code.
The Source-send option was toggled off. For more information, see the
Source-send option explained a little later in this chapter.

Unit 1: Using the AXCESS Program

Using the Menus

Always save the source code on either the hard drive or a floppy disk. Do not
rely on the Master Card to keep all of the source code in memory.

Send...

BUZZWORD
Downloading is the sending
of data from computer to a
device (such as a Master
Card). Uploading is the
opposite: the computer is
the receiver.

This option sends the current executable code to the Master Card. If possible, the
source code is also stored in Master Card memory. If there is not enough room
in the Master Card for the program, AXCESS will stop downloading and give you
a warning. When this happens, try to send the program again, but without sending the source code.
If you have made changes to your source code, AXCESS asks if you want to
recompile your program. If you do not accept this option, the file sent to the
Master Card is not the same as the file in the text editor, but instead the last
compiled code.
Pressing <Ctrl-P> also activates the Send... command.

Source-send
This option toggles on and off. The current status is listed at the right of the
Source-send option.
With Source-send on, AXCESS will attempt to download both the executable
code and the source code to the Master Card when you select the Send... option, memory permitting. This allows the Retrieve option to re-load the source
code from the Master Card. If Source-send is off, AXCESS downloads only the
executable code, which cannot be retrieved from the Master Card.
It is a good idea to leave this option turned on. The only reasons to turn the
Source-send option off are to speed up downloading time during program
development, or because you know the source code is too large to send.

Verify
As a safeguard, this option checks to see if your compiled program is the exact
same as that in the Master Card. It is possible that the Master Card does not
have the latest compiled version of your program. If your compiled program
fails this test, simply recompile the program and send it to the Master Card.

Create S19 file...


This menu selection is used to create a Motorola S19 format file for use in storing
the program into an EPROM. This is only used to make PC+ Program Carrier
chips, which are now obsolete. You will probably never need to use this menu
option, but it is mentioned here for information purposes.

10

Using the Menus

Unit 1: Using the AXCESS Program

Send w/password...
This menu command is identical to the Send... command, but with one addition: it allows the specification of a password which will be needed to retrieve
the program in the future. This password can only be numerical; no alphabetic
characters are allowed in the password.
When a password-protected program is retrieved from a Master Card, AXCESS
will prompt the user for the password before it decompresses and displays the
program in the editor. This provides a means of storing the source code in the
Master Card so that only authorized persons can retrieve it. If the password is
forgotten, however, there will be no way to retrieve the source code from the
Master Card, so do not forget it!

Options...
This menu command brings up a window (Figure 1-3) where the user can set
various options concerning compile-time warning and error messages and other
compiler options. The options are divided into compiler messages and compiler
options. Here is what each selection in the compiler messages section means:
Parameter mismatch: turning this option on enables errors when a parameter of the wrong type is passed to an AXCESS function
Assignment of unlike types: turning this option on enables warnings when a
variable or constant of one type is assigned to a variable of a different type
Variable is not used: turning this option on enables warnings when a
variable declared anywhere in the program is not actually used
DEFINE_CALL is not used: turning this option on enables warnings when a
Define_Call subroutine declared in the program is not actually used
The compiler options section has only one option to turn on or off: Separate
DEFINE_CALL list. Compiling with this option on causes all Define_Call subrou-

Figure 1-3
Screen produced by the
Options... selection in the
AX File menu.

[
[
[
[

]
]
]
]

OPTION
Compiler messages
Parameter mismatch
Assignment of unlike types
Variable is not used
DEFINE_CALL is not used

Compiler Options
[ ] Separate DEFINE_CALL list

to toggle

Unit 1: Using the AXCESS Program

ESC when done

Using the Menus

11

tines to be stored in a separate section of the Master Card memory than the
Define_Program section. This effectively allows the code size of a program to
reach 128K (64K for the Define_Calls and 64K for the Define_Program section).
When this option is turned on, the dialog box asks for a size of the Define_Call
memory segment.
Diagnostics

The Diagnostics menu

Show current devices...


Compare current devices...
Show current versions...
Watch variables...

Press <F3> to enter this menu. The Diagnostics menu allows you to view and
compare the devices on AXlink and the devices defined in the current program
stored in the Master Card.

Show current devices...


When this option is selected, AXCESS asks the Master Card for a list of all devices
currently present on AXlink. The device number, device type, and device name
in the program are displayed for each device. Pressing the <Enter> key updates
the list. See Figure 1-4.

Compare current devices...


This option compares the devices defined in the current program in the Master
Card against the devices that actually are on AXlink. AXCESS lists the devices
that are defined in the Define_Device section of the program but not on AXlink.
Also, AXCESS lists the devices that are currently on AXlink but are undefined in
the program. After altering any devices, pressing the <Enter> key updates this
listing. See Figure 1-5.

Figure 1-4
Screen produced by the
Show current devices
option in the Diagnostics
menu.

DEVICE
-----1
2
3
4
128

DEVICE TYPE
----------UNIVERSAL 8 RELAY
UNIVERSAL 8 RELAY
IR/SERIAL DATA
VOLUME CONTROL
SOFTWIRE PANEL

PROGRAM NAME
-----------CASS
LIGHTS
VCR
VOLUME
PANEL

These are the names of the


devices assigned in the program
These are the product type
names that AMX gives the devices

12

Using the Menus

Unit 1: Using the AXCESS Program

***** DEVICES PROGRAMMED BUT NOT PRESENT ****


DEVICE DEVICE TYPE
PROGRAM NAME
------ ---------------------1
UNKNOWN
CASS
128
UNKNOWN
PANEL

These devices are not


plugged into AXlink

***** DEVICES NOT PROGRAMMED BUT PRESENT ****


DEVICE DEVICE TYPE
PROGRAM NAME
------ ---------------------4
VOLUME CONTROL

Figure 1-5
Screen produced by the
Compare Current Devices... option in the
Diagnostics menu.

This device is not


defined in the program

Show current versions...

BUZZWORD
Firmware is the software that
resides in the EPROMs in
many of the AXCESS devices.
This software is what makes
these devices operate.

Communications
Terminal emulator... ctrl-t
Configure...
Send file...
Receive file...
Pass thru...

When this option is selected, AXCESS displays a list of the devices present in the
system, along with the firmware version of the device (if applicable).

Watch variables...
This item brings up the Variable Watch window. This window allows you to
observe the contents of selected variables while the program is running. See the
AXCESS Programming Guide for details on how to use this feature.

The Communications menu


Press <F4> to enter this menu. The Communications menu lets you communicate directly to the Master Card. In addition, AXCESS can be configured to fit
some of your specifications, including the baud rate and the selection of communications ports and printer ports.

Terminal emulator...
Dumb terminal
A serial communications
device. Whatever you type
goes out the communications port, and whatever
comes in the port is
displayed on the screen.

This option puts the AXCESS system into a dumb terminal mode. Whatever you
type on the screen exits through the communications port, and anything coming
in from the communications port is displayed on your monitor. This mode is
used to communicate directly to the Master Card, modems or other RS-232 devices, and also to debug RS-232 controlled devices. For more information, consult
the AXCESS Programming Guide for Master Card communication commands.
Pressing <Ctrl-T> also activates the Terminal emulator... command.

Configure...
This option lets you choose which communications port, baud rate, and printer
port you need for the AXCESS system. Upon selecting this, a window appears list-

Unit 1: Using the AXCESS Program

Using the Menus

13

COM
COM
COM
COM

1
2
3
4

CONFIGURE
BAUD RATE
300
600
1200
LPT 1
2400
4800
9600
LPT 2
19200
38400

This changes the port to which


your printer is connected

This changes the speed at which serial


data exits the communications port

Figure 1-6
Screen produced by the
Configure... option in the
Communications menu.

This changes the communications


port through which serial data exits

ing the choices. Move the cursor with the arrow keys next to the item you need
to change. Pressing <Enter> places a check mark next to that item. See Figure 1-6.

Send file...
This option is not the same as the Send... option in the AX File menu. Instead,
it allows the transfer of files between two computers through a connecting serial
cable or modem. Both computers must be running the AXCESS program in order
for the transfer to be complete.

Receive file...
This option works in conjunction with the Send file... option. Once two computers are connected with a serial cable or modem, select Send file... on the
computer that has the file to be sent. Select Receive file... on the other computer to initiate the transfer of data.

Pass thru...
This option allows you to pass data between two of the computers communications ports. All data going in one port comes out the other, and vice versa. Immediately after you select this option, a window appears allowing you to select
the two communications ports you wish to use. When you have done that,
pressing <F10> establishes the pass-thru connection. A window on the screen
will show the number of characters of data being received by each port. Pressing
the <Esc> key quits the pass-thru.

14

Using the Menus

Unit 1: Using the AXCESS Program

Help
Help on Help
Editor
Keywords
Sample Program

The Help menu


Press <F6> to enter this menu. (In order for this menu to work, the file HELP.OVL
must be present in the current directory.) The Help menu can give you a brief
definition of a specified keyword or command. This menu is self-explanatory in
its instructions to select an option.

Unit 1: Using the AXCESS Program

Using the Menus

15

The Text Editor

Editor basics
The AXCESS system offers you a simple text editor for manipulating text in your
programs. Whenever a menu is not displayed on the screen, the editor is in effect. Figure 1-7 lists the commands used within the editor.
Cursor movement around the screen is controlled by the arrow keys. (If you
do not have an extended keyboard, make sure the <NumLock> feature on the
keyboard is off so you can use the keypad instead.) <Home> brings you to the
beginning of the current line, and <End> puts you at the end of the current
line. Also, <Pg Up> takes you one screen of text up, and <Pg Dn> takes you
one screen of text down. <Ctrl-Home> takes you to the very beginning of the
program, and <Ctrl-End> takes you to the very end.

Figure 1-7

Editing commands

A list of editing commands


and their functions.

Command

Function

Command

Function

<Alt-C>

Copy block

<Alt-W>

Write block to disk

<Alt-D>

Delete block

<Alt-Z>

Delete to end of line

<Alt-F>

Find Push statement

<Alt-minus>

Delete current line

<Alt-G>

Get block from disk

<Alt-=>

Undo last command

<Alt-I>

Insert Push statement

<Ctrl-A>

Simulate pressing button

<Alt-L>

Mark block

<Ctrl-E>

Toggle error window on/off

<Alt-M>

Move block

<Ctrl-Home>

Go to beginning of program

<Alt-N>

Go to next error

<Ctrl-End>

Go to end of program

<Alt-O>

Print block

<Home>

Go to beginning of current line

<Alt-P>

Go to previous error

<End>

Go to end of current line

<Alt-R>

Search & replace text

<Pg Up>

Go up one screen of text

<Alt-S>

Search for text

<Pg Dn>

Go down one screen of text

<Alt-U>

Unmark block

<Ins>

Toggle insert/overwrite mode

Unit 1: Using the AXCESS Program

The Text Editor

17

Pressing the <Ins> key toggles the insert/overwrite mode. If you are in the
Insert mode, every character you type is inserted into the current cursor position. In the Overwrite mode, any character under the cursor is overwritten with
the new one.
If you would like to delete an entire line in the program, type <Alt-minus
sign>. If you accidentally delete the wrong line, simply press <Alt-=> to undo
the last command.
There is a status line near the bottom of the screen when you are in the editor.
This tells you which line the cursor is currently on, the amount of available
memory, and the current insert/overwrite mode.

Blocking

NOTE
A number of pre-written
blocks are included on the
AXCESS distribution diskette.

This feature allows you to treat one section of text as a complete block. This
block as a whole can be copied, moved, or deleted.
To mark a block, position the cursor at the beginning of the section of text.
Type <Alt-L>, and this line of text will be highlighted. Move down to the end of
the section and type <Alt-L> again. All the text between the first <Alt-L> and
the last will now be highlighted. To shorten or lengthen this text block, position
the cursor at the new ending for the section and type <Alt-L>.
Now that a block is highlighted, it can be manipulated. To copy the block,
move the cursor to the desired place for the copied text and type <Alt-C>. The
block is copied into the specified place. In order to move the block, move the
cursor again to the desired place for the text and type <Alt-M>. The block disappears from its previous position and is inserted into the new specified place. If
you would like to delete the entire block, type <Alt-D> and the block is erased.
Blocks can also be saved to a disk and then retrieved. To write a block to disk,
type <Alt-W> and AXCESS will ask you for a filename. Even though the block is
saved to disk, it still remains in your current program. To retrieve the block from
disk, position the cursor in the place where you would like to insert the new
text. Type <Alt-G> and supply AXCESS with the blocks filename. The new block
is inserted into your program where the cursor appears.
Once you are finished manipulating a block, it must be unmarked by typing
<Alt-U>. The block returns to a normal background color, and you can resume
editing.

Search and replace


The AXCESS system allows you to search for a particular line or fragment of text,
such as cassette or PROJ. This is useful when you would like to view all references to a certain device, such as VHS. Move the cursor to the line where you
want the searching to begin and type <Alt-S>. AXCESS asks you for the line of

18

The Text Editor

Unit 1: Using the AXCESS Program

Case sensitive
Uppercase and lowercase
values are not evaluated the
same.

text you would like to find. The search function is not case sensitive. This means
that an entry of CASS will return possible references of CASS and cass2,
and even Cassette.
If the fragment or word is found, the current cursor position is set at the beginning of the first line found. Type <Alt-S> again to go to the next line containing the fragment or word.
If you would like to replace text automatically with a new fragment or line,
use the search and replace function. Do the same positioning as the search command, but type <Alt-R>. AXCESS asks you for the text you are searching for, as
well as the text that will replace it. Be careful with this function. If you try to replace all references of cass with CD, cassette would become CDette. (The
cass of cassette was replaced with CD, thus creating the strange new
word.) As a safety precaution, AXCESS asks if you would like to replace the line
or fragment, case by case.

The Push window

Push window
A window on the bottom left
of the AXCESS program that
displays the Push statement
of the last button pressed in
the AXCESS system.

This feature allows you to find the Push statement of an existing button or to
insert the Push statement of a new button into your program. For more information on the Push statement, see Chapter 6.
In the bottom left corner of the screen, there is a small window (colored magenta on color monitors). This Push window displays the Push statement of the
last button pressed in the AXCESS system. If AXCESS has just been powered up
and no buttons have been pressed, the window displays AX Present. If the
Master Card is not connected or communicating properly, the window displays
AX Not Responding.
For example, an AMX Touch Panel is defined as TOUCH_PANEL in the
Define_Device section of the program (for more information, see Chapter 5).
When button 2 on the Touch Panel on AXlink is pressed, the Push window displays the following:

PUSH[TOUCH_PANEL,2]

In order to find this Push statement in your program, type <Alt-F> when the
statement is in the Push window. The cursor is placed on the line containing the
exact statement. If there is not a Push statement in the program that matches the
text in the Push window, the computer responds with a beep.
You can also insert the displayed Push statement into the program; this is especially useful when a button is not yet programmed. To add a new button into
the program, press the button; its Push statement now appears in the Push win-

Unit 1: Using the AXCESS Program

The Text Editor

19

dow. Position the cursor where the statement should be inserted and type <AltI>; the Push statement will be inserted into your program.
If this button already appears in the program, the computer beeps and takes
the cursor to the existing Push statement. This function does not allow you to
insert the same Push statement twiceyou must do this manually.

Simulated button press


There is a way to operate a button without actually pressing the button on the
panel. Simply position your cursor next to a Push statement in the program and
type <Ctrl-A>. The system thinks that the button on the corresponding panel is
being pressed. Its function continues to operate as long as you hold down the
<Ctrl> key. Also, the push window displays the Push statement.

Compilation errors
After compiling a program (see the previous chapter for the Compile option
in the File menu), a list of errors and/or warnings may appear in a window at
the bottom of the screen. The cursor is automatically placed at the first of these
in the file, and the type of error or warning is highlighted in the window. See the
AXCESS Programming Guide for more details on warnings and errors.
Once you finish correcting the mistake, you can go to the next error by typing
<Alt-N>. The cursor appears at the next error. To go back to previous mistakes,
type <Alt-P>. The cursor will move to the appropriate place.
After the first error is corrected, it is a good idea to recompile your program.
That one error could be causing many more down the line. For example, if you
forgot to define the device VHS2 earlier in the file, every line that references VHS2
is considered wrong. If you define VHS2 in the appropriate section, all the other
lines are now correct. When the program is recompiled, those errors are repaired.
You might want to have more space on the screen, especially if there is a large
number of errors in a particular section. To remove the error window, press
<Ctrl-E>. This command toggles the error window on and off, so press <Ctrl-E>
to get the window back on the screen.

20

The Text Editor

Unit 1: Using the AXCESS Program

AXCESS Language Tutorial

UNIT 2

LANGUAGE
BASICS

Simply the Basics

Introduction
This unit will help you start writing AXCESS programs. By the end of this unit
you should be familiar with several concepts: the basic ground rules for writing
AXCESS programs, the device-channel concept, the different sections that make
up an AXCESS program, how AXCESS executes a program, basic input and output
functions, and simple feedback. As you progress through the chapters you will
develop a simple AXCESS program containing these basic features, and you will
build on this program in later units.

Format of the language


Free format
A characteristic of the
AXCESS language that allows
the source code to be
independent of tabs and
carriage returns.

The AXCESS language is in a free format, meaning that the source code is independent of tabs and carriage returns. Because of this, it is advised to use a consistent
method of code placement in order to make the code more readable. In this
manual, an outline format is used; that is, each subsection of a section is
slightly indented. For example:

IF (X = 1)
{
PUSH[PANEL,1]
{
Y = 2
Z = 3
}
}

However, the program section will be executed in the same manner even if it
looks like this:

IF(X=1) {PUSH[PANEL,1] {Y=2 Z=3}}

All the elements are in the correct places, but the spacing is different. Use
whatever method is easiest for you to type and understand.

Unit 2: Language Basics

Simply the Basics

23

Statements and compound statements

Keyword
A word or series of words
that signifies the operation
for AXCESS to execute.
Statement
A keyword and all of its
parameters or conditions.
Operator
A character or group of
characters that performs a
specific mathematical or
relational function.
Compound statement
A group of several statements, enclosed by a set of
braces.

During programming, most of the keywords and operators require a complete


statement. A keyword is a word or series of words that signifies the operation for
AXCESS to execute. That keyword and all its parameters form the statement. For
example, the keyword to turn a channel on is merely On. However, the statement to turn on a particular channel is ON [RELAY_CARD,RELAY].
Statements can also involve mathematical or logical operations when operators are used. An operator is a character that performs a specific mathematical or
relational function. For example, the operator used to set a variable equal to a
value is =. As expected, the statement used to set variable X to the number 5 is
X = 5.
You will frequently have to group several different statements together into
one compound statement. The braces { } are used to enclose this type of statement. Compound statements are used if several statements are to be executed in
a situation where AXCESS syntax will allow just one. The statements are executed
in the sequence in which they are programmed.
The number of open braces { and close braces } must be the same in your
program. After compiling, AXCESS will point out this error to you if the quantities are different.
Compound statements give you the ability to group multiple statements together into one unit, much like grouping sentences together into one paragraph.
The most common example of compound statements occurs with the Push keyword. (This keyword is explained in depth later.)

PUSH[PANEL,1]
{
ON [RELAY_CARD,5]
X = 5
}

In this example, when button 1 on PANEL is pressed, relay 5 on RELAY_CARD


is turned on. Also, the variable X is assigned the value of 5. The open brace indicates the beginning of the compound statement, and the close brace ends it.
If you only needed the relay to be turned on, the statement could have been
written like this:

PUSH[PANEL,1]
ON [RELAY_CARD,5]

24

Simply the Basics

Unit 2: Language Basics

Figure 2-1
The uses of braces,
brackets, and parentheses.
These operators cannot be
interchanged within the
program.

Special operators
Operator

Name

Function

{}

Braces

Combine several statements into a function

[]

Brackets

Enclose the device-channel: [device, channel]


Enclose the location of a storage space in an array
Enclose the instance number for use with a System_Call

()

Parentheses

Enclose the expression after an If statement


Enclose a mutually exclusive set in the Define section
Group a mathematical operation

Or if you prefer, braces could be added around the statement:

PUSH[PANEL,1]
{
ON [RELAY_CARD,5]
}

Since there is only one (and only one) statement after the line PUSH[PANEL,1],
braces are not needed.

Comments within the program


Comment
A description or remark
within an AXCESS program
that is not considered part of
the actual program; it is
ignored by the compiler.

AXCESS allows you to place helpful comments inside your program. A comment
is a description or remark that is not considered part of the actual program. Any
text after (* and before *) will not be compiled, even if the text is separated over
several lines. See the following example:

(* This section will define all the devices used. *)


DEFINE_DEVICE
VCR = 1
CD = 2

(* Video cassette recorder *)


(* Compact disc player *)

You can place any number of comments in your program. However, when the
program is compiled, the compiler will pass over these. They have no effect on
the actual operation of the program.
It is wise to use comments. They are especially helpful in a long program,
where you can label each part of the program for future reference. If changes
have to be made, you can merely look for the label of the section you need to
edit. As illustrated in the next example, descriptions of Push statements are
very useful.

Unit 2: Language Basics

Simply the Basics

25

PUSH[T_PANEL,1]
{
(* statement(s) *)
}
PUSH[T_PANEL,2]
{
(* statement(s) *)
}
PUSH[T_PANEL,3]
{
(* statement(s) *)
}

(* SLIDE preset *)

(* VHS preset *)

(* V_PROJ preset *)

This will help you find the SLIDE preset, VHS preset, and the V_PROJ preset of
the Touch Panel much faster.

Identifiers
Identifier
A combination of letters,
numbers, or underscores
that represents a device,
constant, or variable.

Identifiers are used to denote a device, constant, or variable. For example,


T_PANEL could represent an AMX Touch Panel, PLAY could represent the first
channel, and CD_SELECT could represent the current compact disc player.
There are certain guidelines for identifiers. They are as follows:
They must begin with a letter followed by any combination of letters,
numbers, or underscores. No spaces are allowed.
Valid identifiers:

CD3, TOUCH_PANEL, VCR3_SELECT

Invalid identifiers: 3VHS, CD PLAYER, *RGB4.


The identifier must have less than 26 characters.
Identifiers are not case-sensitive. For example, Touch_Panel is the exact
same identifier as TOUCH_PANEL.
The identifier must be unique. Once you define VHS3, do not choose the
same name later for a different identifier.

Reserved words
There are certain words that are reserved for AXCESS keywords or functions.
These are integral to the system and cannot be redefined or used as identifiers.
For example, PUSH cannot be used as an identifier, because AXCESS recognizes it
as a keyword.

26

Simply the Basics

Unit 2: Language Basics

Special characters and operators


There is also a complete set of symbols that are used within the AXCESS program, as shown in Figure 2-2. These symbols represent a wide variety of characters and operators.

Figure 2-2

Special mathematical operators

A list of the special operators


used for mathematical
functions and operations.

Operator

Function

Operator

Function

()

Parentheses

<

Less than

Multiply

>

Greater than

Divide

<=

Less than or equal to

Modulus

>=

Greater than or equal to

Add

<>

Not equal to

Subtract

Unit 2: Language Basics

Simply the Basics

27

The Definition Sections

Starting a new program


Now that the ground rules are laid out, you can start writing your first AXCESS
program! When you begin a new program with the New.. option in the File
menu, you are not given an empty file with which to work. Instead, there are
several definition headings to signify what should be defined in each section.
The definition sections that are given to you are the following:
Define_Device
Define_Constant
Define_Variable
Define_Latching
Define_Mutually_Exclusive
Define_Start
Define_Program
Feel free to delete any of these headings you do not need, and keep those that
you do. If you do not have any statements under one of these headings, your
program will not operate any differently. However, you might want to keep the
headings there for future reference.
Although the definition sections are not used within the main program, they
create the materials the main program needs. Devices and their channels are given names, channels are given different characteristics, and variables are formed.
Even the immediate startup procedures of the AXCESS system are within a Define section. If you develop a good understanding of the Define statements, you
will be able to build an excellent foundation for the main part of your program.

The device-channel concept


Everything that an AXCESS system controls is controlled through a device in the
system. Each device communicates to the Master Card through AXlink, the
AXCESS systems communications bus. Most devices, such as a Touch Panel or a
relay card, have channels which either accept an input, generate an output, or

Unit 2: Language Basics

The Definition Sections

29

both. These inputs and outputs are referred to in the AXCESS program as a device-channel, which is written like this:
[5,1]

This device-channel references channel 1 of device 5. If device names and constants are used instead of numbers, the same reference could look like this:
[VCR,PLAY]

Using device names and constants is obviously much more readable. This concept of the device-channel is the most basic concept of the entire AXCESS system,
as it is the most common way that AXCESS communicates to the outside world.

Defining devices

Device number
A unique number from 1 to
255 designated to each
device connected to AXCESS
via AXlink.

This code fragment is from


STEP1.AXS on the AXCESS
distribution diskette.

30

The Definition Sections

When you start writing a program, you should first label each device in the system. Each device on AXlink must have a unique device number. Card 1 may have
device number 1, and card 2 may have device number 2. Any time these device
numbers are referenced in the program, AXCESS checks the corresponding device.
However, with a long list of devices connected to AXlink, these numbers can be
difficult to remember. Assigning actual names to these devices is much easier.
This is the function of the Define_Device section. It is placed at the beginning
of the program, and it lets you name the devices. Whenever you use this device
name in your program, AXCESS will automatically use the corresponding device
number to reference the device.
You will start writing your program by first defining the devices in your system. Suppose you have a VCR, a CD player, and a cassette deck, and you are controlling them with the first three cards in your CardFrame. These cards have
device numbers 1, 2, and 3. You also will need to control a projection screen,
some drapes, and lights. Two relay cards, one in slot 4 and one in slot 5, will
handle these (the first card handles both the screen and drapes). A Softwire
Panel will be used to control all of these devices. Here is what your
Define_Device section should look like:

DEFINE_DEVICE
VCR
= 1
CD
= 2
CASS
= 3
RELAY = 4
LIGHTS = 5
SWP
= 128

Unit 2: Language Basics

From this point on, you can reference device 1 with the name VCR, device 2
with the name CD, and so on.
Also, the push window at the bottom of the screen is changed. If the devices
in the previous example are on AXlink, AXCESS modifies the window to use the
given device name instead of the devices number. This provides a quick reference tool for future programming.
There is one more reason for using Define_Device. When you compare devices using the Compare current devices... option in the Diagnostics menu,
AXCESS checks all the devices listed under Define_Device. Next, it checks which
devices are on AXlink. AXCESS then tells you the devices that you did not define
in your program. These devices cannot be used or referenced until they are defined, so make sure that all devices are under this heading.
The name you assign to a device number cannot change in the program. It
must remain the same to the very end.
AMX encourages the practice of starting control panel device numbers at device 128. This includes radio frequency (RF) receivers, Touch Panels, Softwire
Panels, and all other control panels and receivers.

Defining constants
Constant
An identifier whose value
remains unchanged
throughout the entire
program.

Transport functions
Common functions of
devices such as VCRs and
cassette decks. For
example: Play, Stop, Pause,
Fast Forward, and Rewind.

This code fragment is from


STEP1.AXS on the AXCESS
distribution diskette.

Unit 2: Language Basics

Constants are identifiers whose values remain unchanged throughout the entire
program. The process of defining them is very similar to defining devices. Assigning a value to an identifier in this section locks that value to the identifier for
the entire program, making it possible to use descriptive names instead of just
numbers in your program.
In your system, the VCR, CD player, and cassette deck devices have channels
that activate the various transport functions, such as Play and Stop. As a general
rule, Play is usually channel 1 and Stop is channel 2. You could define these
channel numbers as constants in your program to make it more readable.

DEFINE_CONSTANT
(* Transport channel numbers *)
PLAY = 1
STOP = 2
PAUSE = 3
FFWD = 4
REW
= 5
(* Relay card
SCREEN_UP
=
SCREEN_DOWN =
SYS_POWER
=
DRAPE_OPEN =
DRAPE_CLOSE =
DRAPE_STOP =

channel definitions *)
1
2
3
4
5
6

The Definition Sections

31

(* Lighting card channel definitions *)


LIGHT_FULL = 1
LIGHT_MED = 2
LIGHT_LOW = 3
LIGHT_OFF = 4

The value of the constant PLAY from now on is 1. Also, STOP has a value of 2.
Both of these values cannot be changed anywhere in the program.
Later in your program when you need to activate the Play function of the
VCR, you dont have to remember that it is channel 1 of the devicejust use the
constant PLAY and AXCESS knows to use channel 1.
More than one constant can have the same number. For example, PLAY and
FWD can both equal 1. You will probably come across this if two cards do not
have the same channels for the same functions. PLAY on the VCR control card
might be channel 1, and FWD on the slide control card might also be channel 1.
By definition, the same constant cannot reference more than one number.
This may seem obvious, but this type of error could work its way into large
programs. If you make this mistake, AXCESS will notify you with a Duplicate
symbol error message upon compiling.

Defining variables
Variable
A place to store data that will
change as the program is
executed.

32

The Definition Sections

Variables are places to store data that will change as the program is executed.
Think of a variable as an anything box; nearly anything can be placed in here.
For example, a variable can represent a number. The numeric range is from 0 to
65,535; variables cannot hold a negative number. If one variable is subtracted
from another, the result will be positive. (If, however, you do subtract a larger
number from a smaller number, the result wraps around at 65,535. For instance, if you subtract 20 from 10, the result is 65,525).
Once the system is turned off, variables do not lose their values. If a certain
variable equals 3 when AXCESS is shut down, it will remain 3 when the system is
re-activated. This function has both advantages and drawbacks. It obviously
helps when you need AXCESS to retain values for the variables. However, if you
need those variables to be reset when the system is turned on, they must be reset
manually within the Define_Start section.
In your first program you will not be using variables, but keep the
Define_Variable header because you will be using them in the future. The
Define_Mutually_Exclusive, Define_Latching, and Define_Toggling sections are
also explained later.

Unit 2: Language Basics

Startup code
When the AXCESS system is turned on, the program that was last loaded into the
Master Card is in operation. It is waiting for input from the user. However, you
can tell AXCESS to run a series of statements immediately when the system is
turned on. These statements are placed under the Define_Start header, and they
are run only once on power-up. They cannot be executed again until another
AXCESS power-up.
In your program, you may want to reset all three decks to STOP when AXCESS
is powered up. Here is what your Define_Start section should look like:

This code fragment is from


STEP1.AXS on the AXCESS
distribution diskette.

DEFINE_START
PULSE [VCR,STOP]
PULSE [CD,STOP]
PULSE [CASS,STOP]

(Pulse is explained later in more detail.)


If variables need to be reset to certain values, the statements needed to do this
should be in this section. Remember, variables retain their values even if the system loses power.
An important note: The keyword To cannot be used within the Define_Start
section. Instead use On, Off, or Pulse. These keywords are explained later in the
unit.

Mainline
Before you begin the main program, you must have the Define_Program
header. This has no real function except to tell AXCESS that you are beginning the
actual program at this point. It is used simply like this:

DEFINE_PROGRAM
(* Your program starts here. *)

Mainline
The section of the program
that actually is executed
continuously by the Master
Card. Also known as the
Define_Program section.

Unit 2: Language Basics

The Define_Program header marks the start of what is called mainline. Mainline is the section of the program that actually runs while the Master Card is
operating. Mainline is the heart of the AXCESS program, and it is where you will
spend most of your time while programming an AXCESS system.

The Definition Sections

33

Figure 2-3
AXCESS continually loops
through mainline.

DEFINE_PROGRAM

Mainline

AXCESS continually
loops through mainline

The most important feature of mainline is that it runs in a continuous loop.


Most programming languages have a beginning and an end; they start at the
top, continue until they are finished, and quit. Not AXCESS. Mainline is like a
circle: when the Master Card gets to the end, it goes back to the top and passes
through it again. See Figure 2-3, and refer to the AXCESS Programming Guide for
a complete discussion of mainline and the AXCESS bus.

34

The Definition Sections

Unit 2: Language Basics

Using Input and Output

Controlling something over there


The basic idea behind remote control is to do something over here to make something happen over there. In an AXCESS system, the something over here is usually some kind of control panel, such as a wireless remote control panel or a
Touch Panel. The something over there can range from a simple relay to a
complex lighting system.
In mainline you define what happens when these inputs occur. But how do
you get your inputs in the program? How do you generate an output? The answer: you use channels.

All about the channel

Input change
A signal sent by the input
function of a channel that
alerts AXCESS to scan
mainline for a reference to
that signal.

Almost all methods of control using an AXCESS system require the use of channels on devices. Every channel has two aspects: the input function and the output function. See Figure 2-4. When a button is pressed on a control panel, the
input function of the button sends an input change to your program. The input
change alerts the Master Card to scan your program for a reference to that input.
When there is an input change, AXCESS passes through the entire program
once to see if the change is referenced. If so, AXCESS executes the statement(s) in
the program associated with the input change. There are six keywords used in
conjunction with input changes:
Push
Release
Push_Device

Figure 2-4

PUSH [Device,Channel]

INPUT
Input change

The input and output


functions of a channel.

RELEASE [Device,Channel]

OUTPUT
Channel
Mainline

Unit 2: Language Basics

Using Input and Output

35

Release_Device
Push_Channel
Release_Channel

Push
The Push keyword is used to find out if a channel has had an input change from
off to on, such as when a button is pressed. If the channel has been turned
on, the corresponding Push statement is activated. The operation or operations
following this Push statement are only executed once after the channel is turned on.
Push must be followed by a device number and a particular channel, and
both are enclosed in brackets. Variables can be used in their places, but this is
done only in special circumstances. Following the Push statement is the operation to be executed when the Push occurs. If more than one event must happen,
a compound statement must follow the Push. (See the earlier discussion on
compound statements.)

Release
The Release keyword is used in the same way as a Push, except that the operation underneath a Release statement will be executed if the corresponding button is released.

Push_Device
System variable
A value kept in the Master
Card that can be referenced
by certain keywords.

Push_Device is a system variable containing the number of the device having the
channel that was just turned on due to an input change. If a button for device
T_PANEL was pressed, Push_Device would be equal to the device number of
T_PANEL. This variable is set when a channel is turned on, and it remains constant for one pass through mainline. If no channel has been turned on,
Push_Device will contain zero.

Release_Device
NOTE
Push_Device and
Release_Device cannot both
have a non-zero value
during the same pass
through mainline. At least
one will always be zero.

36

Using Input and Output

Release_Device stores the number of the device containing the channel whose
button was most recently released. If a button for device T_PANEL was released,
Release_Device would be equal to the device number of T_PANEL. This system
variable is used in a program in the same manner as Push_Device. This variable
will have the same value for only one pass through the program.

Unit 2: Language Basics

Push_Channel
Push_Channel is the same as Push_Device, except in this case the channel number that was most recently turned on is stored inside the variable.

Release_Channel
NOTE
Push_Channel and
Release_Channel cannot
both have a non-zero value
during the same pass
through mainline. At least
one will always be zero.

Output change
A message to the output
function of a channel.

Release_Channel, on the other hand, stores the channel whose button was most
recently released. This system variable is used in a program in the same manner
as Push_Channel.

Changing the state of a channel


So now you can respond to an input change in your program, and you want it to
activate a different device-channel. The next series of keywords allow you to activate channels based on an input change. This activation is called an output
change, which is a message to the output function of a channel. See Figure 2-5.
The keywords to do this are the following:
On
Off
Total_Off
To
Pulse
When you use one of these keywords to activate a channel in a device, the
device starts the operation that is associated with the channel. For instance, activating channel 5 on a relay card activates relay number 5, whereas channel 5
on an infrared/serial card causes it to generate the infrared pattern it has

Figure 2-5
Keywords affecting output
changes.

[Device,Channel]

INPUT

ON [Device,Channel]
Output change
OUTPUT
Channel

OFF [Device,Channel]
TOTAL_OFF [Device,Channel]
TO [Device,Channel]
PULSE [Device,Channel]

Mainline

Unit 2: Language Basics

Using Input and Output

37

stored at location 5.
Variables can be used as output channels also, but doing so does not actually
cause an output change. When a variable is activated as a channel, turning it
on gives it a value of 1, and turning it off gives it a value of 0.
The following are some brief definitions of each of the output change keywords.

On
The On keyword simply turns on a channel or variable. If the channel or variable
is already on, its status will remain unchanged. Here are two different examples:
ON [1,2]

This turns on channel 2 of device 1.

ON [TEMP]

This sets the value of the variable TEMP to 1.

A variable is considered on if it contains a nonzero number; in this case, the


value is 1. If a variable contains the value zero, it is considered off.

Off
The Off keyword turns a channel or variable off. The channel or variable will
remain off if it is already off. Here are two different examples:
OFF [1,2]

This turns off channel 2 of device 1.

OFF [TEMP]

This sets the value of the variable TEMP to zero.

Total_Off
The Total_Off keyword acts in the same manner as Off, except that it also turns
off the status of a channel or variable that is in a mutually exclusive set. Mutually exclusive sets are discussed later in this unit.

To
The To keyword is used to activate a channel or variable for as long as the corresponding device-channel of its Push statement is activated. When the devicechannel referenced by the Push statement changes from off to on, the To starts
activating the device-channel or variable in the brackets following it. When the
device-channel of its Push is released, the To statement stops activating its device-channel or variable. For this reason, To must be found only underneath a
Push statement.
The To keyword has several conditions:
It must be used only below a Push statement.
It cannot be used with the Wait keyword. (This will be explained later.)
It cannot be placed within the Define_Start section.

38

Using Input and Output

Unit 2: Language Basics

The channel or variable will act under the rules set by Define_Latching,
Define_Mutually_Exclusive, and Define_Toggling. You will learn what these
definitions mean later when you add more to your program.

Pulse
The Pulse keyword turns on a channel or variable for a certain amount of time.
Once the time elapses, the channel or variable is turned off.
As an example, refer back to the discussion on Define_Start. The Pulse keyword was used to activate the three decks Stop function. The duration of this
Pulse is one half-second, but it can be changed if necessary with the Set_Pulse_
Time keyword. The Pulse time is measured in tenths of seconds, and the AXCESS
default is one half-second. The Pulse time remains the same value until it is
changed within the program. Here is an example of Set_Pulse_Time:

SET_PULSE_TIME(12)

This sets the current duration of future Pulses to 1.2 seconds.

Direct assignment
There is another method of generating an output change, but it does not involve
the use of any keywords. Any reference to a device-channel that does not have
the keywords Push or Release preceding it is a reference to the output side of
the channel. Thus assigning a value directly to a device-channel changes the output of the channel. For example:
[SWP,1] = 1

This statement will send an output change to channel 1 of device SWP, telling
the channel to turn on since AXCESS interprets any non-zero number as on.
Putting this statement in mainline will make the channel be forever on.
Using direct assignment is only appropriate in feedback statements. In most
situations, the keywords On, Off, and To are more appropriate.

Putting input and output together


Combining input and output changes into one statement is the basis of most
AXCESS programming. Now that you have these tools, you can write the code
that will actually accomplish this. On your Softwire Panel, you will have button
numbers 1 through 5 activate the five transport functions of the VCR: Play, Stop,
Pause, Fast Forward, and Rewind. Here is your first section of program code:

Unit 2: Language Basics

Using Input and Output

39

This code fragment is from


STEP1.AXS on the AXCESS
distribution diskette.

PUSH[SWP,1]
TO [VCR,PLAY]
PUSH[SWP,2]
TO [VCR,STOP]
PUSH[SWP,3]
TO [VCR,PAUSE]
PUSH[SWP,4]
TO [VCR,FFWD]
PUSH[SWP,5]
TO [VCR,REW]

In this code, there are actually five separate but similar statements. Examine
the first to see how it all fits together. First there is the keyword Push, followed
by a device-channel reference, in this case [SWP,1]. This tells AXCESS, OK,
look here if channel 1 on device 128 receives an input change from off to on. If
such an input change occurs, the corresponding To statement executes. The To
statement tells AXCESS, For as long as channel 1 on device 128 is activated,
turn on device 1, channel 1. You may be wondering where the numbers came
from, since the Push and To statements have the words SWP, VCR, and PLAY.
Remember, SWP is a device definition for device 128, and VCR is a constant with
a value of 1, as is PLAY.
Duplicate the above section for the CD player and the cassette deck, replacing
VCR with CD and CASS where needed. Also be sure to use different channel numbers for the Push statements, or one activation of channel 1 could make all three
decks play at the same time.
Now that you have the transport functions of your decks programmed, you
can add the rest of the functions on your panel to the program. But before you
do that, you need to learn about the other definition sections: those that define
the characteristics of a channel.

40

Using Input and Output

Unit 2: Language Basics

Channel Characteristics

The parts of an output channel


An output channel actually has two parts, the physical part and the status part
(simply referred to as status). See Figure 2-6. The physical part is the devicedependent physical control, such as a relay on a relay card, a button light
(lamp) on a Softwire Panel, or an infrared pattern in an infrared card. The status is what records the state of the physical part. In most applications, these two
parts act exactly the same; when one is on, so is the other.
However, you can change the way the status part of an output channel behaves. In this chapter, you will be shown how to change the status behavior,
which in turn changes the way a channel reacts when it is activated by the output change keywords.

Figure 2-6
Parts of an output channel.

INPUT

OUTPUT
Physical

Output change

Status

Channel

Unit 2: Language Basics

Channel Characteristics

41

Defining latching
Momentary
A defined behavior of status
that causes its output
channel to be activated as
long as the corresponding
button is pressed.

Latching
A defined behavior of status
that causes its output
channel to stay on or off until
activated once more.

This code fragment is from


STEP1.AXS on the AXCESS
distribution diskette.

All channels are momentary by default.* When a momentary channel is activated


with a To keyword, it activates its output and status only as long as the button
which activated the To keyword is pressed. For example, the Focus channel for a
certain slide projector is momentary. When the corresponding Focus button is
pressed, the slide projector will focus. The projector will continue to do so until
the button is released.
However, some devices need their particular channel to stay on in order to
operate. If so, the channel can be made latching by being placed in the Define_
Latching section. Once a latching channel is activated by a To keyword, the
channel changes its state from off to on (considering it was previously off).
However, when the To keyword stops activating the channelthat is, its corresponding button is releasedthe channel does not go back to off like a momentary channel. It stays on. Only when the channel is re-activated by a To keyword
does it return its state back to off. As a result, the status of a latching channel
reflects the true on/off state of the channel.
In your program, RELAY is already defined as device number 4 and
SYS_POWER is defined as a constant having the value 3. Using these two values
together as device-channel [RELAY,SYS_POWER] gives you a relay to use for your
systems power control. You will need to make this relay latching so that it stays
on after you release the Softwire Panel button. Also, your drape motor needs
latched relays to operate. Here are the definitions:

DEFINE_LATCHING
[RELAY,SYS_POWER]
[RELAY,DRAPE_OPEN]
[RELAY,DRAPE_CLOSE]

If you have a series of consecutive channels to be defined, you can use a shortcut. The use of double periods (..) will specify a range of channels between the
first and last channel. Suppose the lights your system controls needs latched relays to operate. Instead of defining each one right after the other, you can do this:

This code fragment is from


STEP1.AXS on the AXCESS
distribution diskette.

[LIGHTS,LIGHT_FULL]..[LIGHTS,LIGHT_OFF]

* Actually, the correct terminology here is the status of all channels is momentary by default.
However, in the common language of programmers, status is understood. From this point on
in the manual, the behavior of status will be described in this manner.

42

Channel Characteristics

Unit 2: Language Basics

In your Define_Constant section, you defined these constants as 1 through 4,


so this will make relays 1 through 4 on the LIGHTS card (card 5) latching.

Mutually exclusive
Channels can also be defined as mutually exclusive. A mutually exclusive group
is a set of channels in which only one channel of the set can be turned on at a
time. There are three kinds of mutually exclusive channels: momentary, latching, and toggling.

Defining momentary mutually exclusive


Momentary mutually
exclusive
A characteristic of status that
allows only one channel of a
pre-defined set to be on at a
time. The output channel is
activated as long as the
corresponding button is
pressed.

IMPORTANT
Make sure you find out which
devices need mutually
exclusive channels. Do not
wait until you test out the
program, as you may
damage some devices.

NOTE
Once a channel has
feedback in a mutually
exclusive group, there will
always be one channel with
its status on in that group,
unless it is turned off with
Total_Off.

This code fragment is from


STEP1.AXS on the AXCESS
distribution diskette.

Unit 2: Language Basics

When a channel is turned on in a momentary mutually exclusive set, it activates its


physical output as long as the button is pressed. When the button is released, the
physical output stops. The status, however, does not work in the same manner.
Even after the physical output stops, the status still indicates that the channel is
on until another channel in the mutually exclusive set is activated. The status is
on to let you know which channel in the set was last activated. This is sometimes
called last button pressed feedback.
When a channel or variable in this set is activated, all the other members of
the set are turned off beforehand. This is called break before make logic. This
prevents an accidental activation of more than one channel at the same time,
which could cause serious damage to some devices.
For example, consider the drape and screen channels of the device RELAY.
Since you cannot open and close a drape all at once, and you cannot raise a
screen and lower it at the same instant (it could damage some motors if you
tried!), only one channel can be turned on at a time. They must be defined as
mutually exclusive. When SCREEN_UP is activated, the SCREEN_DOWN channel is
turned off and SCREEN_UP turns on. The corresponding SCREEN_UP status stays
on even though the relay is de-energized when the button is released. When
SCREEN_DOWN is activated, SCREEN_UP is turned off. The SCREEN_DOWN status
is now the only status turned on.
You also will define the lighting relays as mutually exclusive so that you can
utilize the last button pressed logic when you program the feedback for these
buttons. This will allow the user to look at the panel and know which lighting
preset he or she activated last.
Members of a mutually exclusive set are placed in parentheses underneath
the Define_Mutually_Exclusive keyword. The double period (..) shortcut explained in the latching section is also applicable here. For example:

DEFINE_MUTUALLY_EXCLUSIVE
([RELAY,SCREEN_UP],[RELAY,SCREEN_DOWN])
([RELAY,DRAPE_OPEN]..[RELAY,DRAPE_STOP])

Channel Characteristics

43

([LIGHTS,LIGHT_FULL]..[LIGHTS,LIGHT_OFF])
([VCR,PLAY]..[VCR,REW])
([CASS,PLAY]..[CASS,REW])
([CD,PLAY]..[CD,REW])

The first set defines the two screen channels as mutually exclusive. Using the
shortcut, the second set defines the three drape channels as mutually exclusive,
and the third set defines the four lighting relays as mutually exclusive. The
fourth through the last sets also use the shortcut to define the five transport
functions as mutually exclusive. This is done to achieve last button pressed
status for those decks. When you add the feedback statements to the program,
the buttons for the VCR, CD player, and cassette deck will indicate the last button
selected from each group.

Defining mutually exclusive latching

Mutually exclusive
latching
A characteristic of status
that allows only one channel
of a pre-defined set to be on
at a time. The output channel
stays on until another channel
of the set is activated.

This code fragment is from


STEP1.AXS on the AXCESS
distribution diskette.

There is a way for a mutually exclusive channel have its physical output continually on if necessary: a channel can be defined as both mutually exclusive and
latching, resulting in the description mutually exclusive latching. If you define a
channel in this manner, the physical output remains on until another button in
its mutually exclusive set is pressed.
The status of a mutually exclusive latching channel behaves in the same manner
as that for a mutually exclusive momentary channel. Note that the physical part
and the status of a mutually exclusive latching channel operate in the same manner.
In your program, the lighting relays are already defined as latching. However, you also want them to have the characteristics of a mutually exclusive set;
only one lighting mode can be on at one time. Thus you would also place the
device-channels of these relays in the Define_Mutually_Exclusive section:

DEFINE_MUTUALLY EXCLUSIVE
([LIGHTS,LIGHT_FULL]..[LIGHTS,LIGHT_OFF])

Defining mutually exclusive toggling


Mutually exclusive
toggling
A characteristic of status that
allows only one channel of a
pre-defined set to be on at a
time. The output channel
stays on until it is reactivated or another channel
of the set is activated.

44

Channel Characteristics

When a channel is defined as mutually exclusive latching, there is no way to


turn off the channel without activating another. Mutually exclusive toggling allows a channel to be turned on or off by successive presses of the same button,
just like a normal latching channel. Also, the channel is still affected by its mutually exclusive characteristics; if the channel is on, it can be turned off by another activated channel in its mutually exclusive set. The status of a mutually
exclusive toggling button operates in the same way as that for a mutually exclusive latching button.

Unit 2: Language Basics

In order to make a channel toggling, it must be defined as mutually exclusive


and toggling in both the Define_Mutually_Exclusive and Define_Toggling sections. In your program, the screen relays are both mutually exclusive and latching,
and thus there is no way to turn off a screen relay without turning on the other.
You could fix this by defining the screen relays as mutually exclusive toggling:

This code fragment is from


STEP1.AXS on the AXCESS

distribution diskette.

DEFINE_TOGGLING
[RELAY,SCREEN_UP]
[RELAY,SCREEN_DOWN]

Putting it all to work


Now that you know just how all these different types of channels operate, you
can skip down to the mainline section of the program and add these lines to activate your system power, screen, drape, and lighting relays:

This code fragment is from


STEP1.AXS on the AXCESS
distribution diskette.

PUSH[SWP,8]
TO [RELAY,SYS_POWER]
PUSH[SWP,33]
TO [RELAY,SCREEN_UP]
PUSH[SWP,34]
TO [RELAY,SCREEN_DOWN]
PUSH[SWP,41]
TO [RELAY,DRAPE_OPEN]
PUSH[SWP,42]
TO [RELAY,DRAPE_CLOSE]
PUSH[SWP,43]
TO [RELAY,DRAPE_STOP]
PUSH[SWP,45]
TO [LIGHTS,LIGHT_FULL]
PUSH[SWP,46]
TO [LIGHTS,LIGHT_MED]
PUSH[SWP,47]
TO [LIGHTS,LIGHT_LOW]
PUSH[SWP,48]
TO [LIGHTS,LIGHT_OFF]

This section accomplishes several tasks:


Pressing button number 8 on the Softwire Panel alternately latches and
unlatches the SYS_POWER channel (channel 1) on card RELAY

Unit 2: Language Basics

Channel Characteristics

45

A press of the Screen Up button latches on the SCREEN_UP channel on


device RELAY, after unlatching SCREEN_DOWN. The Screen Down button
acts the same way as the Screen Up button, but with the opposite channels.
Pressing Drape Open or Drape Close does several things. If it is off, it
makes sure the other drape channel is off (due to its mutually exclusive
relationship), then it latches on. If it was on, it simply turns off, but leaves
its status on. (Remember, to turn off the status of a channel in a mutually
exclusive group, use the keyword Total_Off.)
Since the LIGHTS channels are mutually exclusive latching, a press of the
Lights Full button latches on the LIGHT_FULL channel on the device LIGHTS,
after unlatching any LIGHTS channel that was previously on. The other
LIGHTS channels operate in a similar fashion.
Now here is the twist. The DRAPE_STOP channel is momentary mutually exclusive, whereas the other drape channels are mutually exclusive latching. When
the Drape Stop button is pressed, AXCESS makes sure the other drape channels
are off, then engages the DRAPE_STOP channel. Unlike the DRAPE_OPEN and
DRAPE_CLOSE channels, however, the DRAPE_STOP channel turns off when the
button is released. Like the others, its status stays on because it is in the mutually exclusive group with the other Drape channels.

Programming feedback

Feedback
The lighting of a button
during and after it is pressed.

So far you have been shown how a channels output is affected in a program.
You know what to do with the input changes and how to create output changes,
but now you want to see some feedback on your Softwire Panel. Feedback refers
to the lighting of a button during and after it is pressed. AXCESS will not do this
automatically; you must tell the system how to light the button.
Feedback involves only one statement per button. The first part of the statement references the device-channel of the button that is going to be lit. It is followed by an equal sign (=) and the device-channel corresponding to the source
of the feedback. For example:

[SWP,1] = [VCR,PLAY]

When VCR channel 1 (the constant value of PLAY) is on, the light of SWP button 1 will also be on. When the channel is off, the light will be off.
Remember that any reference to a device-channel that does not have the keyword Push or Release preceding it is referring to the output side of the channel.
This is a very important concept, because it is the basis of how feedback works.

46

Channel Characteristics

Unit 2: Language Basics

NOTE
Once a channel has
feedback in a mutually
exclusive group, there will
always be one channel with
feedback on in that group,
until turned off with Total_Off.

Also recall that one way of creating an output change is to assign a value directly to the device-channel. If the value that you are assigning is another device-channel reference, this is in effect saying to AXCESS, Take the output status
of channel PLAY on device VCR, and send it as an output change to channel 1 of
device SWP. Since you defined the device-channel [VCR,PLAY] as being in a
mutually exclusive group, its status will be on if it was the last channel activated
in that set, and the feedback assignment will light button 1 on the Softwire Panel.

Grouping feedback statements


The feedback statement is sometimes found after the end of a Push statement.
For example:

PUSH[SWP,1]
TO[VCR,PLAY]
[SWP,1] = [VCR,PLAY]

When SWP button 1 (Play) is pressed, both VCR channel 1 (PLAY) and the
buttons feedback are turned on.
The feedback statements can also be grouped together in a feedback section at
the end of the program. For example:

This code fragment is from


STEP1.AXS on the AXCESS

distribution diskette.

NOTE
For the sake of saving space,
the additional feedback
statements for your program
are listed in the next chapter.
But first, try to write them on
your own.

Unit 2: Language Basics

[SWP,1] = [VCR,PLAY]
[SWP,2] = [VCR,STOP]
[SWP,3] = [VCR,PAUSE]

This feedback section will act no differently if each statement is placed under
its corresponding Push statement.
Where you locate your feedback statements inside your program makes no
difference to the operation of the system, but it does make a difference in the
readability of your program. Grouping all of the feedback statements at the end
of the program is fine, but in larger programs it can be a hassle to skip from the
top where the Push is located to the bottom where the feedback statements is
located. Smaller programs, however, may be easier to manage if all the Pushes
are together and all the feedback statements are together. A good compromise
is to break your program into sections of code where each section has a similar
group of functions, and put the feedback statements for each section right below it. (See Figure 2-7.)

Channel Characteristics

47

Code

Code

Code

Feedback

Code

Code

Code
Code

Code

Feedback

Feedback
Feedback

Feedback
Code

Feedback

Code

Feedback

Feedback

Code

Feedback
Code

Feedback

Feedback

Feedback

Feedback directly afterwards

Feedback at the end

Combination

Figure 2-7
Different positions for
feedback statements.

48

Channel Characteristics

Unit 2: Language Basics

Your First Program

The program and the panel


This chapter contains your first finished program and a drawing of the Softwire
Panel layout, which is pictured in Figure 2-8. On the next few pages is the entire
source code for the program you developed in this unit. This code can be found
on your distribution disk as STEP1.AXS.
Notice that in this system, all of the feedback is at the bottom. If your program
does not look exactly like this one, dont worry! Ten people could write the same
program and none would look exactly the same. What is important is that it operates the way in which you intend.

VCR

CD

CASS

SCREEN

DRAPE

PLAY

PLAY

PLAY

UP

OPEN

STOP

STOP

STOP

DOWN

CLOSE

PAUSE

PAUSE

PAUSE

FFWD

SKIP
FWD

FFWD

REW

SKIP
REV

REW

STOP

LIGHTS
FULL

MED

LOW

SYSTEM POWER

OFF

Figure 2-8
The Softwire Panel layout
based on your program.

Unit 2: Language Basics

Your First Program

49

(***********************************************************)
(*
DEVICE NUMBER DEFINITIONS GO BELOW
*)
(***********************************************************)
DEFINE_DEVICE
VCR
CD
CASS
RELAY
LIGHTS
SWP

=
=
=
=
=
=

1
2
3
4
5
128

(***********************************************************)
(*
CONSTANT DEFINITIONS GO BELOW
*)
(***********************************************************)
DEFINE_CONSTANT
(* TRANSPORT CHANNEL NUMBERS *)
PLAY = 1
STOP = 2
PAUSE = 3
FFWD = 4
REW
= 5
(* THE RELAY CARD CHANNEL DEFINITIONS *)
SCREEN_UP
= 1
SCREEN_DOWN = 2
SYS_POWER
= 3
DRAPE_OPEN = 4
DRAPE_CLOSE = 5
DRAPE_STOP = 6
(* THE LIGHT
LIGHT_FULL =
LIGHT_MED =
LIGHT_LOW =
LIGHT_OFF =

CARD CHANNEL DEFINITIONS *)


1
2
3
4

(***********************************************************)
(*
VARIABLE DEFINITIONS GO BELOW
*)
(***********************************************************)
DEFINE_VARIABLE
(***********************************************************)
(*
LATCHING DEFINITIONS GO BELOW
*)
(***********************************************************)
DEFINE_LATCHING
[RELAY,SYS_POWER]
[RELAY,DRAPE_OPEN]
[RELAY,DRAPE_CLOSE]
[LIGHTS,LIGHT_FULL]..[LIGHTS,LIGHT_OFF]

50

Your First Program

Unit 2: Language Basics

(***********************************************************)
(*
MUTUALLY EXCLUSIVE DEFINITIONS GO BELOW
*)
(***********************************************************)
DEFINE_MUTUALLY_EXCLUSIVE
([RELAY,SCREEN_UP],[RELAY,SCREEN_DOWN])
([RELAY,DRAPE_OPEN]..[RELAY,DRAPE_STOP])
([LIGHTS,LIGHT_FULL]..[LIGHTS,LIGHT_OFF])
([VCR,PLAY]..[VCR,REW])
([CASS,PLAY]..[CASS,REW])
([CD,PLAY]..[CD,REW])
DEFINE_TOGGLING
[RELAY,SCREEN_UP]
[RELAY,SCREEN_DOWN]
(***********************************************************)
(*
STARTUP CODE GOES BELOW
*)
(***********************************************************)
DEFINE_START
PULSE [VCR,STOP]
PULSE [CD,STOP]
PULSE [CASS,STOP]
(***********************************************************)
(*
THE ACTUAL PROGRAM GOES BELOW
*)
(***********************************************************)
DEFINE_PROGRAM
PUSH[SWP,1]
TO [VCR,PLAY]
PUSH[SWP,2]
TO [VCR,STOP]
PUSH[SWP,3]
TO [VCR,PAUSE]
PUSH[SWP,4]
TO [VCR,FFWD]
PUSH[SWP,5]
TO [VCR,REW]
PUSH[SWP,9]
TO [CD,PLAY]
PUSH[SWP,1]
TO [CD,STOP]
PUSH[SWP,11]
TO [CD,PAUSE]
PUSH[SWP,12]
TO [CD,FFWD]
PUSH[SWP,13]
TO [CD,REW]
PUSH[SWP,17]
TO [CASS,PLAY]
PUSH[SWP,18]
TO [CASS,STOP]

Unit 2: Language Basics

Your First Program

51

PUSH[SWP,19]
TO [CASS,PAUSE]
PUSH[SWP,2]
TO [CASS,FFWD]
PUSH[SWP,21]
TO [CASS,REW]
PUSH[SWP,8]
TO [RELAY,SYS_POWER]
PUSH[SWP,33]
TO [RELAY,SCREEN_UP]
PUSH[SWP,34]
TO [RELAY,SCREEN_DOWN]
PUSH[SWP,41]
TO [RELAY,DRAPE_OPEN]
PUSH[SWP,42]
TO [RELAY,DRAPE_CLOSE]
PUSH[SWP,43]
TO [RELAY,DRAPE_STOP]
PUSH[SWP,45]
TO [LIGHTS,LIGHT_FULL]
PUSH[SWP,46]
TO [LIGHTS,LIGHT_MED]
PUSH[SWP,47]
TO [LIGHTS,LIGHT_LOW]
PUSH[SWP,48]
TO [LIGHTS,LIGHT_OFF]
(* FEEDBACK *)
[SWP,33] = [RELAY,SCREEN_UP]
[SWP,34] = [RELAY,SCREEN_DOWN]
[SWP,1]
[SWP,2]
[SWP,3]
[SWP,4]
[SWP,5]

=
=
=
=
=

[VCR,PLAY]
[VCR,STOP]
[VCR,PAUSE]
[VCR,FFWD]
[VCR,REW]

[SWP,9] = [CD,PLAY]
[SWP,1] = [CD,STOP]
[SWP,11] = [CD,PAUSE]
[SWP,12] = [CD,FFWD]
[SWP,13] = [CD,REW]
[SWP,17]
[SWP,18]
[SWP,19]
[SWP,2]
[SWP,21]

=
=
=
=
=

[CASS,PLAY]
[CASS,STOP]
[CASS,PAUSE]
[CASS,FFWD]
[CASS,REW]

[SWP,8] = [RELAY,SYS_POWER]

52

Your First Program

Unit 2: Language Basics

[SWP,41] = [RELAY,DRAPE_OPEN]
[SWP,42] = [RELAY,DRAPE_CLOSE]
[SWP,43] = [RELAY,DRAPE_STOP]
[SWP,45]
[SWP,46]
[SWP,47]
[SWP,48]

=
=
=
=

[LIGHTS,LIGHT_FULL]
[LIGHTS,LIGHT_MED]
[LIGHTS,LIGHT_LOW]
[LIGHTS,LIGHT_OFF]

(***********************************************************)
(*
END OF PROGRAM
*)
(*
DO NOT PUT ANY CODE BELOW THIS COMMENT
*)
(***********************************************************)

Unit 2: Language Basics

Your First Program

53

AXCESS Language Tutorial

UNIT 3

CONDITIONALS,
LOOPS,
AND WAITS

If and the Boolean Expressions

Introduction
While your first program may look complicated at first, it really doesnt show
the power of the AXCESS language. The program is what we at AMX call one-toone. That means that each button has one and only one function, with no special conditions or considerations. The control panel has a separate section of
buttons for each piece of equipment.
But suppose you want the same number of functions with fewer buttons. A
common solution is to have several groups of buttons with similar functions reduced to one group, with a set of buttons that selects which piece of equipment
the buttons control. In your program, you could have one button for each piece
of equipment to select each deck, and one set of transport buttons. Your panel
could now look like the one in Figure 3-1.

SELECT

TRANSPORT

SCREEN

DRAPE

VCR

PLAY

UP

OPEN

CD

STOP

DOWN

CLOSE

CASS

PAUSE

STOP

FFWD
LIGHTS
REW

FULL

MED

LOW

SYSTEM POWER

OFF

Figure 3-1
The revised Softwire Panel
layout for your program. The
functions are the same, but
there are fewer buttons.

Unit 3: Conditionals, Loops, and Waits

If and the Boolean Expressions

57

You now have seven fewer buttons than you did before. What you want to happen with this panel is that the user selects the deck with a Select button, then controls it with the Transport buttons. This will not be a one-to-one program because
the Transport buttons each have three possible functions. In the program you will
use Boolean expressions to select the correct function of the Transport buttons.

Boolean expressions
Boolean expression
A conditional statement used
to tell AXCESS whether or not
to execute a particular
function or functions in the
program. Also known as a
relational expression.

A Boolean, or relational, expression is used to tell AXCESS whether or not to execute


a particular function or functions in the program. Picture yourself walking along
a path in the country. Suddenly you come upon a fork in the road. Which way
should you go? If you guess, you might become lost. Therefore you judge certain conditions before continuing. Is the left road heading north? Is the right
road heading east?
This is what AXCESS must do whenever you branch off in different directions
in your program. Either AXCESS continues in the direction it is going, or it must
jump to a different section.
A Boolean expression can have one of two results, true or false. In AXCESS,
any non-zero value is true and a zero value is false. When AXCESS evaluates a
Boolean expression, it assigns a 1 for a true result, and a zero for a false result.

The If statement
The most common keyword in AXCESS that uses Boolean expressions is the If
keyword. Every If statement must be followed by a Boolean expression enclosed
in parentheses. This provides the beginning of a conditional execution of statements. The structure is as follows:

IF (Boolean expression)
(Statement 1)

If the Boolean expression is true, AXCESS executes Statement 1 and then continues with whatever statements follow. If the Boolean expression is false, Statement 1
is ignored. If Statement 1 is a compound statement, it must be enclosed in braces.

The If...Else set of statements


This is similar to the basic If statement, with the addition of one more branch. If
the Boolean expression is false, AXCESS executes a function independent of the
true Boolean expression. For example:

58

If and the Boolean Expressions

Unit 3: Conditionals, Loops, and Waits

IF (Boolean expression)
(Statement 1)
ELSE
(Statement 2)

If the Boolean statement is true, then Statement 1 is executed. Statement 2, underneath the Else statement, is ignored. If the Boolean statement is false, then
Statement 2 is executed. Remember that Statement 1 is automatically ignored if
the expression is false.

The If...Else If set of statements


Whereas using If and If...Else allows two different paths, using If...Else If allows
an essentially unlimited number of paths. AXCESS stops at the first true Boolean
expression and executes the following function. After completion, it goes on to
the rest of the program. For example:

IF (Boolean expression)
(Statement 1)
ELSE IF (Boolean expression)
(Statement 2)
ELSE IF (Boolean expression)
(Statement 3)
(* As many Else If statements as memory allows... *)

Default statement
A statement (or compound
statement) that executes if
none of the conditions being
tested comes true.

Nesting
Placing conditional branches
inside other conditional
branches.

A last Else statement (not Else If) can be placed at the end as a default statement; that is, if AXCESS does not find a true If or Else If statement, it executes the
final Else statement. However, this last statement is not necessary.

Nesting
Once AXCESS is travelling along a branch (for example, Statement 1 in the previous example), you can tell it to branch off again with another If statement. This
branch within a branch is called nesting. There can be any level of branches; an
If can be within an If within an If, and so on. The only restriction is the amount of
memory available.
When you are nesting If...Else statements, be sure to use braces. Look at the
following incorrect example:

IF (X = 5)
IF (Y = 1)
(Statement 1)
ELSE
(Statement 2)

Unit 3: Conditionals, Loops, and Waits

If and the Boolean Expressions

59

You can see by the alignment of the Else statement with the IF (X = 5) that
these two should be associated. The second If statement is not supposed to have
an Else counterpart in this example. However, such is not the case. AXCESS pairs
the second If statement with the Else, because the compiler associates the Else
with the closest If statement.
With braces, you can force the compiler to associate the Else with IF (X =
5). For example:

IF (X = 5)
{
IF (Y = 1)
(Statement 1)
}
ELSE
(Statement 2)

By using the braces, you isolate the IF (Y = 1) statement from the If...Else
set of statements.

The Select...Active statement


There is a way to make If...Else If nesting easier: the Select...Active statement. This
allows the easy placement of several branches from one path. This is the format:

SELECT
{
ACTIVE (Boolean expression 1) : (Statement 1)
ACTIVE (Boolean expression 2) : (Statement 2)
ACTIVE (Boolean expression 3) : (Statement 3)
(* ...etc. *)
}

Each one of the Boolean expressions, in order, is evaluated until one is found
to be true. The statements associated with that true expression are then executed, and the path then flows to whatever statements follow the closing brace.
Using a Select...Active is much preferred to multiple If...Else If statements; it
uses less memory and it runs faster. If too many If...Else If statements are
chained together, they can overflow the Master Cards memory and crash the
entire system. Obviously it is much better to use Select...Active in such situations.
When using the If...Else set of statements, the code following the Else is the
default statementif the condition of the If is false, the default statement following the Else is executed. So what happens in a Select...Active if none of the con-

60

If and the Boolean Expressions

Unit 3: Conditionals, Loops, and Waits

ditions evaluate as true? In such a case, no code of any Active statement will be
executed, since Select...Active has no default statement. You can, however, create your own default for a Select...Active:

SELECT
{
ACTIVE
ACTIVE
ACTIVE
ACTIVE
}

(condition) : (statement)
(condition) : (statement)
(condition) : (statement)
(1) : (default statement)

Here, the last Active will always be true, and will execute only if all of the
conditions of the previous Actives are false. This makes the last Actives statement the default statement.

Trying it out

BUZZWORD
Select groups refer to a
group of buttons that select
a single deck or device out of
a group. In this case, the
select group consists of the
VCR, CD player, and the
cassette deck.

Now you can write the code for your new panel layout. Before you do that,
however, you will need to update your definition sections a little.
There are two methods of implementing select groups. One is to base the
selection on which variable of a mutually exclusive set is active. The other is to
use one variable and change its value based on which deck is selected. You will
explore the mutually exclusive variable method first.

Mutually exclusive variable method


In this method, you create a variable for each selection you need and make the
variables mutually exclusive. Variables can be made mutually exclusive in the
same way device-channels can. First you create the variables in the
Define_Variable section:

DEFINE_VARIABLE
VCR_SELECT
CD_SELECT
CASS_SELECT

This code fragment is from


STEP2.AXS on the AXCESS
distribution diskette.

Now you make the variables mutually exclusive by adding this line to the
Define_Mutually_Exclusive section:

This code fragment is from


STEP2.AXS on the AXCESS
distribution diskette.

Unit 3: Conditionals, Loops, and Waits

(VCR_SELECT,CD_SELECT,CASS_SELECT)

If and the Boolean Expressions

61

Notice that there are only parentheses around the whole group and no brackets. This is because brackets are only necessary when a device-channel reference
is used. Now you can make the Push for each Select button go To one of these
variables. Due to the last button pressed nature of the variables status, you
can determine which deck was last selected. Here is the mainline code:

PUSH [SWP,1]
TO [VCR_SELECT]
PUSH [SWP,2]
TO [CD_SELECT]
PUSH [SWP,3]
TO [CASS_SELECT]

This code fragment is from


STEP2.AXS on the AXCESS
distribution diskette.

Notice that even though you do not use brackets in the mutually exclusive
section with variables, you do in the To statement. This is because the To statement always requires brackets.
Now you can add your conditional statements. Look at the VCR functions
first, noting that the button numbers on the Softwire Panel for the transport buttons are 17 through 21 for all three decks.

IF (VCR_SELECT)
{
PUSH[SWP,17]
TO [VCR,PLAY]
PUSH[SWP,18]
TO [VCR,STOP]
PUSH[SWP,19]
TO [VCR,PAUSE]
PUSH[SWP,2]
TO [VCR,FFWD]
PUSH[SWP,21]
TO [VCR,REW]
}

Notice that the Boolean expression of the If statement is simply a variable.


What happens is that the If tests the variable to see if it is zero or non-zero. The
only time it is non-zero is if it was the last variable set by one of the Select buttons. If another Select button is pressed, the other mutually exclusive variables
are turned off and the new SELECT variable is turned on. When you duplicate the
above code for the CD player and the cassette player, only one section will run at
a time, which is what you want. Make sure that all three sections have the same
button device-channels in the Push statements.

62

If and the Boolean Expressions

Unit 3: Conditionals, Loops, and Waits

Not only are the functions of the Transport buttons conditional, but the feedback is too. You could make three more If statements, one for the feedback of
each deck. Yet a better method is to include each decks feedback statements in
the same If statement as the control statements. By doing this, your VCR section
now looks like this:

IF (VCR_SELECT)
{
PUSH[SWP,17]
TO [VCR,PLAY]
PUSH[SWP,18]
TO [VCR,STOP]
PUSH[SWP,19]
TO [VCR,PAUSE]
PUSH[SWP,2]
TO [VCR,FFWD]
PUSH[SWP,21]
TO [VCR,REW]

This code fragment is from


STEP2.AXS on the AXCESS
distribution diskette.

[SWP,17]
[SWP,18]
[SWP,19]
[SWP,2]
[SWP,21]

=
=
=
=
=

[VCR,PLAY]
[VCR,STOP]
[VCR,PAUSE]
[VCR,FFWD]
[VCR,REW]

Repeating this procedure for each deck completes the programming required
to implement your new panel layout using mutually exclusive variables. The
entire source code up to this point is on your distribution disk as STEP2.AXS.

The variable assignment method

Select variable
A variable whose value
determines which device in a
group is currently selected.

Another method of programming select groups is to use one variable, assigning


different values to it depending on what is selected. This method is actually
more powerful than the previous method, as it provides more flexibility while
using a lot less code.
Before writing the program using this method, go back to the STEP1.AXS program. First add just one variable, DECK. This will be the select variable. To this
variable you will assign the device number of your currently selected deck. Here
is your Select buttons code:

This code fragment is from


STEP3.AXS on the AXCESS
distribution diskette.

Unit 3: Conditionals, Loops, and Waits

PUSH[SWP,1]
DECK = VCR
PUSH[SWP,2]
DECK = CD
PUSH[SWP,3]
DECK = CASS

If and the Boolean Expressions

63

Now here is where you see some of the real power of the AXCESS language.
You can reduce the number of transport sections from three to just one by using
the variable DECK as the device number in the To statements, instead of using
VCR, CD, and CASS. Heres the section of code:

PUSH[SWP,17]
TO [DECK,PLAY]
PUSH[SWP,18]
TO [DECK,STOP]
PUSH[SWP,19]
TO [DECK,PAUSE]
PUSH[SWP,2]
TO [DECK,FFWD]
PUSH[SWP,21]
TO [DECK,REW]

This code fragment is from


STEP3.AXS on the AXCESS
distribution diskette.

Notice that there is no If statement necessary, no mutually exclusive variables


are necessary, and this is the only deck transport section of programming needed
in the whole program! But how does this work? Suppose you want to play the
CD player. First you press the CD Select button. This assigns the value 2 (the constant value of CD) to the variable DECK. Now the device-channel references of
the To transport statements will reference device number 2 (the CD device).
Pressing button number 17 on the Softwire Panel will activate [DECK,PLAY],
which AXCESS will interpret as [2,1].
The feedback for the transport section works in the same manner as the control section. The feedback statements use the DECK variable as the device from
which to get the feedback. These statements for the selection buttons, however,
are something new:

[SWP,1] = (DECK = VCR)


[SWP,2] = (DECK = CD)
[SWP,3] = (DECK = CASS)

This code fragment is from


STEP3.AXS on the AXCESS
distribution diskette.

These statements, like all feedback statements, are direct assignment output
changes; however, the source of the assignment is a Boolean expression. In interpreting this kind of feedback statement, AXCESS first evaluates the Boolean expression. If the expression is evaluated as true, AXCESS replaces the expression
with a 1; otherwise AXCESS replaces it with a zero. (Remember, only one of these
will be evaluated as true because a variable cannot have two different values at
one time.) Thus the direct assignment will assign a 1 (on) to the Softwire Panel

64

If and the Boolean Expressions

Unit 3: Conditionals, Loops, and Waits

button for which the expression is true, and a zero (off) to the false ones. Recall that assigning a 1 to a device-channel is the same as turning that devicechannels output on.
The entire source code for this program using the variable assignment
method is included on the distribution disk as STEP3.AXS.

More Boolean operators

Boolean operator
A keyword or symbol that
creates a relation between
two items.

The previously discussed If and If...Else statements could only base the program
flow on one condition. You can, however, combine two of these conditions with
a Boolean operator. This operator sets the rules of what the end result will be.
The Boolean operators used in the AXCESS system are And, Or, Xor, and Not.
These are placed in between the two conditions after the If statement. For example:

IF ((X = 1) AND (Y = 5))


{
(Statement 1)
}

If the end result of the Boolean expression is true, AXCESS continues with
Statement 1. If the end result is false, AXCESS simply ignores Statement 1.

Reading a Boolean expression table


In most Boolean expressions, the possible conditions of two statements are analyzed to achieve one result. These results can be visualized using Boolean expression tables, as explained in Figure 3-3. A text formula can also be followed
to find that result:
If <statement 1> is <its condition (true or false)> <Boolean operator> <statement 2> is <its condition>, then the result of the expression is <result of statement conditions>.

Figure 3-2

Boolean operator abbreviations

The Boolean operators in


AXCESS have shorthand
symbols which can be used
in place of the words. (The
bitwise operators are
explained in the AXCESS
Programming Guide.)

Abbrev

Function

Abbrev

Function

&&

Logical And

&

Bitwise And

||

Logical Or

Bitwise Or

^^

Logical Xor

Bitwise Xor

Logical Not

Bitwise Not

Unit 3: Conditionals, Loops, and Waits

If and the Boolean Expressions

65

Figure 3-3
A pictorial explanation of the
Boolean expression table for
the operator And.

Figure 3-4
An example of how a
Boolean expression table is
used to compare multiple
conditions.

And

Boolean operator

Statement 2
possible conditions

T
T T

F
F

F F

Results of statement conditions


based upon rules set by the
Boolean operator

And

Boolean operator

Statement 2:
(NUM2 = 4) is false

Statement 1 possible conditions

T T
T T T

Statement 1: (NUM1 = 5) is true

F F

Result of statement conditions: false

The result is found by basing the conditions of the statements against the
rules set by the Boolean operator. Here are those specific rules:
And

Both statements must be true for the result to be true.

Or

At least one of the conditions must be true for the result to be true.

Xor

Only one statement can be true for the result to be true.

Not

If the statement is true, the result is false. On the contrary, if the


condition is false, the result is true. This expression uses only one
statement.

Assume that it has been previously defined that NUM1 = 5 and NUM2 = 3. Insert the variables from the example into the text formula:
If NUM1 = 5 is true and NUM2 = 4 is false, then the result of the expression is false.
The statement would have been true if NUM2 had been equal to 3, because in
an And expression both statements must be true (see Figure 3-4).
The Boolean expression tables in Figure 3-5 are a quick reference guide for the
result of a Boolean expression. They are not necessary, but they can be very helpful.

And

Figure 3-5
Tables of results of various
Boolean operators.

66

Or

Xor

Not

T
T T

F
F

T F
T T T

T F
T F T

T F
T F T

F F

F T

F T

F T

If and the Boolean Expressions

Unit 3: Conditionals, Loops, and Waits

10

Waits and Timer Keywords

Controlling time within AXCESS


Within the AXCESS system, there are a variety of timing keywords available for
your use. Functions can be delayed for a few seconds, or they can be delayed
until certain conditions are right. The built-in stopwatch allows you to measure
time intervals between operations in your program. You can even program
AXCESS to start rolling the film precisely on Saturday at 3:15 PM. This chapter
will help you learn each of these keywords and show you how to apply them to
your programs.
You will build on your previous program (STEP3.AXS), but this time you will
not be changing the layout of your Softwire Panel; youll just add more functions to the existing buttons.

The Wait list

Wait list
A list containing unexpired
Wait statements. After each
pass through mainline, the
Master Card scan this list to
see if any have come due.

The most common keyword relating to time is the Wait keyword, which is used
to activate functions after a specified delay time has elapsed. The program flow
does not stop when a Wait is encountered. Instead, AXCESS places the Wait statement into a list in memory and continues on with the rest of the program. After
each pass through mainline, the Master Card scans this Wait list, and if any
Waits have come due, AXCESS executes the statement or compound statement
immediately following the expired Wait keyword. Up to 50 Waits are allowed in
the list at a time. (Refer to the AXCESS Programming Guide for a complete discussion of mainline and the AXCESS bus.)
Time in the Wait list is measured in tenths of a second. A Wait of 10 is one second, a Wait of 15 is one and a half seconds, a Wait of 20 is two seconds, and so on.
Suppose in your system you have two relays controlling system power. One
is for the audio amplifier, and the other is for the rest of the equipment (well
call that rack power). In many cases, a time delay is desired between powering up the source equipment and powering up the audio amplifier. The reason is
that if both are powered up at the same time, there is sometimes a loud pop
over the audio system from the source equipment; but if there is a delay, the
source equipment is already on and there will be no pop when the amp is
turned on. In most cases a one half-second delay is enough.

Unit 3: Conditionals, Loops, and Waits

Waits and Timer Keywords

67

In your program, you will first add a constant definition for your new relay
and change the name of the existing system power relay to RACK_POWER. If you
use relay 7 (the next available relay on the card), the line to add to the Define_
Constant section looks like this:

AMP_POWER = 7

This code fragment is from


STEP4.AXS on the AXCESS
distribution diskette.

You will also change the constant identifier SYS_POWER to RACK_POWER. As


for the System Power button, you want the rack power to come on first (relay 3)
when the power is turned on; one half-second later, the amp power should turn
on. When you turn the power off, you want the reverse to happen. Heres the
new code for the System Power button:

PUSH[SWP,8]
{
IF ([RELAY,RACK_POWER])
{
OFF [RELAY,AMP_POWER]
WAIT 5 OFF [RELAY,RACK_POWER]
}
ELSE
{
ON [RELAY,RACK_POWER]
WAIT 5 ON [RELAY,AMP_POWER]
}
}

This code fragment is from


STEP4.AXS on the AXCESS
distribution diskette.

First, look at the organization of this set of statements. Here is a simplified


outline of the structure of this code:

PUSH[SWP,8]
{
IF (device-channel)
compound statement
ELSE
compound statement
}

From this simpler outline you can more easily examine what is happening
here. Following the Push statement is a single If...Else statement which has only
a device-channel reference for its condition. In this case AXCESS checks that

68

Waits and Timer Keywords

Unit 3: Conditionals, Loops, and Waits

channels status. If it is on, AXCESS evaluates the condition as true and executes
the first compound statement. Otherwise AXCESS executes the compound statement following the Else.
The first compound statement, which is executed if the rack power is on, uses
a Wait to accomplish a time-delayed powering-down of the system. The first
statement inside the compound statement turns off the amplifier relay. The next
statement is a Wait statement for five-tenths of a second (same as one half-second), followed by an Off statement to the rack power relay. AXCESS places this
Wait into the Wait list and continues with the program. Since these statements
are part of an If compound statement, AXCESS does not execute the Elses compound statement.
As AXCESS continues to run, the Wait is still in the Wait list. After one halfsecond has elapsed, AXCESS will execute the statement immediately following
the Wait, which in this case turns off the rack power. The corresponding Wait is
then taken out of the list.
The compound statement following the Else is nearly the same as the one just
described; its functions are just slightly different. AXCESS first turns on the rack
power, waits a half-second, and then turns on the amp power.

Multiple Waits
Now that you know how to delay an action for a specific amount of time, you
can add a little pizzazz to your system. Suppose you want a series of several
events to happen when you press just one button. At this point, the System
Power button completes just two events with a delay in between.
Now you will make the System Power button accomplishes several more
things when the power is being turned on and off. Suppose that when the power
is being turned on, you want a series of timed events to take place. First, the rack
power comes on as before. At the same time, the screen starts to come down and
the drapes start to close. One half-second later, the amp power comes on, just
like before. Twenty seconds after the button is pressed, the Medium lighting
scene is selected.
When the power is turned off, a different sequence happens. First the amp
power is turned off, lights go to the Full setting, the screen is raised, and the
drapes are opened. One half-second later the rack power turns off. Two minutes
later the lights go to the Off setting.
Here is the code for the System Power Push for the described scenario:

PUSH[SWP,8]
{
IF ([RELAY,RACK_POWER]) (* Power being turned off *)
{

Unit 3: Conditionals, Loops, and Waits

Waits and Timer Keywords

69

OFF [RELAY,AMP_POWER]
TO [LIGHTS,LIGHT_FULL]
TO [RELAY,SCREEN_UP]
TO [RELAY,DRAPE_OPEN]
WAIT 5 OFF [RELAY,RACK_POWER]
WAIT 12 PULSE [LIGHTS,LIGHT_OFF]

This code fragment is from


STEP4.AXS on the AXCESS
distribution diskette.

}
ELSE
(* Power being turned on *)
{
ON [RELAY,RACK_POWER]
TO [RELAY,SCREEN_DOWN]
TO [RELAY,DRAPE_CLOSE]
WAIT 5 ON [RELAY,AMP_POWER]
WAIT 2 PULSE [LIGHTS,LIGHT_MED]
}
}

Notice the use of the Pulse keyword. This is done, as you may recall, because
To cannot be used inside a Wait. Since the lighting buttons are momentary, you
use a Pulse to actuate the relay for just a moment.
Waits can appear inside other Waits. This is called nesting Waits. You dont
need to nest Waits in your program here, but here is how it is done:

WAIT 2
{
ON [RELAY,SCREEN_UP]
WAIT 2 OFF [RELAY,SCREEN_UP]
}

In this example, AXCESS would wait twenty seconds, turn on the Screen Up
relay, wait twenty more seconds, then turn off the Screen Up relay. Any timed
sequence of events can be accomplished with or without nested Waits. Using
nested Waits is in many cases more readable than non-nested Waits. Non-nested
Waits, however, use less code. Here is the same example without nesting:

WAIT 2 ON [RELAY,SCREEN_UP]
WAIT 4 OFF [RELAY,SCREEN_UP]

Special uses of Wait


A Wait time of zero is a special case: the code following the Wait will be executed directly after the current pass through mainline. This is because the Wait
goes into the Wait list, and at the end of mainline when the Master Card checks

70

Waits and Timer Keywords

Unit 3: Conditionals, Loops, and Waits

the list for expired Waits, the Wait will be due to execute. Using Wait is
only done in special cases.
Any one Wait can only be placed in the Wait list once. If a particular Wait is
already in the Wait list, it cannot be placed into the list a second time until the
first instance is either cancelled or expired. For instance, suppose the following
line appears in mainline where it will be executed every pass through mainline:

WAIT 5 FLASH = NOT FLASH

The first time this is executed, the Wait is placed into the Wait list. But what if
this line is executed again before the Wait expires? Since the Wait is already in
the Wait list, the line is simply ignored. One half-second after the first execution
of this statement, the value in variable FLASH is inverted; if it was zero it will be
changed to 1, and if it was non-zero it will be changed to zero. On the next pass
through mainline, the Wait will again be placed into the Wait list and the cycle
will repeat for the duration of the program. This in effect creates a variable
whose state inverts every half-second.

Naming Waits
When a Wait is given a unique name, it can be either cancelled, paused, or
restarted. To name a Wait, simply place a name in single quotes after the Wait
statement. For example:

WAIT 3 DELAY

Once DELAY is entered into the list, it cannot be re-entered until the first has
been removed.
There are certain considerations in naming Waits:
They should not be previously defined constants or variables.
They cannot be names that have already been assigned to buffers or
subroutines. (Buffers and subroutines are explained later in the manual.)
They can contain spaces, unlike other AXCESS identifiers.

Cancelling, pausing, and restarting Waits


Once a Wait is named, it can be manipulated within the program with several keywords. Pause_Wait places a Wait on hold. The Wait does not continue counting

Unit 3: Conditionals, Loops, and Waits

Waits and Timer Keywords

71

down until it is resumed with Restart_Wait. The Wait then continues from where
it was paused. Cancel_Wait completely nullifies a Wait, removing it from the
Wait list. Cancel_All_Wait nullifies every Wait currently in the list. The keywords Pause_All_Wait and Restart_All_Wait act the same as Pause_Wait and
Restart_ Wait, except they affect all Waits in the Wait list, named and un-named.
You could use a named Wait in your System Power Push routine. Suppose
the user just turned off the power. The program now has a two-minute Wait in
the Wait list for the lights to go off. If the user turns the power back on before this
Wait executes, the power-on sequence will start, but the events of the LIGHT_OFF
Wait will still happen! The user could end up in a very dark room which is definitely not what he or she wanted. In this case it would be advantageous to name
that Wait and cancel it in the power-on section of the Push. To do this, simply
add the Wait name to the Wait in the power-off section like this:

WAIT 12 LIGHTS OFF PULSE [LIGHTS,LIGHT_OFF]

These code fragments are


from STEP4.AXS on the
AXCESS distribution diskette.

To cancel the Wait in the power-on section, simply add this line:

CANCEL_WAIT LIGHTS OFF

The Wait_Until keyword

Wait_Until list
A list containing unexpired
Wait_Until statements. After
each pass through mainline,
the Master Card scan this list
to see if any have come due.

The Wait_Until keyword is not a true timing keyword; AXCESS does not wait
for a certain amount of time to elapse. Instead, AXCESS checks to see if a condition is true. When the condition becomes true, AXCESS executes the statements
listed directly below the Wait_Until statement.
All Wait_Untils go into another list very similar to the Wait list, called the
Wait_ Until list. Just as it does with Waits, each pass through mainline AXCESS
checks to see if any Wait_Until conditions have become true. For each one that
has, AXCESS immediately executes the sequence below the Wait_Until statement. If not, AXCESS keeps the Wait_Until in the Wait_Until list until its condition becomes true.

Misusing Wait_Until
Since AXCESS only checks the status of pending Wait_Untils after completely
running mainline, make sure that the condition has a chance to become true, or
you will defeat the purpose of the Wait_Until statement. You dont need Wait_
Until in your program yet, but this program segment illustrates the misuse of
Wait_Until:

72

Waits and Timer Keywords

Unit 3: Conditionals, Loops, and Waits

WAIT_UNTIL (Y=4)
{
(* statements *)
}
Y=4
Y=3

As you can see, Y will never equal four at the end of the program. The
Wait_Until in this case is completely useless.
It would be hard to make this mistake in a small program such as the one you
are working on, but this problem could make its way into a fairly large program.
AXCESS cannot detect this sort of error, so make sure each Wait_Until statement
can become true one way or another.

Naming and removing Wait_Untils


In the same manner as a Wait, a Wait_Until can be named. To do this, a name in
single quotes is placed at the end of the statement. Once a Wait_Until has a
name, it can be cancelled with the Cancel_Wait_Until keyword, which removes
it from the Wait_Until list. The Cancel_All_Wait_Until keyword removes all
Wait_Untils from the Wait_Until list.

The timer keywords


There are several more timing features: the timer keywords. Set_Timer and
Get_Timer allow you to have both a stopwatch and the ability to measure
time intervals within the AXCESS system.

Set_Timer
The timer provided to you is a simple one. It cannot be stopped or pausedonly
set. Like a Wait, time is measured in increments of tenths of seconds. There is
only one such timer available.
To set the timer, the Set_Timer keyword is used. You must specify a number
between 0 and 65,535, and the timer will start counting up from that point. After
the timer reaches 65,535 it wraps around to 0 and starts over.

Get_Timer
The Get_Timer system variable contains the current status of the timer. Usually
this keyword is used in conjunction with an If statement. For example, look at
the following code segment:

Unit 3: Conditionals, Loops, and Waits

Waits and Timer Keywords

73

IF (GET_TIMER >= 1)
{
(* do something *)
}

Notice that a greater than sign was combined with the equal sign. There
is a chance that the timer will reach the number 100 while the program is being
executed elsewhere. When AXCESS reaches the Get_Timer section, the timer
might be 103. If the condition was that Get_Timer be equal to 100, the following
statements would have been skipped. Never use only an equal sign with the
Get_Timer system variable in an If statement.
Unlike variables, the timer loses its value when the AXCESS system is turned
off. When the system is reactivated, the timer is reset to zero.

Using Time, Date, and Day


The system variables Time, Date, and Day can also be used to create timing
functions. Time contains the current time in the form of the string HH:MM:SS, in
which HH equals hours, MM equals minutes, and SS equals seconds. The
time is given in a 24-hour format (military time). Date contains the current date
in the form of the string MM/DD/YY, in which MM equals month, DD equals
day, and YY equals year. Finally, Day contains the current day of the year in
the form of one of the strings MON, TUE, WED, THU, FRI, SAT, or SUN.
These variables have two restrictions:
They cannot be changed within the AXCESS program. Instead, this is done
with the terminal emulator which was explained in Unit 1.
Individual storage locations cannot be referenced. (This reference to arrays
and string operations is explained in Unit 5.)
The string operations Left_String, Mid_String, and Right_String can be
used to access parts of these variables.
Most of the time, these variables are used with an If statement. Once the condition is true, certain statements are executed. For instance, suppose you wanted
to turn off all of the lights at 11:00 PM every night.
The code would look like this:

IF (TIME = 23::)
PULSE [LIGHTS,LIGHT_OFF]

74

Waits and Timer Keywords

Unit 3: Conditionals, Loops, and Waits

The statements following the If statement will be executed every day at 11:00
PM. Suppose you wanted to change it so that every hour the lights would turn
off. The statement would simply be changed to read:

IF (TIME = ??::)
PULSE[LIGHTS,LIGHT_OFF]

The question mark (?) acts like a wildcard character, allowing any character
to be in its place. Since question marks are in place of the hour, the comparison
will be true once an hour when the minutes and seconds are zero, and the lights
will turn off.
Your entire program up to this point is contained in the file STEP4.AXS on your
distribution disk.

Unit 3: Conditionals, Loops, and Waits

Waits and Timer Keywords

75

11

The While Keywords

While
Sometimes it may be necessary to loop through a certain section of a program
until a condition becomes true. This is the purpose of the While family of keywords. When AXCESS comes to a While, it checks to see if the condition following
it is true. If the condition is false, AXCESS skips the statement immediately following the Whilejust like the If keyword. However, if the condition is true,
AXCESS executes the statement and then rechecks the Whiles conditional expression. If the condition is still true, the statement is executed again.
This sequence continues until the condition is evaluated as false. When the
condition comes up false, program execution continues with the statement following the Whiles block of code. Here is an example:

X = 1
WHILE (X < 5)
{
ON [RELAY,X]
X = X + 1
}

In this code example, the variable X is first set to 1. Next, the While statement
checks to see if X is less than 5. Since it is, AXCESS executes the compound statement directly following the While: the device-channel referenced by [RELAY,1]
(since X equals 1) is turned on, and X is incremented by one. Then program execution goes back to the While statement. This loop continues until X becomes 5,
in which case the compound statement following the While is not executed, and
AXCESS goes on to the rest of the program. This block of code essentially turns
on the first four channels of device RELAY.
There is a limitation on using the While keyword. The amount of time AXCESS
spends executing any single While cannot exceed 0.5 seconds. This is because the
Master Card updates AXlink (the communications bus between all AXCESS devices) between each pass through mainline. If AXlink is not updated at certain
time intervals, problems could develop during bus communications. Therefore,
to prevent an AXCESS program from stalling mainline too long, there is a 0.5 sec-

Unit 3: Conditionals, Loops, and Waits

The While Keywords

77

ond time-out on While loops; that is, AXCESS will forcibly exit the While after one
half-second, regardless of the operation it is executing. (Remember, Waits are
checked after mainline and thus are not subject to such restrictions.)

Long_While
There are cases where a While loop cannot help but to take longer than one halfsecond to execute. If this becomes the case, simply change the While keyword in
question to a Long_While.
The main difference between a While and a Long_While is that after each loop
through the Long_Whiles statement, the AXlink bus is updated. This, in effect,
makes the statement or compound statement following a Long_While to be a
mini-mainline for as long as the condition of the Long_While is true. Therefore, Long_While has absolutely no timeout period. But be careful! If you dont
provide a way out of your Long_While (by allowing the condition to become
false), the program will become stuck inside the Long_While and no other code
outside of the loop will be executed.

Medium_While
During the execution of a Long_While, AXCESS scans AXlink just like it does
when running mainline. It is during this scanning that AXCESS receives information about input changes from devices such as Softwire Panels and Touch Panels. This activity also takes place after each loop through a Long_While. Therefore, if
a user presses a button while AXCESS is looping through a Long_While, the input
change is lost to any programming outside the Long_While loop.
If this becomes a problem, the Medium_While keyword may be used. This
keyword operates just like a Long_While, but it ignores input changes from
AXCESS devices. These input changes are not lost, but will remain pending until
the Master Card scans for them againeither before the next pass through
mainline, or after a pass through a Long_While. (Refer to the AXCESS Programming Guide for a complete discussion of mainline and the AXCESS bus.)
Once again, be very careful when using Long_While and Medium_While. If
the condition associated with one of these in your program can never become
false, your program could get stuck in an infinite loop, requiring a reset of the
Master Card or maybe even a re-loading of the systems programming.

78

The While Keywords

Unit 3: Conditionals, Loops, and Waits

AXCESS Language Tutorial

UNIT 4

LEVELS

12

Creating Levels

Introduction
So far, you have used channels in devices to interact both with the user and with
what he or she wants to control. Channels, however, are not the only method of
controlling some devices, such as volume control cards, voltage generator cards,
and pan/tilt control cards. Devices such as these use levels to interface with
the outside world. Also, several AXCESS panels have bar graph displays capable
of displaying a level. This unit will show you how to create, read, and modify
these levels, plus show you how to use bar graphs and sliders on some of the
AXCESS devices.

What is a level?
Digital
An input or output can have
only two values: on and off.
Analog
An input or output can have
many values.

Level

An input/output (I/O) channel in AXCESS is usually digital in nature; that is, it


can only have an on or an off state. Several AXCESS devices, such as the volume control card and the pan/tilt control card, have analog input and/or output capabilities. An analog input or output may have many different states.
Devices using analog I/O internally store the values relating to the state of each
of these analog inputs and outputs; these values are called levels. On a volume
card, levels relate to the volume levels of the card. Levels can be used to tell a
pan/tilt control card where to position a camera, or tell a voltage generator card
the amount of voltage to generate.

A value that is related to an


analog input or output on an
AXCESS device.
Level values
135
80

Figure 4-1
The imaginary knob. The
knob is the level, which can
have a range of values.

LEVEL 1
0

Unit 4: Levels

LEVEL 2
255

255

Creating Levels

81

Imagine that a volume control card has two volume knobs: one for the left
speaker and one for the right. See Figure 4-1. Each knob has a range of values
from 0 to 255. These knobs represent the two levels present in the volume control card. When a level is discussed in the text, it is usually referring to the
value of one of these imaginary knobs.

Creating levels
In the AXCESS language, a level can have a value between 0 and 255. Level values can be stored in a variable for later use. In order to read a level from an
AXCESS device that supports levels, you use the keyword Create_Level. Here is
the syntax:

CREATE_LEVEL device, level number, variable

Create_Level takes three parameters:


the device from which to read the level
which level of the device to read (some devices have many different levels)
the variable in which to store the level

This keyword creates an association between the specified level of the device
and the specified variable. During execution of your program, AXCESS will continually update the variable to contain the value of the level with which it is associated.
(Refer to the AXCESS Programming Guide for a complete discussion of mainline
Figure 4-2
The Touch Panel layout for
this unit.

VOLUME CONTROL

UP
DOWN
MUTE
PRESET

82

Creating Levels

Unit 4: Levels

and the AXlink bus.) Since this association only needs to be done once, this keyword is only allowed to appear in the Define_Start section of your program.
In this unit, you will develop a new program that handles levels. This system
will contain a volume control card to control a volume level, and a Touch Panel
for the user to control the volume card. On the Touch Panel, there will be four
buttons: Volume Up, Volume Down, Volume Mute, and Volume Preset. There
will also be a bar graph on the Touch Panel to display and control the volume
level. See Figure 4-2. Here are some code excerpts to get started:

This code fragment is from


STEP5.AXS on the AXCESS
distribution diskette.

DEFINE_DEVICE
VOLUME = 1
PANEL = 128
DEFINE_CONSTANT
(* Three channels to control both outputs together *)
V_UP = 1
V_DN = 2
V_MT = 3
DEFINE_VARIABLE
VOL_LEVEL

(* This will store the volume level


value of the card *)

DEFINE_LATCHING
[VOLUME,V_MT]
DEFINE_START
CREATE_LEVEL VOLUME,1,VOL_LEVEL

This code defines the devices you will use, a variable in which to store the
volume level value, and the statement in the startup code to create the association between level number 1 of the volume card and the VOL_LEVEL variable. It
also defines some constants which give names to the different channels available
in the volume control card. By turning on and off these channels the user can
raise, lower, and mute the volume levels of the card. Notice that the V_MT channel is latching; this is the channel that mutes the volume. By making it latching,
subsequent presses toggle the muting on and off. Here is the code for the Volume Up, Volume Down, and Volume Mute buttons on the Touch Panel:

This code fragment is from


STEP5.AXS on the AXCESS
distribution diskette.

Unit 4: Levels

DEFINE_PROGRAM
PUSH[PANEL,1]
{
OFF [VOLUME,V_MT]
TO [VOLUME,V_UP]
}

Creating Levels

83

PUSH[PANEL,2]
{
OFF [VOLUME,V_MT]
TO [VOLUME,V_DN]
}
PUSH[PANEL,3]
TO [VOLUME, V_MT]
[PANEL,1] = [VOLUME,V_UP]
[PANEL,2] = [VOLUME,V_DN]
[PANEL,3] = [VOLUME,V_MT]

Ramp
To change a level from one
value to another smoothly
over a period of time.

84

Creating Levels

Notice that the Volume Up and Volume Down buttons will automatically
unmute the volume before starting to ramp the volume up or down. Also, these
control channels affect both levels of the volume card simultaneously, ramping
both up and down together.
This code handles all of the functions of your system except for the bar graph
and the Volume Preset button. You will add the code for these in the next chapter.

Unit 4: Levels

13

Using Levels

Reading levels
NOTE
The volume card remembers
the last level when it is muted
so that it can unmute to that
same level.

When a level is associated with a variable using Create_Level, AXCESS continually keeps the variable updated with the value of that level. In your program, as
the user ramps the volume level up, the value in VOL_LEVEL increases. When the
volume is ramped up to the maximum, VOL_LEVEL will contain 255. The same
goes for ramping down; when the volume is muted, the variable will contain zero.

Making a preset
Preset
A level saved for later
retrieval. When a preset is
recalled, the level returns to
the preset value.

This code fragment is from


STEP5.AXS on the AXCESS
distribution diskette.

For information on a
particular devices
Send_Command functions,
see the AXCESS Programming Guide and the
products literature.

Now you are going to add the code necessary to create a preset. A preset is a
level stored for later retrieval. What you will do here is give the Volume Preset
button a dual role. If the button is pressed and held for two seconds, the current
level of the volume card is stored in the variable PRESET. If the button is pressed
for less than two seconds, it sends a command to the volume card to set the level
of the card to the previously saved level in PRESET. First, here is the code:

PUSH[PANEL,5]
{
SET_TIMER()
}
RELEASE[PANEL,5]
{
IF (GET_TIMER>2)
{
PRESET = VOL_LEVEL
}
ELSE
{
SEND_COMMAND VOLUME, "'PL', ITOA(PRESET)"
OFF [VOLUME,V_MT]
}
}
[PANEL,5] = (PRESET = VOL_LEVEL)

This code uses the timing keywords Set_Timer and Get_Timer to test the
amount of time between the Push and the Release of the Preset button. If the time
is greater than two secondsremember, Get_Timer returns time in increments

Unit 4: Levels

Using Levels

85

of one-tenth of a secondthen the current level of the card (stored in VOL_LEVEL)


is saved into the variable PRESET. If the button press is less than two seconds a
command is sent to the volume card to go to the level saved in PRESET, and the
volume is unmuted. Note that the feedback for the Volume Preset button is lit
whenever the current volume level equals the value of the PRESET variable.

Using bar graphs


Now you will add the code to continuously display the current level of the volume card on the Touch Panels bar graph. To update a bar graph on a device,
you use the Send_Level keyword. Here is the syntax:

SEND_LEVEL device, level number, value

This keyword is used to update a level in a device. Assume your bar graph display on the Touch Panel has level number 1. In order to keep the display updated continually, you will add the following line into your program (on mainline):

This code fragment is from


STEP5.AXS on the AXCESS
distribution diskette.

SEND_LEVEL PANEL, 1, VOL_LEVEL

Since this code resides in mainline it will be executed continually, thus making sure that the bar graph reflects the value of level number 1 of the volume
card. As the volume ramps up, VOL_LEVEL increases and the bar graph fills. As
the volume ramps down, VOL_LEVEL decreases and the level indicated on the
bar graph also decreases. Since both volume levels are ramping together, you
only have to track one of them for the bar graph.

Connecting levels
Touch Panel bar graphs have a unique feature: you can touch and slide the bar
graph itself and the level will raise or lower to that point; the level simply tracks
the movement of your finger. However, to do this you must set up a connection
between the bar graph and the volume level. That is what the keyword Define_
Connect_Level accomplishes.
Define_Connect_Level is not a keyword that is used inside mainline, but is
actually a definition section like Define_Device or Define_Start. When you use
it, the best location to place it is immediately following the Define_Variable section. Underneath the Define_Connect_Level header is where all level connections are listed. Here is how Define_Connect_Level is used:

86

Using Levels

Unit 4: Levels

DEFINE_CONNECT_LEVEL
(device 1,level number 1,device 2,level number 2,...etc.)

The section inside the parentheses represents a single connection. All levels
listed in the connection will follow each other. If any one level changes, all others will change to match. Any number of levels may be supported per connection, and there is no limit to the number of connections.
Here is how you would use Define_Connect_Level in your program to connect the Touch Panel's bar graph to the volume card's levels:

This code fragment is from


STEP6.AXS on the AXCESS
distribution diskette.

DEFINE_CONNECT_LEVEL
(PANEL, 1, VOLUME, 1, VOLUME, 2)

This connects level number 1 on the Touch Panel (your bar graph) and levels
1 and 2 on the volume card together. The reason that two levels on the volume
card are included is because volume control cards have two levels: the left audio
channel and the right audio channel. These connections are a two-way street:
anytime the bar graph is changed, both volume levels will follow, and anytime a
volume level is changed (probably by the volume control buttons on the Touch
Panel), the bar graph will automatically follow. When using Define_Connect_
Level, it is not necessary to use the Send_Level keyword in your program since
the connection constantly takes care of updating the bar graph.
The example programs for this unit can be found on the AXCESS distribution
diskette. The file STEP5.AXS uses the Create_Level and Send_Level keywords,
and STEP6.AXS uses the Define_Connect_Level keyword.

Unit 4: Levels

Using Levels

87

AXCESS Language Tutorial

UNIT 5

ARRAYS,
STRINGS,
AND BUFFERS

14

Arrays and Strings

Introduction
In the previous unit you developed a program that demonstrates the most common features of the AXCESS language. In this unit, more advanced concepts will be
introduced: arrays, strings, buffers, and two-dimensional arrays. Understanding
these concepts and the keywords that go with them will allow you to easily handle
data, and will provide another means of communicating with the outside world.
In this first chapter, you will develop a small example program. For this program, you will need to create a level and assign it to a variable. You will use the
variable VOLUME_LEVEL for this. Your control panel will have nine buttons: Volume Up (button 1), Volume Down (button 2), Store (button 3), Preset 1, Preset 2,
Preset 3, Preset 4, Preset 5, and Preset 6 (buttons 9 through 14). The Volume Up
and Volume Down buttons ramp a volume card up and down. The Store button
simply toggles a state on and off. The Preset 16 buttons either store or recall a
preset, depending on whether the Store button is on or not.

Defining arrays

Array
A single variable that has
more than one storage
location.

The example program for


this chapter can be found on
your distribution diskette as
STEP7.AXS.

In the program developed in Unit 2, you used a variable called DECK. This variable could only hold one value at a time. However, if you need a variable to
hold several values at once, use an array. An array is a single variable that has
more than one storage location.
Arrays must be defined as variables within the Define_Variable section of
your program. Its definition has two parts: a unique identifier and its storage
capacity. First, the variable must be named by a valid identifier (see Chapter 4
for the rules concerning identifiers). Second, the number of storage locations in
the array must be indicated; a maximum of 255 locations can be specified.
For your new program, you want to store several preset levels for the volume
control card. You could create several individual variables and use If statements
or Select...Active statements to select the preset you want to use. Or even better,
you could create an array and use the index value (explained later) to pick the
preset you want to use. Here is your array declaration:

Unit 5: Arrays, Strings, and Buffers

Arrays and Strings

91

PRESETS

Figure 5-1
The array PRESETS has six
empty storage locations.

DEFINE_VARIABLE
PRESETS[6]

This declares a new variable, PRESETS, which is shown in Figure 5-1. The variable PRESETS is an array which can hold six distinct values, as defined by the
number 6 inside the brackets.

Accessing and storing array values


To access a particular value in an array, simply refer to the storage location inside the array you wish to retrieve, such as follows:

THE_LEVEL=PRESETS[3]

Index value
The number that tells AXCESS
which location in an array to
retrieve. This value must be
an integer from 1 to 255.

The number inside the brackets is called the index value. The index value is the
number that tells AXCESS which location in the array to retrieve, and it must be a
number from 1 to 255. This example assigns the value in the third location of
PRESETS to the variable THE_LEVEL. Retrieving a value from an array does not in
any way change the array. See Figure 5-2.

PRESETS

Figure 5-2
The value in PRESETS[3] is
assigned to the variable
THE_LEVEL.

A
PRESETS[3]

92

Arrays and Strings

THE_LEVEL

Unit 5: Arrays, Strings, and Buffers

PRESETS

Figure 5-3
The storage location
PRESETS[2] is assigned a
value of 6.

You can place values into a storage location by setting the particular location
equal to the needed value. For example, PRESETS was previously defined as having six locations. If you want the second location to hold a value of 6 you would
type the following:

PRESETS[2]=6

The number 6 is placed into the second location, as shown in Figure 5-3. From
now on, anytime PRESETS[2] is referenced, its value is 6.
In the example program, pressing a Preset button either stores or recalls a preset. Examine the section of code that accomplishes this:

PUSH[SWP,3]
STORE = NOT STORE
[SWP,3] = STORE

This code fragment is from


STEP7.AXS on the AXCESS
distribution diskette.

IF ((PUSH_CHANNEL >= 9) AND (PUSH_CHANNEL <= 14))


{
IF (STORE)
PRESETS [PUSH_CHANNEL 8] = VOLUME_LEVEL
ELSE
SEND_COMMAND VOLUME_CARD,PL,
ITOA (PRESETS[PUSH_CHANNEL 8])
}

NOTE
The keyword
Send_Command sends a
string to an AXCESS device,
which then interprets the
string as a command for an
action. See the AXCESS
Programming Guide for a list
of device-specific commands.

The first PUSH[SWP,3] is the Store button, which simply toggles the STORE
variable using the Not operator. (Remember, Not inverts the state of whatever
follows it.) The Push statement is immediately followed by a feedback statement
for the Store button. The next statement is an If statement which checks to see if
Push_Channel is greater than or equal to nine, and less than or equal to 14. In
other words, the statements inside the Ifs block are executed if one of the Preset
buttons are pressed. Inside the block is another If statement which uses the state
of the variable STORE to determine whether to assign the volume cards level to a

Unit 5: Arrays, Strings, and Buffers

Arrays and Strings

93

location in the PRESETS array, or to send a command to the volume card telling it
to go to a previously stored level. In order to place the variable VOLUME_LEVEL
into the array PRESETS at the correct location, 8 must be subtracted from
Push_Channel to find the index value.

Strings

String
A set of values grouped
together with single and/or
double quotes.
String literal
A set of characters (values
ranging from 32 to 127)
enclosed in single quotes.

Many times you may need to reference entire groups of values at once. You can
do this by using strings and string expressions. A string is a set of values
grouped together with single and/or double quotes. Strings enclosed in single
quotes are called string literals.
Single quotes can only enclose values ranging from decimal 32 (the space character) to decimal 126 (the tilde character ~). These string literals are constant
values that are set at compile time. Once loaded into the master card these strings
cannot be changed, except when a new program is loaded into the Master Card.
Here is an example of assigning a string to an array:

PRESETS='FOUR'

When AXCESS processes this assignment, it places the F (ASCII value 70) in
location 1 of PRESETS, O (ASCII value 79) in location 2, and so on. See Figure 5-4.
String FOUR is placed in the array PRESETS. Note that an index value is not
given when strings are assigned to arrays. The first letter is automatically placed
into the first storage location, the second letter is placed into the second storage
location, and so on.
String expression

The string expression

Enclosed by double quotes,


this expression combines
several types of data into a
single string.

Single and double quotes are interpreted in two different ways by the AXCESS
system. Whereas single quotes enclose string literals, double quotes represent a
different operation: they enclose string expressions. A string expression combines
several types of data into a single string. A string expression can contain any

PRESETS

Figure 5-4
The string FOUR is assigned
to the array PRESETS.

94

Arrays and Strings

Unit 5: Arrays, Strings, and Buffers

PRESETS

10

PLAY

Figure 5-5
A string expression is
assigned to the array
PRESETS.

ASCII value (0 to 255), as well as variables, string literals, and arrays. The differ-

Run time
When the program is
executed in the Master Card.

ence between a string literal and the string expression is that the string expression is built at run time instead of compile time. As AXCESS processes a string
expression, it evaluates each member of the expression from left to right, and the
result is a complete string. Here is an example:

Compile time

PRESETS="PLAY,5,,'NO',X"

When the program is


compiled.

NOTE
A string expression cannot
contain another string
expression; i.e. a set of
double quotes cannot
enclose another set of
double quotes.

Assuming that PLAY is a constant with the value of 1, and X is a variable with
the value of 10, the string expression is evaluated as a string with the following
values: 1,5,0,N,O,10. See Figure 5-5. Since the expression is evaluated at run
time, whatever value is in the variable X when the expression is evaluated is
what is placed into the result.

Arrays as strings
There are two ways of referencing data in arrays within AXCESS programs: each
location as an individual value, or each array as a group of values. So far you have
seen how to access the individual locations. However, an entire array can be accessed as one unit. If you refer to an array without specifying an index value, the
contents of the entire array is referenced as a string. Consider the following lines:

DEFINE_VARIABLE
S1[1]
DEFINE_PROGRAM
S1='TEST ONE'
SEND_STRING CARD,'TEST TWO'
SEND_STRING CARD,S1

This small section of code will send two strings to the card named CARD: first
TEST TWO, then TEST ONE. Notice that there are no quotes around the variable

Unit 5: Arrays, Strings, and Buffers

Arrays and Strings

95

S1 in the second Send_String. This is because the variable S1 is an array, and

when an array is referenced as a single unit like this, it is considered a string. If


you had assigned a string expression to S1 and then sent it to the card, the entire
contents of the string expression would be sent.
Suppose that during power-up of the AXCESS system you want to set all of the
presets to default values. You could do this by assigning values to each individual location in the PRESETS array. A better solution, however, is to use a
string expression to set all six at once, like this:

This code fragment is from


STEP7.AXS on the AXCESS
distribution diskette.

DEFINE_START
PRESETS = ,3,9,128,191,255

(* set all preset


values at power-up *)

String lengths

String length
An internal value set for
arrays by string assignment
operations.

Every array declared in the Define_Variable section has a string length value
associated with it. The string length of an array is an internal value set for arrays
by string assignment operations. This number is different than the storage capacity declared in the Define_Variable section. You can get this length value of
an array by using the Length_String function. Here is an example:

Y = LENGTH_STRING (PRESETS)

Here are examples of some assignments, and what the above line of code
would return to the variable Y in each case:

PRESETS
PRESETS
PRESETS
PRESETS

=
=
=
=

'FOUR'
'ONE'
"12,5,'123'"
"PLAY,5,,'NO',X"

(*
(*
(*
(*

Y
Y
Y
Y

=
=
=
=

4
3
5
6

*)
*)
*)
*)

The length of a string array cannot exceed the number of storage locations
allocated to it in the Define_Variable section. If the string GOODBYE is placed in
the PRESETS variable, the array will only contain the string GOODBY, dropping
the final E because PRESETS was defined to hold a maximum of six locations.
The length of PRESETS would also be set to 6.
Assigning string literals and string expressions automatically sets the length
of the string array to the length of the string literal or string expression being

96

Arrays and Strings

Unit 5: Arrays, Strings, and Buffers

assigned to it. However, assigning values to individual elements of an array


does not affect the length value of the array. For instance, if the letters W, O,
R, and D are assigned individually to elements of PRESETS as shown below,
the length will not change. If the length was previously 3, it will still be 3.

PRESETS[1]
PRESETS[2]
PRESETS[3]
PRESETS[4]

=
=
=
=

'W'
'O'
'R'
'D'

There is a way, however, to explicitly set the string length value of an array
variable. The Set_Length_String keyword accomplishes this. For instance, to set
the length value of PRESETS to 4, you would use the following statement:

SET_LENGTH_STRING(PRESETS,4)

After execution, the string length value of the array PRESETS is 4.


String lengths play an important role in the handling of strings. Consider this
string expression that contains an array in the expression:

"5,PRESETS,'GO'"

As AXCESS constructs a string from this string expression, the number of characters from the array PRESETS it will add will be equal to PRESETS string length
value. If PRESETS contains 1,2,3,4,5,6 but its string length value is 3, the resulting string from the above string expression will look like this:

"5,1,2,3,'G','O'"

The string length value of an array is very important to many string operations in AXCESS. This value determines how much of the string is used when the
entire array is referenced as a string. Knowing this will prevent subtle errors
from creeping into your code. For instance, if you assign values to individual
elements in an array, and then assign that array to another, nothing will actually
be copied. Here is an example:

Unit 5: Arrays, Strings, and Buffers

Arrays and Strings

97

PRESETS[1]
PRESETS[2]
PRESETS[4]
SAVE_PRESETS

=
=
=
=

5
6
'A'
PRESETS

What do you think the array SAVE_PRESETS will contain after this code is executed? It will totally depend on the length value of the PRESETS variable. If this
were the entire program, PRESETS would have a default length of 0, so nothing
would be copied into SAVE_PRESETS. In order to assure that SAVE_PRESETS were
to hold a copy of PRESETS, you would first need to set the length value of the
PRESETS array with this line inserted before the copy statement:

SET_LENGTH_STRING (PRESETS,4)

After this, the length value of PRESETS is 4, so the first 4 locations of PRESETS
will be used in all cases where you refer to the entire array.

Sending strings and arrays


To send a string to the outside world, you use the Send_String keyword. Here is
the syntax:

SEND_STRING device,<string, variable, or string expression>

The first value after the Send_String keyword is the device number or identifier to which you wish to send the string. Following that is a comma, then the
string, variable (which can be either a normal variable or an array), or string expression you wish to send. When an array variable is specified, the number of
characters from the array that are sent is determined by the length value for the
array. (Remember, you can set that value with the Set_Length_String function.)
For instance, if you need to send the PRESETS array to a card named RS232, you
would write the following line:

SEND_STRING RS232,PRESETS

String literals and string expression can also be sent using Send_String. Here
are some examples:

98

Arrays and Strings

Unit 5: Arrays, Strings, and Buffers

SEND_STRING RS232,'THIS IS A STRING LITERAL'


SEND_STRING RS232,"'EXPRESSION ',PRESETS,$D,$A"

The first example sends the entire set of characters enclosed in the single
quotes, from left to right, to the card named RS232. The second example first
builds the string expression using a string literal, followed by however many
characters from PRESETS as defined by its length value, and then two numbers
expressed here in hexadecimal. (The hexadecimal numbers in the example represent the codes for carriage return and line feed, respectively.)

ASCII codes
As you have learned, a string is broken up into single letters when placed into a
string array. Each storage space returns the letter it is holding when referenced.
For example, assume that PRESETS[3] holds the letter R. There are actually
three ways you can reference this array location (in this example using If statements):

IF(TEMP[3] = 'R')
{
(* statement(s) *)
}

or
IF(TEMP[3] = 82)
{
(* statement(s) *)
}

or
IF(TEMP[3] = $52)
{
(* statement(s) *)
}

The letter R has an ASCII value of 82 decimal, which is equivalent to 52 in


hexadecimal. In AXCESS, hexadecimal numbers begin with a dollar sign ($).
Therefore, the third example above shows $52, meaning this number, 52, is a
hexadecimal number.
All three methodsletters, decimal ASCII codes, and hexadecimal ASCII
codescan be used interchangeably. Feel free to use whichever method is easiest for the task at hand.

Unit 5: Arrays, Strings, and Buffers

Arrays and Strings

99

Integer arrays

Integer array
An array where each location
can hold a value ranging from
zero to 65,535. Note that an
integer array will take up
twice as much AXCESS
memory than a normal array
of the same storage capacity
would.

NOTE
If your array is only going to
hold alphanumeric values, do
not worry about making it an
integer array.

100

Arrays and Strings

So far, in all of the arrays you have seen, the range of values in each location is
zero to 255. Recall that the range of values in a single variable is zero to 65,535,
and when a value greater than 255 is assigned to an array location, the number
is truncated above 255. For instance, if the number 500 is assigned to a location
in an array, the actual number that is assigned is 244. (The way to find this is to
keep subtracting 256 from the number until the number is less than 256.)
So what if you need to create an array in which each location can contain values greater than 255? The answer is to use an integer array. An integer array is
just like a normal array, except that each location can hold values from zero to
65,535. To declare an integer array, simply place the keyword Integer in front of
the array definition in the Define_Variable section. If you wanted your PRESETS
array to be an integer array, here is how you would declare it:

DEFINE_VARIABLE
INTEGER PRESETS[6]

This declares an integer array with six locations; each location can hold values
from zero to 65,535.
There are certain limitations of integer arrays. If an integer array is assigned
to a normal array, all values are truncated above 255. (See the earlier discussion
on truncating values.) This also happens if an integer array is sent to a device
using the keywords Send_String or Send_Command. There is no problem,
however, in assigning a normal array to an integer array.

Unit 5: Arrays, Strings, and Buffers

15

Working with Arrays

Grouping data
The ability to group data into cohesive units (arrays) is one of the more powerful
features of the AXCESS language. Thus there are many keywords to help you manipulate arrays and strings. These keywords can be grouped into two classes:
conversion keywords and array manipulation keywords.

Conversion keywords
There are five conversion keywords available:
Itoa
Itohex
Atoi
Upper_String
Lower_String
The first three keywords serve to convert numberseither as a constant, in a
variable, or explicitly definedinto its string representation, and vice versa. The
last two convert a string into all uppercase or all lowercase.

Itoa
Itoa, which is short for integer to ASCII, creates a string that represents the
decimal value of a number. Here are some examples:

DEFINE_CONSTANT
CONST = 456
DEFINE_VARIABLE
STR[5]
VAR
DEFINE_PROGRAM
VAR = 789
STR = ITOA(123)
STR = ITOA(CONST)
STR = ITOA(VAR)

Unit 5: Arrays, Strings, and Buffers

(* STR = 123 *)
(* STR = 456 *)
(* STR = 789 *)

Working with Arrays

101

The comment after each statement shows the value of the array STR after each
assignment. The length value of STR is set to 3 in each case, even though its storage capacity is 5.

Itohex
This keyword is short for integer to hexadecimal. Itohex works in the exact
manner as Itoa, except that the integer is transformed into a hexadecimal ASCII
string. If you substitute the Itoa keywords in the previous example with Itohex
keywords, this would be the result:

STR = ITOHEX(123)
STR = ITOHEX(CONST)
STR = ITOHEX(VAR)

(* STR = 76 *)
(* STR = 1C8 *)
(* STR = 315 *)

Notice that there are no dollar signs in the results. This is because the dollar
sign indicates a numerical value expressed in hexadecimal, and is only used
when telling AXCESS that a number is hexadecimal.

Atoi
The Atoi keyword stands for ASCII to integer and does just that. It takes a
string literal, string expression, or array as a parameter, and returns a single integer as the result. Here are some examples:

DEFINE_CONSTANT
STR1 = 456
STR2 = YES789GO19
DEFINE_PROGRAM
NUM = ATOI('123')
NUM = ATOI(STR1)
NUM = ATOI(STR2)

NOTE
The three keywords Itoa,
Itohex, and Atoi automatically
set the length value of the
resulting string.

102

Working with Arrays

(* NUM = 123 *)
(* NUM = 456 *)
(* NUM = 789 *)

If the string contains all non-numeric characters (such as HELLO), Atoi returns the integer 0. However, if there are any numeric characters embedded
within the string, Atoi returns the first complete set it comes upon, as is the case
with STR2 above. Notice that only the first set of numbers from STR2 is returned.

Unit 5: Arrays, Strings, and Buffers

Array manipulation keywords


There are a number of keywords at your disposal that allow you to manipulate
arrays and to retrieve certain portions of an array:
Left_String
Mid_String
Right_String
Find_String
Remove_String

Left_String
For this keyword, you must specify two parameters: the string or array you are
referencing and the number of characters you need. Left_String returns a string
containing the number of characters specified starting at the beginning of the
string. Here is an example:

STR = LEFT_STRING (PRESETS,3)

After execution of this line, the array STR will contain the first 3 characters of
the array PRESETS. If PRESETS contains the string HELLO, then STR will contain
HEL. Also, the length value of STR will be set to 3.

Right_String
This keyword requires the same parameters as Left_String. However, Right_
String begins reading at the end of the string array for the specified amount of
characters. Assuming PRESETS still contains HELLO, replacing Left_String in
the previous example with Right_String will assign the string LLO to STR. This
keyword also will set the length value of the array receiving the result.

Mid_String
This keyword returns the specified amount of characters starting at a specified
location in the source string. Three parameters, rather than two, are needed for
its operation: the string to reference, the position at which to start, and the number of characters to return. Here is an example:

STR = MID_STRING (PRESETS,2,3)

Unit 5: Arrays, Strings, and Buffers

Working with Arrays

103

This line tells AXCESS: Place three characters from the array PRESETS, starting
at location 2 and moving to the right, into the array variable STR. If PRESETS
contains HELLO, this line will assign ELL to the array STR. This keyword also
will set the length value of the array receiving the result.

Finding strings
The keywords explained previously are helpful when you know where certain
parts of strings are located within a string array. However, there will be many
times when you have no idea where to look. In these cases, the Find_String keyword is used. This keyword will search through a string for a specified sequence
of characters. As soon as it finds a duplication of the sequence, it returns the beginning position of that duplication.
For example, suppose you dont know the exact contents of the PRESETS array, but you want to find out if it contains the string LO. Assume that PRESETS
contains HELLO, and the following line is executed.

X = FIND_STRING (PRESETS,'LO',1)

When AXCESS executes this statement, it will search the array PRESETS from
the beginning, looking for the string LO. If AXCESS finds the substring, as in this
case it will, it returns the starting position of the substring in the PRESETS array:
in this case, 4. The third parameter (in this example, 1) tells AXCESS where in the
string to start the search.

Removing strings
The Remove_String keyword works much like the Find_String keyword. However, when AXCESS finds the sequence it is looking for, it extracts every character
up to and including the sequence. All the other characters move up to fill in the
space. Here is an example:

DEFINE_VARIABLE
SOURCE[2]
DEST[2]
DEFINE_PROGRAM
SOURCE = THIS IS A TEST
DEST
= REMOVE_STRING (SOURCE,IS,1)

104

Working with Arrays

Unit 5: Arrays, Strings, and Buffers

After the last line is executed, DEST will contain THIS and SOURCE will contain IS A TEST. Notice that after the removal, the first location of the array
SOURCE contains a space. This is because Remove_String removed all characters
from the beginning of SOURCE up to and including the string IS. It did not remove the space following the string IS in SOURCE. Also notice that the first occurrence of IS is embedded in the word THIS. The length values of both arrays
are set according to the results of the operation. In this case, the length value of
SOURCE is set to 4, and DEST is set to 10.
In Find_String, each of the first two parameters can be a string literal, string
expression, or array. However, in the case of Remove_String, having anything
except an array as the first parameter makes no sense because AXCESS cannot
remove part of a string literal or string expression, only an array variable. This is
because string literals are constant values and string expressions may contain
constant values. Once loaded into the Master Card, constant values cannot be
changed. Look at these examples:

STR = REMOVE_STRING(PRESETS,12,1)
STR = REMOVE_STRING(2,HELLO,1,13,HELLO,1)

(* OK *)
(* NO *)

Remember that Remove_String changes the first parameter after it removes


whatever characters it needs, and only variables can be changed at run time.
Also remember to supply the starting position of the search as the third parameter for both Find_String and Remove_String.

Uppercase vs. lowercase


When using Find_String and Remove_String, as well as when comparing two
string values, it is important to remember that such comparisons are case sensitive, which means that uppercase and lowercase values are not evaluated the
same. As you recall, the compiler is not case sensitive when it comes to keywords and identifiers. The compiler is case sensitive, however, when it comes to
values inside single quotes (string literals). Here are some examples:

DEFINE_PROGRAM
Identifier_1 = 'Fred'
Identifier_2 = 'FRED'
if (IDENTIFIER_1 = IDENTIFIER_2)
{
(* This will not be true because 'Fred' and 'FRED'
are not the same. *)
}

Unit 5: Arrays, Strings, and Buffers

Working with Arrays

105

NOTE
When programming, you
may use whatever capitalizing scheme you wish. At
AMX, as a standard we
capitalize all keywords and
identifiers in the program.

Notice that the string literals FRED and Fred are not the same. However, in
the case of identifiers IDENTIFIER_1 and IDENTIFIER_2, AXCESS makes no differentiation based on the case of the letters making up the identifier name. Also notice that in this example the keyword If is not capitalized. This also makes
absolutely no difference to the AXCESS compiler.

Setting uppercase and lowercase


Within the AXCESS system, the lower case letter a is not the same as the upper case
letter A. Each has its own decimal ASCII code; the code for a is 97, and the code
for A is 65.
This could become a problem when, for example, your program compares an
incoming string ABC against another:

IF (ABC = 'YES')
{
(* statement(s) *)
}

If the incoming string is YES, there is no problem. The statements are executed as normal. However, what if ABC equals Yes? Since YES and Yes do
not have the same decimal ASCII value, the statements below the If would not
be executed.
The solution is to change all incoming strings to either uppercase or lowercase.
The keywords that do this are Upper_String and Lower_String. For example,
the following statement could have been added before the preceding program:

ABC2 = UPPER_STRING(ABC)

The If statement can now compare ABC2 against YES, providing that the If
statement reads IF (ABC2 = YES). The string Yes is accepted since it has
been converted into uppercase.
As expected, Lower_String converts a string into lowercase in the same manner that Upper_String operates.

106

Working with Arrays

Unit 5: Arrays, Strings, and Buffers

16

Using Buffers

Communicating to the outside world


One of the most powerful features of the AXCESS system is its ability to send and
receive any combination of values using RS-232, RS-422, PA-422, MIDI, and a variety
of other formats. You have the ability to construct any combination of numbers
and characters with the string expression and send it to an external device. In
addition, you can receive strings from external devices and interpret them to
obtain useful information.

Receiving strings

Buffer
An array variable that is
associated with a particular
device for the purpose of
storing information sent by
the device.

Receiving strings requires several more steps than sending strings. To be able to
receive strings from a device, you must first create a buffer for that device. A
buffer is an array variable that is associated with a particular device for the purpose of storing information received from the device.

Creating buffers
To create a buffer, use the Create_Buffer keyword. This keyword can only appear in the Define_Start section of your program, and it has the following syntax:

IMPORTANT

CREATE_BUFFER device, array

Create_Buffer can only be


used within the Define_Start
section.

The Create_Buffer keyword directs AXCESS to place any data received from the
specified device into the specified array. When AXCESS places the byte into the
Figure 5-6
When data comes in from a
device, it goes into the spot
determined by the length
value of the array. Here, the
length value was 3. So the
Y is put into location 4, and
the length value is
incremented to 4.

Unit 5: Arrays, Strings, and Buffers

BUFFER

10

Y
from device

Using Buffers

107

array, it increments the length value for the array and then places the byte into
the array at the current end of the array. See Figure 5-6 for a pictorial explanation.
Even though the array is acting as a buffer, it is still an array and can be
treated as one. You can still access the individual locations, send it to a device,
assign it to other arrays, assign other arrays to it, as well as use the array manipulation keywords discussed in the previous chapter.

Storing characters

NOTE
A buffer is said to be full
when its length value is equal
to its storage capacity.

When a device sends string information to the Master Card, the Master Card
places the incoming information into the buffer created for that device, and updates the buffers length value. (Remember, a buffer is an array.) These actions
are executed after the Master Card has passed through mainline. Since all data
going in and out of these devices is serial (that is, one byte at a time), each byte
is handled one at a time.
If the buffer is full when a character needs to be inserted into it, AXCESS drops
the first character, shifting the contents of the buffer left in order to insert the new
character at the end of the buffer. See Figure 5-7 for a diagram showing this action.

Retrieving characters
This is where the keyword Get_Buffer_Char comes into play. This keyword has
a two-part operation:
First, it retrieves the first character in the buffer for your own utilization.
This creates the same effect as if you retrieved the first storage location of a
normal string array.

from device

Figure 5-7

BUFFER

Inserting a character into a


full buffer causes the first
character to be dropped.

C
dropped

108

Using Buffers

Unit 5: Arrays, Strings, and Buffers

Second, it removes that character from the buffer, causing all the other
characters to shift up one place. The second character is now the first, the
third is now the second, and so on.
Here is the syntax of this keyword:

string = GET_BUFFER_CHAR (array)

The parameter passed to Get_Buffer_Char must be an array, but does not need
to be a buffer. (Remember: All buffers are arrays, but not all arrays are buffers.)
The statement will operate identically in either case. The result must be a simple
variable (not an array), because one and only one character will ever be returned.
In these examples, you will create an array called BUFR with a capacity of ten
characters. Then you will make it a buffer associated with a device named RS232.

DEFINE_VARIABLE
BUFR[1]
CHAR
DEFINE_START
CREATE_BUFFER RS232,BUFR

Now all string data sent to the Master Card from the device RS232 will go
into the array BUFR, as described earlier. Now, suppose you want to get the
data out of the buffer as soon as it enters. This is usually a two-step process.
Here is an example:

IF (LENGTH_STRING (BUFR))
CHAR = GET_BUFFER_CHAR (BUFR)

These two lines of code are actually one statement: an If statement. The condition of the If is the result of the Length_String keyword; if there are not any
characters in the buffer (length value of BUFR is zero), then AXCESS will skip the
second part of the statement. The second part, which will be executed if there
are one or more characters in BUFR, tells AXCESS to get the first character in BUFR
place it into the variable CHAR. This process is diagrammed in Figure 5-8.

Unit 5: Arrays, Strings, and Buffers

Using Buffers

109

BUFR

LENGTH_STRING = 6

GET_BUFFER_CHAR (BUFR)

Figure 5-8
Getting the next character
out of a buffer with
Get_Buffer_Char.

LENGTH_STRING = 5

CHAR

Characters should be continuously retrieved and removed from the buffer so


that incoming strings have spaces to completely enter. Be sure to place a
Get_Buffer_Char statement in a position to do this. Remember, the AXCESS system is constantly running through the main program, and AXCESS will execute
the Get_Buffer_Char statement as long as it is in its path of execution.

Clearing a buffer
AXCESS provides a single keyword which clears a buffer: Clear_Buffer. Here is
how it is used:

CLEAR_BUFFER BUFR

BUZZWORD
A null string is simply an
empty set of single quotes,
which represents a string
literal with no content and a
length value of zero.

110

Using Buffers

This keyword effectively sets the length of the buffer to zero, so that subsequent Get_Buffer_Char statements will not return anything. Using Clear_Buffer
is preferable to other methods, such as assigning a null string to the buffer, or
using Set_Length_String. The Clear_Buffer keyword actually compiles into
smaller code and executes faster than the other methods, plus it is clearer to the
reader as to what the programmer is trying to accomplish.

Unit 5: Arrays, Strings, and Buffers

17

Two-Dimensional Arrays

Powerful grouping
In the previous two chapters, you learned how to group data into arrays and
how to manipulate those arrays as single units. In this chapter, you will see how
to group multiple arrays together into one two-dimensional array. Using twodimensional arrays provides even greater flexibility and power for the more
complex applications.

The anatomy of the two-dimensional array

Two-dimensional
array
A storage place holding
multiple one-dimensional
arrays.

To understand the structure of the two-dimensional array you must refer back
to the basic single variable. A variable holds one and only one value at a time.
Using arrays, you can create a variable that can hold many values, and you reference the value you want with an index value. In this way, you are able to perform many programming feats such as storing several related values and
accessing a particular one.
The two-dimensional array expands on the one-dimensional array in the same
way that the one-dimensional array expands on the simple variable: it holds
multiple one-dimensional arrays which can be referenced with an index value.
Heres how you declare a two-dimensional array:

DEFINE_VARIABLE
NAMES[1][3]

Figure 5-9

NAMES

The structure of a twodimensional array.

Entire row is NAMES[3]

Single location is

NAMES[3][6]

Unit 5: Arrays, Strings, and Buffers

Two-Dimensional Arrays

111

NOTE
A two-dimensional array can
be declared with the Integer
keyword, just like a onedimensional array can. This
allows values in the range
zero to 65,535 to be
assigned to locations within
the two-dimensional array.

Notice how this declaration differs from the one-dimensional array. Instead of
a single storage capacity value, there are two. Heres how to interpret this variable declaration: NAMES is a two-dimensional array that can hold 10 one-dimensional arrays, each with a storage capacity of 30 characters. The total storage
capacity of NAMES is 10 characters by 30 characters, for 300 characters total. The
variable NAMES might be used to store up to 10 names, each with a maximum
length of 30 characters. Figure 5-9 depicts the structure of the array NAMES.

Storing values
The method of storing values into a two-dimensional array is basically the same
as that of a one-dimensional array. You can assign values to individual locations; you can assign one-dimensional arrays, string literals, and string expressions to one of the one-dimensional arrays inside the two-dimensional array;
and you can assign entire two-dimensional arrays to other two-dimensional arrays. Here is a small program as an example:

DEFINE_VARIABLE
NAMES[1][3]
PEOPLE[8][2]
ONE_NAME[3]
A_VALUE

(*
(*
(*
(*

two-dimensional array *)
another two-dimensional array *)
one-dimensional array *)
single-value variable *)

DEFINE_PROGRAM
A_VALUE = 1
ONE_NAME = 'EMMITT SMITH'
NAMES[1][1] = 6
NAMES[1][2] = A_VALUE
NAMES[2] = 'TROY AIKMAN'
NAMES[3] = "1,2,ONE_NAME,3"

(*
(*
(*
(*
(*
(*

1
2
3
4
5
6

*)
*)
*)
*)
*)
*)

Figure 5-10 depicts what the two-dimensional array NAMES will look like after
this code is executed.
Each row in the two-dimensional array has a length value just like a one-dimensional array. When a string literal or string expression is assigned to a row
of a two-dimensional array (see statements 5 and 6 in the above example), that
row has its length value set in the same manner as a one-dimensional array
does. The Length_String and Set_Length_String functions operate on rows in
two-dimensional arrays in the same way as whole one-dimensional arrays. Assuming that the above example has executed, here is what the Length_String
function returns on the first three rows of NAMES:

112

Two-Dimensional Arrays

Unit 5: Arrays, Strings, and Buffers

NAMES

10

Figure 5-10
The two-dimensional array
NAMES after the assign-

ments.

X = LENGTH_STRING (NAMES[1])

(* X will contain

*)

X = LENGTH_STRING (NAMES[2])

(* X will contain 11 *)

X = LENGTH_STRING (NAMES[3])

(* X will contain 15 *)

As you can see, it helps to think of a two-dimensional array as an array of


one-dimensional arrays.

Retrieving values
Retrieving values from a two-dimensional array is done in the same manner as a
one-dimensional array. Recall that there are two ways of referencing data in a
one-dimensional array: referencing a single value inside the array, and referencing the entire array. When using a two-dimensional array, there are three ways
of referencing the contents:
BUZZWORD

By cell (single values)

The term cell is often used


to refer to one particular
location in a two-dimensional
array.

By row (an array of values)


As a whole
Single locations (or cells) are retrieved by using two index values, the first
specifying the row and the second specifying which location in that row. Here is
an example:

VALUE = NAMES[3][6]

Unit 5: Arrays, Strings, and Buffers

Two-Dimensional Arrays

113

This line of code takes whatever value is in the sixth location of the third row
in the two-dimensional array NAMES, and assigns it to the variable VALUE. In the
context of the previous examples, VALUE will now contain an E.
Retrieving a whole row from a two-dimensional array is done in the same
way, except only the first index value is used. The index value will indicate the
row that is to be retrieved, and the length value for that row determines how
many locations from the row are actually retrieved. For instance:

ONE_NAME = NAMES[2]

After this line is executed, the array ONE_NAME will contain the string TROY
AIKMAN, and its length value will be 11. If you were to try to retrieve the entire

first row, nothing would be returned because its length value is zero.
The third method of accessing a two-dimensional array is to assign it to another two-dimensional array:

PEOPLE = NAMES

This will copy the entire contents of NAMES into PEOPLE, regardless of the individual rows length values. Making an assignment like this copies the entire contents of the two dimensional array, including the rows length values.
PEOPLE[2] will contain TROY AIKMAN and have a length value of 11, just like
NAMES[2].
If you go back to the original example, however, you will notice that the twodimensional array PEOPLE is defined with a size 8 by 20, whereas NAMES is 10
by 30. When AXCESS performs a copy from a two-dimensional array into a
smaller one, any information that falls outside the ranges of the smaller array
is not copied.

114

Two-Dimensional Arrays

Unit 5: Arrays, Strings, and Buffers

AXCESS Language Tutorial

UNIT 6

ADVANCED
AXCESS
PROGRAMMING

18

Using Subroutines

Introduction
By now you should have a firm grasp of the basics of AXCESS programming.
Now you will delve into some more complex topics such as using subroutines,
creating local variables, and passing parameter. With these tools, you will be
able to tame complex systems with a relatively small amount of code.
Subroutine

Subroutines

A section of code that


stands alone and can be
called from anywhere else
in the program.

There is a way to break the program into smaller, more manageable parts called
subroutines. A subroutine is a section of code that stands alone and can be
called from anywhere else in the program.
You may create subroutines for a variety of reasons. The most common usage
of subroutines is to execute the same group of instructions from different places
in the program. Using a subroutine to do this means that you dont have to re-type
those instructions over and over in the programyou can just call the subroutine.

Defining a subroutine
In AXCESS, subroutines are created using the Define_Call statement. Enclosed in
single quotes, the subroutine name follows the Define_Call keyword. There are
certain restrictions for these subroutine names:
They cannot be previously defined contents or variables.
They cannot be names that have already been assigned to buffers or Waits.
They are case-sensitive. Test and TEST are not the same.
Subroutines must be defined before they can be used. For this reason,
Define_Calls are usually found right before the Define_Start section of the program. For example:

DEFINE_CALL LIGHTS OFF


{
(* the subroutine goes here *)
}

Unit 6: Advanced AXCESS Programming

Using Subroutines

117

DEFINE_START
(* startup code goes here *)
DEFINE_PROGRAM
(* the main program starts here *)

Spaces in the subroutine name are allowed since it is a string literal. Notice
that the subroutines code is enclosed in braces. No matter how long the subroutine is, it must be in this format.

Calling your subroutines


In order to tell AXCESS to execute a subroutine, use the Call keyword and the name
of the subroutine in single quotes. For example, in order to execute the previous subroutine you would type the following where you want the Call to occur.

CALL LIGHTS OFF

When AXCESS executes the Call, program execution jumps to the first line
inside the braces of the Define_Call. The subroutine is executed only once, and
then AXCESS returns to the statement directly following the Call statement.

Sample program
Now you will look at a complete example program using a subroutine. Here are
the basic requirements for the program:
The devices used are four infrared/serial cards and an AMX TX Series
wireless (radio frequency) remote controller. The device numbers are 1, 2, 3,
4, and 128, respectively. The infrared/serial cards will transmit infrared
code to three different VCRs and a video projector.
The TX transmitter will have three buttons. Here are the functions to be
associated with each button:
Button 1: Projector to input 1, stop all VCRs, wait 5 seconds, play VCR 1.
This code listing is from
STEP8.AXS on the AXCESS
distribution diskette.

118

Using Subroutines

Button 2: Projector to input 2, stop all VCRs, wait 5 seconds, play VCR 2.
Button 3: Projector to input 3, stop all VCRs, wait 5 seconds, play VCR 3.

Unit 6: Advanced AXCESS Programming

This is the actual program:

DEFINE_DEVICE
VCR1 = 1
VCR2 = 2
VCR3 = 3
VPROJ = 4
RADIO = 128
DEFINE_CONSTANT
(* COMMON TRANSPORT CONSTANTS *)
PLAY
= 1
STOP
= 2
PAUSE
= 3
FFWD
= 4
REWIND
= 5
DEFINE_VARIABLE
WHICH_VCR
CALL_ACTIVE

(* This will hold which VCR and input


is selected *)
(* This will be on while the Call is
waiting to play the VCR *)

DEFINE_CALL DO SWITCH
{
CALL_ACTIVE = 1
PULSE [VPROJ,WHICH_VCR+1]
PULSE [VCR1,STOP]
PULSE [VCR2,STOP]
PULSE [VCR3,STOP]
WAIT 5 PULSE [WHICH_VCR,PLAY]
WAIT 6 CALL_ACTIVE =
}
DEFINE_START
CALL_ACTIVE =
DEFINE_PROGRAM
PUSH[PANEL,1]
{
IF (NOT CALL_ACTIVE)
{
WHICH_VCR = VCR1
CALL DO SWITCH
}
}
PUSH[PANEL,2]
{
IF (NOT CALL_ACTIVE)
{
WHICH_VCR = VCR2
CALL DO SWITCH
}
}

Unit 6: Advanced AXCESS Programming

Using Subroutines

119

PUSH[PANEL,3]
{
IF (NOT CALL_ACTIVE)
{
WHICH_VCR = VCR3
CALL DO SWITCH
}
}

Here is the program explained step-by-step:

DEFINE_DEVICE
VCR1 = 1
VCR2 = 2
VCR3 = 3
VPROJ = 4
RADIO = 128

This section defines the five devices used in the program.

DEFINE_CONSTANT
(* COMMON TRANSPORT CONSTANTS *)
PLAY
= 1
STOP
= 2
PAUSE = 3
FFWD
= 4
REWIND = 5

This section defines the common locations in the IR cards for the transport
functions PLAY through REWIND.

DEFINE_VARIABLE
WHICH_VCR
CALL_ACTIVE

The variable WHICH_VCR will hold the selected VCR/input number.


CALL_ACTIVE tells whether or not the subroutine is waiting to tell the VCR to
play. If its value is zero, the subroutine is not waiting; if the value is 1 or
greater, the Waits in the subroutine are still pending.

DEFINE_START
CALL_ACTIVE =

120

Using Subroutines

Unit 6: Advanced AXCESS Programming

When the system is turned on or reset, this will initialize CALL_ACTIVE to zero.

DEFINE_CALL DO SWITCH
{

This begins the subroutine. Notice that the sequence must begin with a brace
no matter how long the subroutine is.

CALL_ACTIVE = 1
BUZZWORD
A flag is a variable that is
used to store an on or off
state.

The first statement of the subroutine turns CALL_ACTIVE on. In this program
CALL_ACTIVE acts as a flag to let the rest of the program know that the Waits

inside the subroutine are still pending, and the subroutine is not to be re-activated until the Waits are finished.

PULSE [VPROJ,WHICH_VCR+1]
PULSE [VCR1,STOP]
PULSE [VCR2,STOP]
PULSE [VCR3,STOP]
WAIT 5 PULSE [WHICH_VCR,PLAY]

This section is the heart of the Define_Call. The first statement Pulses the
function on the video projectors controller card corresponding to the input desired on the projector. A little trick was used here: since the functions on IR cards
for video projectors have the switcher inputs located at 1120, you can simply
add 10 to the desired input number to obtain the needed IR function number. For
instance, if WHICH_VCR contains 2meaning you selected VCR number 2 and
input number 2 on the projectorthe first Pulse statement will activate function 12, which (on video projector cards) is usually the input 2 Select function.
The next three Pulses stop all three VCRs, and then a Wait is started with a
time of five seconds. When this Wait is over, AXCESS will Pulse the Play function
on the VCR whose device number equals WHICH_VCR.

WAIT 6 CALL_ACTIVE =
}

Unit 6: Advanced AXCESS Programming

Using Subroutines

121

BUZZWORD
When flags are used to
disable events in this way, it
is called locking or locking
out. When the flag is turned
off, the event or code is
unlocked.

Six seconds after the subroutine is called, CALL_ACTIVE is reset to zero. This
will create a one half-second delay between the end of the Play Pulse and the
unlocking of the subroutine. Thus, six seconds after being called, the subroutine can be safely re-activated again.

DEFINE_PROGRAM
PUSH[PANEL,1]
{
IF (NOT CALL_ACTIVE)
{
WHICH_VCR = 1
CALL DO SWITCH
}
}

The main program starts here. The code inside each Push first checks to see if
the subroutine is busy by checking CALL_ACTIVE with an If statement. If the flag
is not on, the code sets WHICH_VCR to the desired VCR number and projector input number, and then calls DO SWITCH. This is repeated for each button.
You may realize that the value assigned to the variable WHICH_VCR in each
Push is equivalent to the channel in the Push statement. Since this is true, the
three button presses could be combined into one section like this:

DEFINE_PROGRAM
PUSH[PANEL,1]
PUSH[PANEL,2]
PUSH[PANEL,3]
{
IF (NOT CALL_ACTIVE)
{
WHICH_VCR = PUSH_CHANNEL
CALL DO SWITCH
}
}

This works great for control panels with buttons positioned sequentially, but
not so well if the buttons channel codes are not sequential. Since you will build
on this program in the upcoming chapters, leave the section as three separate
Pushes.

122

Using Subroutines

Unit 6: Advanced AXCESS Programming

19

Local Variables and Parameters

More power for your subroutines


Two features which expand on the functionality of subroutines are local variables
and parameters. Using these features can help simplify your programs, add more
power to your code, and make your program easier to read and understand.

Local variables
Local variable
A variable declared in a
subroutine, and whose
scope is limited to that
subroutine.
Global variable
Any variable defined in the
Define_Variable section of
the program. The scope of
these variables extends
throughout the entire
program.
Scope
The part of the program
where the variable can be
accessed. A variable has
global scope if the entire
program has access to it; a
variable has local scope if
only a section of the program
has access to it.

NOTE
A global variable is said to be
hidden if a local variable of
the same name is in scope.

The first of these two features is the local variable. A local variable is a variable
which is declared inside a Define_Call and can only be used inside that same
Define_Call. Variables declared in the main Define_Variable section are called
global variables. The words local and global refer to a variables scope, which
is the part of the program that can access the variable. Global variables have
global scope; that is, the entire program has access to them. A local variable has
local scope, and can only be accessed inside the Define_Call in which it is declared. Here is an example of a local variable declaration:

DEFINE_CALL TEST CALL


LOCAL_VAR
LOC_VAR
LOC_ARRAY[1]
{
LOC_VAR
= 1
LOC_ARRAY = TESTING
}

This section of code defines the subroutine TEST CALL. It then declares two local
variables, LOC_VAR (a simple variable) and LOC_ARRAY (an array with a storage
capacity of 10.) Local variables are defined after the Define_Call and before the
first open brace, with the keyword Local_Var preceding the block of local variables defined. Nowhere else in the entire program can any code access the two
variables LOC_VAR and LOC_ARRAY; they are local to the subroutine TEST CALL.
A local variable can have the same name as a local variable in another subroutine. If another subroutine declares a local variable LOC_VAR, that subroutine will use its LOC_VAR and TEST CALL will use its own LOC_VAR. A local
variable can also have the same name as a global variable. If this happens, the
local variable takes precedence in its scope; the global variable is hidden. For

Unit 6: Advanced AXCESS Programming

Local Variables and Parameters

123

instance, if in the previous example there was a global variable LOC_VAR, the
reference in the subroutine still refers to the local variable. In this case the global LOC_VAR is hidden from the subroutine.
Local variables are best used in cases where a subroutine needs to use a variable, but no other piece of code needs it. Such variables are usually temporary
flags, loop counters, and other variables a subroutine may need to do its work.
A well-organized program may even have more local variables than global variables, because the main work of the program is handled mostly by subroutines
rather than the main program.

Parameters
Several AXCESS keywords and functions use parameters, such as Atoi and
Mid_String. Your Define_Call subroutines can also use parameters. Parameters
are variables defined as part of the Define_Call declaration that can receive values from and pass back values to the Call statement that called the subroutine.
Here is a subroutine declaration using parameters:

DEFINE_CALL DO SWITCH (INPUT,OUTPUT)


{
SEND_STRING SWITCHER, I, ITOA(INPUT), O,
ITOA(OUTPUT)
}

This subroutine is defined as having two parameters, INPUT and OUTPUT (enclosed in parentheses), which are essentially local variables of the subroutine.
These variables, however, have their initial values set by the parameters in the
Call statement which called the routine. Here is a Call to this subroutine:

CALL DO SWITCH (3,7)

This calls the subroutine DO SWITCH, and assigns the value 3 to INPUT and 7
to OUTPUT. The subroutine uses a string expression to construct the string I3O7
and then sends the string to the card named SWITCHER. This shows the power
of using parameters. Later in the program, the same subroutine can be used
with different parameters to produce different strings. Here are some examples:

124

CALL DO SWITCH (1,2)

(* sends I1O2 *)

CALL DO SWITCH (2,12)

(* sends I2O12 *)

CALL DO SWITCH (1,2)

(* sends I1O2 *)

Local Variables and Parameters

Unit 6: Advanced AXCESS Programming

BUZZWORD
The caller refers to the Call
statement that called the
subroutine.

Passing values back to the caller


A parameter variable can be modified inside a subroutine just as any other type
of variable. After all code in the subroutine has been executed and before
AXCESS returns to the caller, AXCESS attempts to copy the values in the parameter variables back into the callers parameters. This is only successful if the
subroutine is called with variables in the Call statement. Here is an example:

DEFINE_CALL SQUARE (NUMBER)


{
NUMBER = NUMBER * NUMBER
}
X = 5
CALL SQUARE ( X )
(* X now equals 25 *)
CALL SQUARE ( X )
(* X now equals 625 *)

When the subroutine SQUARE is called with a variable as a parameter (in this
case X), a series of events occurs.
The value of the variable (in this case, 5) is assigned to NUMBER.
The subroutine takes the parameter, multiplies it by itself (thus squaring it)
and assigns the result back to itself.
AXCESS then re-assigns NUMBER back to the variable X, so that upon return
from the subroutine, X will contain its previous value squared.
If, however, a constant value is passed to the routine, a re-assignment cannot
be made. For example:

CALL SQUARE ( 5 )

This will assign the value 5 to the parameter variable NUMBER in the subroutine, and NUMBER will be squared. However, AXCESS cannot take the value in
NUMBER and re-assign it to the constant value 5. Calling a routine in which a parameter is expected to return some sort of result should not be called with a constant value as that parameter. If you want to use a constant value as a parameter
to this subroutine and still get a new value returned, rewrite the Define_Call to
have two parameters:

Unit 6: Advanced AXCESS Programming

Local Variables and Parameters

125

DEFINE_CALL SQUARE (NUMBER,RESULT)


{
RESULT = NUMBER * NUMBER
}

Here are some examples of using this subroutine:

CALL SQUARE (5,X)


(* on return, X will contain 25 *)
CALL SQUARE (X,Y)
(* on return, X will contain 25 and Y will contain 625 *)

It is important to note that the re-assignment of the parameter variable to the


callers variable happens after the subroutine is finished and before any other
code is executed. This fact could lead to a very-hard-to-find bug:

DEFINE_VARIABLE
GLOBAL
DEFINE_CALL BUGGY (PARAM)
{
PARAM = 1
GLOBAL = 2
}
DEFINE_PROGRAM
GLOBAL = 5
CALL BUGGY (GLOBAL)
(* What will GLOBAL contain here? *)

You might expect GLOBAL to contain 20 when AXCESS reaches the comment.
However, this is not the case. In the subroutine BUGGY, after GLOBAL is set to 20,
AXCESS re-assigns the value in PARAM to the variable in the Call statement which
called BUGGYin this case GLOBAL. The parameter variable PARAM contains the
value 10 at the end of the subroutine, and this value is re-assigned to the variable in the Call statement: GLOBAL. In the end, GLOBAL will contain the value 10
at the comment.

126

Local Variables and Parameters

Unit 6: Advanced AXCESS Programming

20

Include Files and System_Calls

Managing large programs


In this chapter, two advanced features of AXCESS will be introduced: include
files and System_Calls. These two features are important in managing large
programs and in simplifying basic programming. Include files allow you to
break a large program into smaller, more manageable files. System_Calls provide ready access to pre-canned programming solutions and tools, without
having to rewrite them.

Include files

Include file
A DOS file which is included
in the compiling process
without having to reside in
the computers memory.

Most of the time, your program will reside in a single file. AXCESS program files
are saved with a DOS extension of AXS. When you compile your program,
AXCESS compiles it in the computers memory, and when you save your program, AXCESS saves it to disk using this extension.
Sometimes, however, a program may grow to be too large to fit into your
computers memory all at once. In such a case, it is possible to break the program up into multiple files. This is done by taking portions of your program and
putting them into one or more include files. An include file is a DOS file which is
included in the compiling process without having to reside in the computers
memory. Include files always have the DOS extension AXI.
To include a file in a program, use the keyword Include, followed by the
filename in single quotes. Here is an example:

DEFINE_PROGRAM
(* Program statements can go here *)
INCLUDE TEST.AXI
(* More program statements can go here *)

When the compiler reaches the Include statement, it jumps into the specified file and continues compiling. When it has reached the end of the file, it
comes back to the line following the Include statement and continues compiling.
See Figure 6-1 for a pictorial explanation.

Unit 6: Advanced AXCESS Programming

Include Files and System_Calls

127

AXCESS main program


(in computer memory)

Include file TEST.AXI


(on disk)

#INCLUDE TEST.AXI

Figure 6-1
Compilation flow using an
include file.

The code compiled in the include file is compiled just as if it were in the main
program where the Include statement is located. The Include statement can appear anywhere in your program, since it is actually a statement to the compiler
and not the AXCESS control system. What you decide to put into include files is
up to you. Here are several suggestions on their use in large programs:
Place each definition section in its own include file
Group sections of the main program into include files
Place all subroutines into an include file
Place routines that you want to share between multiple programs into an
include file
Place code you wish to re-use in other systems into include files
This by no means is a comprehensive nor mandatory list of how to organize
your programs, but simply some suggestions to get you started toward bigger
and better system programming.
Include files are loaded and edited using the AXCESS editor much like normal
program files (see Unit 1). Like program files, the AXCESS name (not the DOS
name) of the include file is stored on the first line of the file as a Program_Name
declaration.

128

Include Files and System_Calls

Unit 6: Advanced AXCESS Programming

System_Calls and library files

Library file
A special file containing
AXCESS program code.
These files are used only for
System_Calls.

This is the file SQUARE.LIB


on your AXCESS distribution
diskette.

Using include files makes it very easy to share already-written code between
multiple programs. For instance, suppose you had created a subroutine to
handle a certain audio/video switcher, and you saved the subroutine into an
include file. When you need to use the subroutine in another program, you simply include the file into your program and bingo, you have a pre-written piece
of code ready for use.
This is where library files come in. Library files are actually special types of
include files which have the DOS extension LIB. The difference between these
and include files is that these files must contain a Define_Call subroutine having
the same name as the Program_Name on the first line of the library file. This
Define_Call can then be called from within a program using the System_Call
keyword. Here is a small example library file listing:

PROGRAM_NAME = SQUARE
DEFINE_CALL SQUARE (NUMBER)
{
NUMBER = NUMBER * NUMBER
}

This is the entire contents of a library file. Now if you have a variable X which
you want to square within a program, use the following line:

SYSTEM_CALL SQUARE (X)

This line generates a call to the subroutine SQUARE. This is because a


System_Call statement is identical to a Call statement, except that the actual
Define_Call is in a library file instead of the main program.
After AXCESS compiles the main program, it searches through all available
library files for the one that has the following statement on the first line:

PROGRAM_NAME = SQUARE

When AXCESS finds this file, it is compiled. Since the library file contains a
Define_Call with the same name as the Program_Name in the file, the
System_Call to SQUARE actually calls the Define_Call SQUARE in this library
file. See Figure 6-2.

Unit 6: Advanced AXCESS Programming

Include Files and System_Calls

129

AXCESS main program

SYSTEM_CALL SQUARE (X)

Library file

PROGRAM_NAME = SQUARE
DEFINE_CALL SQUARE (NUMBER)
{
NUMBER = NUMBER * NUMBER
}

Figure 6-2
The compilation order of a
library file.

When using System_Calls, you do not have to implicitly include the file with
the subroutine you wish to use because AXCESS automatically does this for you.
In essence, the System_Call is almost like the Include and Call keywords
bundled into one keyword.

Factory System_Calls

BUZZWORD
The look and feel of
something refers to how it
interacts with the user. In the
case of control panels, this
refers to how a device reacts
when certain buttons are
pressed, and what kind of
feedback the user receives.
This is also called the user
interface.

130

AMX has written a number of System_Calls to handle many of the most common
programming requirements in AXCESS systems. These library files are included
on the AXCESS distribution diskette. The System_Calls are divided into several
categories including VCRs, switchers, laser discs, and others. Factory System_
Calls follow a standard naming convention, and the System_Calls in each group
take the same parameters. See Figure 6-3 for descriptions of these two standards.
The main goal of these System_Calls is to maintain a consistent look and
feel for the control panels, regardless of how the deck behaves from its own
remote control. For instance, when some VCRs are in the pause mode, pressing
Pause again will cause the deck to play, whereas on other VCRs, pressing Pause
again does nothing. However, when using a VCR System_Call, pressing Pause
on the control panel while the deck is in pause mode will always cause the deck
to play. This is because the different VCR System_Calls were written to take into

Include Files and System_Calls

Unit 6: Advanced AXCESS Programming

Factory System_Calls
Device type

System_Call*

Parameters required

VCR

VCR

PANEL, PLAY, STOP, PAUSE, FFWD, REWIND,


SRCH_FWD, SRCH_REW, RECORD, DEVICE

Cassette deck

CAS

PANEL, PLAY, STOP, PAUSE, FFWD, REWIND,


SRCH_FWD, SRCH_REW, RECORD, DEVICE

Laser disc player

LDP

PANEL, PLAY, STOP, PAUSE, SKIP_FWD,


SKIP_REV, SCAN_FWD, SCAN_REW, DEVICE

Compact disc player

CDP

PANEL, PLAY, STOP, PAUSE, SKIP_FWD,


SKIP_REV, SCAN_FWD, SCAN_REW, DEVICE

Slide projector

SLD

PANEL, FORWARD, REVERSE, FOCUS_IN,


FOCUS_OUT, POWER, DEVICE

Switcher

SWT

INPUT, OUTPUT, LEVEL, DEVICE

Other

Varies

Varies

Figure 6-3
A list of pre-written
System_Calls for your use.

* There is a complete set of System_Calls for each type of device. Following the first three
letters of the System_Call name is a number. For instance: System_Call VCR3.

account the different behaviors of VCRs. Therefore, no matter what type or


model of equipment is being used, the behavior of the buttons on the control
panel will not change. See the AXCESS Programming Guide for a detailed description of the look and feel of the various factory System_Calls.

The instance number and name mangling


A System_Call can be called more than once in a single program. Take a look at
this example that uses the SQUARE System_Call:

DEFINE_VARIABLE
NUM1
NUM2
DEFINE_PROGRAM
NUM1 = 5
NUM2 = 6
SYSTEM_CALL SQUARE (NUM1)
SYSTEM_CALL SQUARE (NUM2)

Unit 6: Advanced AXCESS Programming

Include Files and System_Calls

131

This code generates two calls to the subroutine SQUARE in the library file, but
it only includes and compiles the library file once. The two System_Calls call the
same routine. This is fine for most System_Calls, but there are occasions where
this could cause problems.
To illustrate this, make a new library file which has Wait statements in its subroutine. Here is a listing:

DEFINE_CALL SEND (STR1[1],STR2[1],CARD )


{
SEND_STRING CARD, STR1
WAIT 2 SS WAIT
SEND_STRING CARD, STR2
}

This subroutine takes three parameters. The purpose of the subroutine is to


send the two strings to the device specified in the parameter variable CARD, with
a delay of two seconds between sends.
The following line will send the string AMX, followed two seconds later by
the string AXCESS to card number 3:

SYSTEM_CALL SEND (AMX,AXCESS,3)

This code compiles and works fine. But what happens when you add another
System_Call to the program?

SYSTEM_CALL SEND (AMX,AXCESS,3)


SYSTEM_CALL SEND (GOOD,TIMES,5)

Only one Define_Call SEND is compiled, and both of these lines call the same
subroutine. The first call sets the routines STR1, STR2, and CARD parameter variables, sends the string AMX to device 3, and starts the named Wait. The next
System_Call resets the parameter variables to all new values, and sends the
string GOOD to card 5. Since the Wait is already in the wait list, however, it is
not restarted. Thus when the Wait comes due, it will use the latest values stored
in the parameter variables CARD and STR2. In this case, CARD will still be 5 and
STR2 will contain the string TIMES, so TIMES is sent to device number 5.

132

Include Files and System_Calls

Unit 6: Advanced AXCESS Programming

Notice that the string AXCESS is never sent to card 3. This is because the
STR2 parameter variable in the subroutine is overwritten by the second

Instance number
A number enclosed in
brackets after the System_
Call keyword to denote
which copy of the compiled
library file to call.

System_Call before the Wait comes due. This is the problem with using Waits
in System_Call subroutines.
There is a way to get around this, however. By using an instance number, you
can force the compiler to compile two separate copies of the subroutine. Here is
an example of the same System_Calls using instance numbers:

SYSTEM_CALL [1] SEND (AMX,AXCESS,3)


SYSTEM_CALL [2] SEND (GOOD,TIMES,5)

The number in the brackets is the instance number. By using this number, you
tell the compiler to compile multiple copies of the routine, and have the different
System_Calls each call a separate copy. The compiler accomplishes this by using
the instance number to modify the actual name of the Define_Call before compiling it. When compiling a library file called with an instance number, AXCESS converts the number to ASCII and appends it to the Define_Call name (see Figure 6-4.)

Figure 6-4

AXCESS main program

How AXCESS modifies the


Define_Call name in the
library file using the instance
number.

SYSTEM_CALL [1] SEND


(AMX,AXCESS,3)

Library file

DEFINE_CALL SEND1

Unit 6: Advanced AXCESS Programming

Include Files and System_Calls

133

Name mangling
The process where the name
of the Define_Call and any
Waits and Wait_Untils in a
library file are changed so
that multiple separate copies
can be compiled into a
program.

This process is called name mangling. When an instance number is used in a


System_Call, AXCESS mangles the names of the Define_Call and any Waits
and Wait_Untils in the subroutine. When the System_Call subroutine SEND is
called with an instance number of 1, AXCESS generates a call to SEND1. Then it
compiles the library file, adding a 1 to the end of the Define_Call name and
the Wait name. If a System_Call were made with the instance number equal to
100, the Define_Call would be named SEND100, and the Wait would be named
SS WAIT100.
In the program, all System_Calls using the same instance number call the
same copy of the library file. For instance:

SYSTEM_CALL
SYSTEM_CALL
SYSTEM_CALL
SYSTEM_CALL

[1]
[2]
[2]
[3]

SEND
SEND
SEND
SEND

(HOW,FEE,3)
(DO,FI,3)
(YOU,FO,3)
(DO,FUM,3)

(*
(*
(*
(*

calls
calls
calls
calls

copy
copy
copy
copy

1
2
2
3

*)
*)
*)
*)

Suppose there is a Define_Call SEND1 in your program, and you attempt the
following line of code:

SYSTEM_CALL [1] SEND (LETS, GO, 3)

After name mangling, this generates a call to SEND1, which will actually call
the subroutine SEND1 in the program file, not the library file. In fact, since the
call to SEND1 is resolved (that is, a subroutine SEND1 was found) the library file is
never compiled. However, if the instance number was 2, the SEND1 subroutine
would not be called, and the SEND library file would be compiled with the
names mangled using the character 2.

134

Include Files and System_Calls

Unit 6: Advanced AXCESS Programming

AXCESS Language Tutorial

GLOSSARY
AND INDEX

ADVANCED
AXCESS
PROGRAMMING

Glossary
Analog An input or output that can have many values.
Array A single variable that has more than one storage location.
ASCII A coding scheme that assigns numeric values to letters, numbers, and
other characters.
AXlink The AXCESS communications bus.
Bar graph A visual representation of a level.
Baud rate Speed of data transmission; measured in bits per second (bps).
Bitwise operator A keyword or symbol that performs a bit-by-bit operation
between two items.
Block Highlighted section of text in the AXCESS text editor.
Block file File saved on disk using the Write Block to Disk command (Alt-W);
it has the DOS extension AXB.
Boolean expression A conditional statement used to tell AXCESS whether or
not to execute a particular function or functions in the program. This is also
known as a relational expression.
Boolean operator A keyword or symbol that creates a relation between two
items.
Buffer An array variable that is associated with a particular device for the purpose of storing information sent by the device.
Caller The Call statement that called a subroutine.
CardFrame Housing for the AXCESS control cards.
Case sensitive Uppercase and lowercase values are not evaluated the same;
for example, CASS is not the same as cass.
Cell One particular location in a two-dimensional array.
Channel The basic input/output unit. Channels correspond to actual control
functions such as relays and infrared signals. Each AXCESS device has 255
channels, although all are not always used.

Glossary

137

Comment A description or remark within an AXCESS program that is not considered part of the actual program; it is ignored by the compiler.
Communications port Port through which serial data is transferred.
Compilation error An error that occurs at compile time.
Compile time When the program is compiled.
Compound statement A group of several statements enclosed by a set of
braces.
Constant An identifier whose value remains unchanged throughout the entire
program.
Decimal Base 10 numbering system.
Deck Any piece of equipment controlled by an AXCESS device.
Default statement A statement (or compound statement) that is executed if
none of the conditions being tested is true.
Definition section One of the various divisions of the AXCESS program. These
sections are Define_Device, Define_Constant, Define_Variable, Define_
Latching, Define_Mutually_Exclusive, Define_Start, and Define_Program.
Device A component that can be connected to AXlink.
Device-channel A reference to a specific channel in the AXCESS system in the
format [device,channel].
Device number A unique number from 1 to 255 designated to each device
connected to AXCESS via AXlink.
Digital An input or output that can have only two values: on or off.
DIP switch A switch on a circuit board that can be turned on or off to determine various settings.
Direct assignment Generating an output change by assigning a value to a
device-channel.
Downloading The sending of data from a computer to a device (such as a
Master Card).
Dumb terminal A serial communications device. Whatever is typed goes out
the communications port, and whatever comes in the port is displayed on the
screen.
EPROM Acronym for erasable programmable read-only memory.

Glossary

138

Error See compilation error, run-time error, and logic error.


Executable code A translated version of the source code that the AXCESS system can understand.
Feedback The lighting of a button during and after it is pressed.
Firmware Residing within the EPROMs in many AXCESS devices, this software
enables these devices to operate.
Flag A variable that is used to store an on or off state.
Free format A characteristic of the AXCESS language that allows the source
code to be independent of tabs and carriage returns.
Global variable Any variable in the Define_Variable section of the program.
The scope of these variables extends throughout the entire program.
Hexadecimal Base 16 numbering system.
Identifier A combination of letters, numbers, or underscores that represents a
device, constant, or variable.
Include file A DOS file which is included in the compiling process without having to reside in the computers memory; it has the DOS extension AXI.
Index value The number that tells AXCESS which location in an array to retrieve. This value must be an integer from 1 to 255.
Infinite loop A loop which will never terminate.
Input change A signal sent by the input function of a channel that alerts
AXCESS to scan mainline for a reference to that signal.
Instance number A number enclosed in brackets after the System_Call keyword to denote which copy of the compiled library file to call.
Integer In AXCESS, the range of whole numbers from 0 to 65,535, inclusive.
Integer array An array where each location can hold a value ranging from
zero to 65,535. Note that an integer array will take up twice as much AXCESS
memory than a normal array of the same storage capacity would.
Keyword A word or series of words that signifies the operation for AXCESS to
execute.
Latching A defined behavior of status that causes its output channel to stay on
or off until activated once more.
Level A value that is related to an analog input or output on an AXCESS device.

Glossary

139

Library file A special file containing AXCESS program code. These files are used
only for System_Calls.
Local variable A variable declared in a subroutine, and whose scope is limited
to that subroutine.
Locking When flags are used to disable events.
Logic error An error in the actual design of the program.
Look and feel How something interacts with the user. This is also called the
user interface.
Loop A block of code that is continuously executed until a condition is satisfied.
Master Card The AXCESS card that controls the activities of the AXCESS system.
Mainline The section of the program that actually is executed continuously by
the Master Card. This is also known as the Define_Program section.
Modem Communications device used to transfer serial data through phone
lines.
Momentary A defined behavior of status that causes its output channel to be
activated as long as the corresponding button is pressed.
Momentary mutually exclusive A characteristic of status that allows only one
channel of a pre-defined set to be on at a time. The output channel is activated
as long as the corresponding button is pressed.
Mutually exclusive latching A characteristic of status that allows only one
channel of a pre-defined set to be on at a time. The output channel stays on
until another channel of the set is activated.
Mutually exclusive set Only one channel or variable in this set can be on at a
time.
Mutually exclusive toggling A characteristic of status that allows only one
channel of a pre-defined set to be on at a time. The output channel stays on
until it is re-activated or another channel of the set is activated.
Name mangling The process where the name of the Define_Call and any
Waits and Wait_Untils in a library file are changed so that multiple separate
copies can be compiled into a program.
Nesting Placing conditional branches inside other conditional branches.
Null string An empty set of single quotes, which represents a string literal with
no content and a length value of zero.

Glossary

140

One-to-one Each button has one and only one function, with no special
conditions or considerations.
Operator A character or group of characters that performs a specific
mathematical or relational function.
Output change A message to the output function of a channel.
Password A series of numbers that allows access to restricted data.
Preset A level saved for later retrieval. When a preset is recalled, the
level returns to the preset value.
Program file File containing the AXCESS program source code; it has the
DOS extension AXS.
Push window A window on the bottom left of the AXCESS program that
displays the Push statement of the last button pressed in the AXCESS system.
Ramp To change a level from one value to another smoothly over a period of time.
Re-assignment When AXCESS assigns a new value to a parameter variable after a subroutine is executed, but before it returns to the caller.
Relational expression See Boolean expression.
Reserved word An identifier reserved for use by the AXCESS compiler.
Row A one-dimensional array of values in a two-dimensional array.
Run time When the program is executed in the Master Card.
Run-time error An error that occurs during program execution.
S19 format File format used to place code or data into EPROM chips.
Scope The part of the program where the variable can be accessed. A
variable has global scope if the entire program has access to it; a variable
has local scope if only a section of the program has access to it.
Select group A group of buttons that selects a single deck or device out
of a group.
Select variable A variable whose value determines which device in a
group is currently selected.
Serial The transfer of data one byte at a time.
Server Card The AXCESS card that distributes command signals among
device cards, to and from the Master Card, and within its CardFrame.

Glossary

141

Source code The AXCESS program that you type and edit.
State The on or off status of a channel.
Statement A keyword and all of its parameters or conditions.
Status Records the state of the physical part of a channel.
String A set of values grouped together with single and/or double quotes.
String expression Enclosed by double quotes, this expression combines several types of data into a single string.
String length An internal value set for arrays by string assignment operations.
String literal A set of characters (values ranging from 32 to 127) enclosed in
single quotes.
Subroutine A section of code that stands alone and can be called from anywhere else in the program.
System variable A value kept in the Master Card that can be referenced by
certain keywords.
Transport function A common function of devices such as VCRs and cassette
decks. For example: Play, Stop, Pause, Fast Forward, and Rewind.
Two-dimensional array A storage place holding multiple one-dimensional
arrays.
Uploading The opposite of downloading; the computer receives data from a
device.
User interface See look and feel.
Variable A place to store data that will change as the program is executed.
Wait list A list containing unexpired Wait statements. After each pass through
mainline, the Master Card scans this list to see if any have come due.
Wait_Until list A list containing unexpired Wait_Until statements. After each
pass through mainline, the Master Card scans this list to see if any have come
due.
Warning A statement by the compiler urging caution with a potentially hazardous statement in the source code.
Wildcard character Allows any character to be in its place; in AXCESS, this is
the question mark (?). This is only valid when comparing dates and times.

Glossary

142

Index
A
Active. See Select...Active
Analog input or output 81
And 66
Arrays 91100
accessing values 9294
as strings 95
defining 9192
integer 100
manipulation keywords 103
sending 9899
storing values 9294
string lengths 96
two-dimensional 111114
ASCII codes 99
Atoi 102
AX File menu 912
Create S19 file... 10
Options... 11
Retrieve 910
Send w/password... 11
Send... 10
Source-send 9, 10
Verify 10
AXCESS
color mode 4
firmware version information 13
installation 3
mainline 3334
memory 9
monochrome mode 4
power-up 33
program files. See Program files
starting program 3
text editor 8
version information 9
AXlink
and While 77
comparing devices on 12

Index

device numbers 5
errors 6
listing devices on 12

B
Bar graphs 86
Blocks 18
Boolean expression tables 6566
Boolean expressions 58
and Wait_Until 72
in feedback statements 64
Boolean operators 65
Braces 24
nesting If...Else statements 59
nesting Waits 70
with compound statements 58
with subroutines 118
Brackets
with arrays 92
with Push 36
with To 38
Branching 58. See also If, Select...Active.
Buffers 107110
clearing 110
creating 107108
retrieving characters from 108110
storing characters in 108

C
118. See also Subroutines
parameters 124
Calling
subroutines 118
Cancel_All_Wait 72
Cancel_All_Wait_Until 73
Cancel_Wait 72
Cancel_Wait_Until 73
CardFrame
Call

143

connections 4
power supply 4
Cards
device numbers 5
Channels 2930, 3537
changing states of 3739
input function 35
momentary 42
momentary mutually exclusive 43
mutually exclusive 43
mutually exclusive latching 44
mutually exclusive toggling 4445
output function 37
specifying ranges 42
status 41, 43, 44
Clear_Buffer 110
Clearing
buffers 110
Comments 2526
Communications
baud rate 13
configuring 13
pass-thru 14
problems 5
terminal emulator 13
Communications menu 13
Configure... 13
Pass thru... 14
Receive file... 14
Send file... 14
Terminal emulator... 13
Compiled code. See Executable code
Compiler
messages 11
options 11
warnings 11
Compiling 8
comments 25
include files 127
Computer 3
Conditional statements. See Boolean
expressions
Connecting
levels 8687
Constants
assignment of unlike types 11
defining 3132
strings 94
Create_Buffer 107

144

Create_Level 82
Creating
buffers 107108

D
Date 74
Day 74
Define_Call 117
and System_Call 129
local variables 123
parameters 124
storing in separate section of memory
11
unused 11
Define_Connect_Level 8687
Define_Constant 31
identifiers 26
Define_Device 30
identifiers 26
Define_Mutually_Exclusive 43
Define_Program 33
Define_Start 33
and Create_Buffer 107
and Create_Level 83
and Define_Call 117
and To 33, 38
setting variables 32
Define_Variable 32
array string lengths 96
arrays 91
identifiers 26
integer arrays 100
Defining
arrays 9192
constants 3132
devices 3031
latching 4243
momentary mutually exclusive 4344
mutually exclusive latching 44
mutually exclusive toggling 4445
subroutines 117
variables 32
Delays. See Wait
Device numbers 5, 30
receivers 5
Touch Panel 5
Device-channel 2930

Index

direct assignment 39
Devices
defining 3031
Diagnostics menu 12
Compare current devices... 12
Show current devices... 12
Show current versions... 13
Watch variables... 13
DIP switches
settings 5
Direct assignment 39
using a Boolean expression 64
Directories
changing 9
Disk files 3, 8, 15
Double periods 42
Double quotes
with string expressions 94
with strings 94

E
Else 5859, 59. See also If
Equipment 3
Error window 20
Errors
parameter mismatch option
viewing 20
Executable code 8
sending 10

F
Feedback
direct assignment 39
grouping statements 47
last button pressed 43
programming 4647
File menu 7
Change dir... 9
Compile 89
Exit 9
New.. 8, 29
Open include.. 8
Open.. 78
Print.. 9
Save 8
Version... 9
Find_String 104

Index

11

Finding
strings

104

G
Get_Buffer_Char 108
Get_Timer 7374, 85
Global variables 123

H
Help menu 15
HELP.OVL file 15

I
Identifiers 26
constants 31
guidelines 26
If 58
associating with Else 60
nesting 5960
If...Else 5859
default statement 59
If...Else If 59
Include 127
files 127
opening files 8
saving files 8
Indenting 23
Index values 92
Input changes 35
and While keywords 78
keywords 3537
Installation
AXCESS program 3
Instance numbers 131
Integer 100
arrays 100
Itoa 101
Itohex 102

K
Keywords

24

145

L
Latching 42
defining 4243
status 42
Left_String 103
Length_String 96, 109, 112
Levels 8184
and bar graphs 86
connecting 8687
creating 8284
preset 8586
reading 85
sending 86
Library files 129
Local variables 123124
Local_Var 123
Long_While 78
Loops 7778
Lower_String 106
Lowercase 105

M
Mainline 3334. See also Define_Program
and buffers 108
and Push_Channel 37
and Push_Device 36
and Release_Channel 37
and Release_Device 36
and Wait 71
and Wait_Until 72
and While 77
Master Card
CardFrame slot 4
executing mainline 33
LED 6
sending compiled program to 10
sending source code to 9
verifying program 10
Medium_While 78
Menus 715
AX File menu 912
Communications menu 13
Diagnostics menu 12
File menu 7
Help menu 15
Messages
setting options for 11

146

Mid_String 103104
Modems
transferring files 14
Momentary 42
Momentary mutually exclusive
defining 4344
Monitors 4
Mutually exclusive 43
double periods 43
latching 44
momentary 4344
parentheses 43
toggling 4445
variables 61
Mutually exclusive latching
defining 44
Mutually exclusive toggling
defining 4445

N
Name mangling 131
Nesting
If statements 5960
Waits 70
NEW.OVL file 8
Not 66

O
Off 38
On 38
Operators 24
Or 66
Output changes 37
and channel status 41
direct assignment 39
keywords 3839
Output channels 41
physical part 41
status 41

P
Parameters 124126
mismatch error 11
reassignment 125126

Index

Parentheses
and If 58
Call parameters 124
mutually exclusive set 43
Passwords 11
Pause_All_Wait 72
Pause_Wait 71
Presets
creating 8586
Printing 9
configuring 13
Program execution sequence 24
and Waits 67
Program files
compiling 8
creating 8
deleting 8
information on 7
naming 8
opening 7
printing 9
saving 8
Program spacing 23
Program_Name
and include files 128
and program files 8
and System_Call 129
Pulse 39
and Wait 70
Push 36
and feedback 47
and To 38
compound statements 24
finding 19
inserting 19
simulated 20
Push window 5, 19
and Define_Device 31
Push_Channel 37
Push_Device 36

Q
Question marks 75
Quotation marks
with strings 94

Index

R
README file 3
Receiving
strings 107
Relational expressions. See Boolean
expressions
Release 36
Release_Channel 37
Release_Device 36
Remove_String 104
Removing
strings 104
Reserved words 26
Restart_All_Wait 72
Restart_Wait 72
Retrieving
source code 910
Right_String 103

S
S19 files 10
Search and replace 18
Select groups
Mutually exclusive variable method
6163
variable assignment method 6365
Select...Active 6061
default statement 61
Send_Command 93
Send_Level 86, 87
Send_String 98
Sending
arrays 9899
levels 86
program to Master Card 10
Source-send option 10
strings 9899
Server Card
DIP switch settings 5
Set_Length_String 97, 110, 112
Set_Pulse_ Time 39
Set_Timer 73, 85
Simulated button press 20
Single quotes
and case-sensitivity 105
with Include files 127

147

with strings 94
with subroutines 117
Source code 8
retrieving from Master Card 9
sending 10
Startup code 33
Statements 2425
compound 2425
String expressions 9495
Strings 91100, 94
array string lengths 96
assigning to a two-dimensional array
112
assigning to an array 94, 96
conversion keywords 101102
finding 104
receiving 107
removing 104
sending 9899
setting upper/lower case 106
string literals 94
Subroutines 117122
calling 118
defining 117
restrictions on names 117
Substrings. See Arrays: manipulation
keywords
Symbols 27
System_Call 129
from the factory 130

Touch Panels
bar graphs 86
device numbers 5
levels 86
Transferring files 14
Two-dimensional arrays 111114
retrieving values from 113114
storing values in 112

U
Upper_String 106
Uppercase 105

V
Variable Watch window 13
Variables
arrays 91
as output channels 38
assignment of unlike types
defining 32
local 123124
mutually exclusive 61
scope 123
unused 11
Verifying Master Card program
Versions
AXCESS program 9
firmware 13
Video monitors 4

11

10

T
W
Text editor 8, 1720
blocking 1820
commands 17
exiting 9
insert/overwrite mode 18
search and replace 18
Time 74
Timer keywords 7374
To 3839
and Define_Start 33, 38
and Wait 38
momentary channels 42
Total_Off 38
and mutually exclusive groups

148

Wait

67
and Pulse 70
and To 38, 70
cancelling 7172
list 67
multiple Waits 6970
naming 71
nesting Waits 70
pausing 7172
problems in library files
restarting 7172
special uses 70

132

43

Index

Wait_Until 72
list 72
misusing 7273
naming 73
problems in library files 132
removing 73
Warnings
assignment of unlike types 11
Define_Call is not used 11
turning on and off 11
variable is not used 11
While 7778
timeout 78
Wildcard characters 75

X
Xor

Index

66

149

You might also like