AXCESS Programming Language
AXCESS Programming Language
AXCESS Programming Language
,QVWUXFWLRQ#0DQXDO
$0;#6RIWZDUH#3URJUDPV
LIMITED WARRANTY
LIMITED WARRANTY. AMX warrants that the SOFTWARE will perform substantially in accordance with the accompanying written materials for a period of ninety (90) days from the date of receipt. Any implied warranties on the SOFTWARE and hardware are limited to ninety (90) days and one (1) year, respectively. Some states/countries do not allow limitations on duration of an implied warranty, so the above limitation may not apply to you. CUSTOMER REMEDIES. AMX's entire liability and your exclusive remedy shall be, at AMX's option, either (a) return of the price paid, or (b) repair or replacement of the SOFTWARE that does not meet AMX's Limited Warranty and which is returned to AMX. This Limited Warranty is void if failure of the SOFTWARE or hardware has resulted from accident, abuse, or misapplication. Any replacement SOFTWARE will be warranted for the remainder of the original warranty period or thirty (30) days, whichever is longer. NO OTHER WARRANTIES. AMX disclaims all other warranties, either expressed or implied, including, but not limited to implied warranties of merchantability and fitness for a particular purpose, with regard to the SOFTWARE, the accompanying written materials, and any accompanying hardware. This limited warranty gives you specific legal rights. You may have others which vary from state/country to state/country. NO LIABILITY FOR CONSEQUENTIAL DAMAGES. In no event shall AMX be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or any other pecuniary loss) arising out of the use of or inability to use this AMX product, even if AMX has been advised of the possibility of such damages. Because some states/countries do not allow the exclusion or limitation of liability for consequential or incidental damages, the above limitation may not apply to you. U.S. GOVERNMENT RESTRICTED RIGHTS The SOFTWARE and documentation are provided with RESTRICTED RIGHTS. Use, duplication, or disclosure by the Government is subject to restrictions as set forth in subparagraph (c)(1)(ii) of The Rights in Technical Data and Computer Software clause at DFARS 252.227-7013 or subparagraphs (c)(1) and (2) of the Commercial Computer Software--Restricted Rights at 48 CFR 52.227-19, as applicable. Manufacturer is AMX Corporation, 11995 Forestgate Drive, Dallas, TX 75243. If you acquired this product in the United States, this Agreement is governed by the laws of the State of Texas. Should you have any questions concerning this Agreement, or if you desire to contact AMX for any reason, please write: AMX Corporation, 11995 Forestgate Drive, Dallas, TX 75243.
Table of Contents
Introduction............................................................................. 1
Overview Programming with AXCESS What's in this Manual Required Equipment Installation Software AXCESS/AXCESSX Included AXCESS documentation Installing AXCESS from disks Installing AXCESS from the AMX Control Disc (CDROM) Integrated Setup Setup Options Launching AXCESS If AXCESS was installed from the AMX Control Disc (CD-ROM) If AXCESS was installed from 3.5 disks 8 8 7 7 7 8 1 1 1 5 5 5 6 6
Table of Contents
Version Options Exit AX File Menu Retrieve Send Source-send Verify Create S19 file Send w/password Options Diagnostics Menu Show current devices Compare current devices Show current versions Watch variables Communications Menu Terminal emulator Configure Send file Receive file Pass thru Help Menu Help on Help Editor Keywords Sample Program AXCESS Cards AXCESS Boxes AXCESS panels & ... NEW_CALLS Master Messages
18 18 19 19 20 20 21 21 21 21 22 23 23 23 24 24 25 25 25 26 26 26 27 27 27 27 28 28 28 28 28 29
ii
Table of Contents
Compilation Errors
35
Table of Contents
iii
Off Total_Off To Min_To Pulse Direct Assignment Putting Input and Output Together
59 59 60 60 60 61 61
Channel Characteristics....................................................... 63
Overview Parts of an Output Channel The Device-Channel Concept Defining Latching Mutually Exclusive Defining momentary mutually exclusive Defining mutually exclusive latching Defining mutually exclusive toggling Putting it all to work Programming Feedback Grouping feedback statements Define_Combine Device and Channel Keywords Device_ID Do_Push Do_Release Get_Pulse_Time Master_Slot Set_Pulse_Time Define_Combine Define_Latching Define_Mutually_Exclusive Define_Toggling The Variable Assignment Method 63 63 63 64 65 65 66 67 67 69 70 71 72 72 73 73 73 74 74 74 75 75 75 76
iv
Table of Contents
String Lengths Array manipulation keywords Left_String Right_String Mid_String Find_string Remove_string Uppercase vs. Lowercase Setting uppercase and lowercase Sending Strings Array Keywords Find_String Left_String Length_String Mid_String Remove_String Right_String Set_Length_String String Keywords Redirect_String Send_Command Send_String
88 91 91 92 92 92 93 94 94 95 96 96 96 97 97 97 98 98 98 98 99 99
Table of Contents
Changing and Comparing Values Arithmetic Operators Relational Operators True and false Logical Operators Bitwise Operators Abbreviations Precedence Among Operators Operator Keywords Logical operator keywords And (&&) Not (!) Or (||) XOR (^^) Bitwise operator keywords BAND (&) BNOT (~) BOR (|) BXOR (^)
111 111 112 113 114 116 117 117 119 119 119 120 120 120 121 121 121 121 121
vi
Table of Contents
The If...Else Set of Statements The If...Else If Set of Statements Nesting The Select...Active Statement More Boolean Operators Reading a Boolean Expression Table Boolean Keywords Select...Active Else If
132 133 133 135 136 136 138 138 139 139
Table of Contents
vii
viii
Table of Contents
Debugging........................................................................... 191
Overview Introduction Types of Errors Compilation Errors and Warnings (w) Cannot assign unlike types (w) Define_Call is not used (w) Integer applies to arrays only (w) Long_While within While (w) Possibly too many nested levels (w) Variable is not used Run-time errors Using AMX BUG Bad assign 2dim... Bad assign Call... Bad element assign... Bad Off... Bad On... Bad To... Bad re-assign Call... Bad run token Bad Set_Length... Bad While Tracking down your errors Tracing program flow Viewing Variables 191 191 191 191 192 193 193 193 193 193 193 194 194 194 194 194 195 195 195 195 195 195 197
Table of Contents
ix
Conditional compile nesting too deep Constant type not allowed Define_Call must have a name Define_Call name already used Device values must be equal Duplicate symbol Evaluation stack overflow Evaluation stack underflow Identifier expected Identifier is not an array type Include file not found Invalid include file name Library file not found Maximum string length exceeded Must be char array reference Must be integer reference Out of memory Parameter mismatch in Call Program_Name must be on line 1 Push/Release not allowed within Push/Release Push/Release not allowed within Wait Push_Channel not allowed within Wait Release_Channel not allowed within Wait Push_Device not allowed within Wait Release_Device not allowed within Wait String constant expected String constant never ends, EOF encountered String literal expected Subroutine may not call itself Syntax error System_Call name not same as Program_Name in <file> This variable type not allowed To not allowed within Define_Start To not allowed within mainline To not allowed within Release To not allowed within Wait Too few parameters in Call Too many include files Too many parameters in Call Type mismatch in function call
199 200 200 200 200 200 200 200 201 201 201 201 201 201 201 201 202 202 202 202 202 202 202 202 202 202 202 203 203 203 203 203 203 203 203 203 203 204 204 204
Table of Contents
Undefined identifier Unmatched #End_If Unrecognized character in input file Use System_Call [instance] name Variable assignment not allowed here Wait not found
Index.................................................................................... 241
Table of Contents
xi
xii
Table of Contents
Introduction
Overview
The AXCESS system is a microprocessor-based control system capable of controlling both simple and complex devices, giving 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 Control System, and not much memory is needed. Even complex AXCESS programs can be handled by an average laptop computer. Once the system is programmed, the computer is needed only for diagnostic tests and for loading or saving programs.
Getting Started Describes how to set device numbers for the devices on AXlink, and lists recommended device numbers. It also describes how to force the AXCESS Control System into monochrome mode (for use with LCD or plasma-type monitors), how to connect the system, and describes the blinking LED status indicator. Using the Menus Describes the AXCESS menu structure.
Introduction to AXCESS
Text Editor Describes how to use the text editor and covers related concepts such as blocking, search and replace, push windows, simulated button press and compilation errors. Simply the Basics Describes how to begin creating AXCESS programs and describes the basic ground rules of AXCESS programming. It also covers the device-channel concept, describes the different sections that comprise an AXCESS program, shows how AXCESS executes a program, and describes basic input/output functions and simple feedback. Using Mainline Describes mainline, checking the WAIT and WAIT_UNTIL lists, turning off expired PULSE s, handling Central Controller RS-232 communications, and updating the AXlink communications bus. Definition Sections Describes how to write an AXCESS program using definition sections. It includes explanations of programming concepts such as defining devices, constants, and variables. It describes startup code, mainline, and lists definition keywords. Using Input and Output Describes how to use input and output, channels, direct assignments, and putting input and output together. It includes explanations of the concepts involved and examples of AXCESS programming code. Channel Characteristics Describes channel characteristics and includes explanations of channel concepts, and examples of AXCESS programming code. It includes information on the parts of an output channel, device-channel, defining latching, mutually exclusive, programming feedback, and lists channel keywords. Arrays and Strings Describes how to define arrays, how to access and store arrays, and how to use strings. It includes explanations of concepts involved, lists array and string keywords, and includes example AXCESS programming code. Creating Levels Describes how to create levels. It includes explanations of the concepts involved, lists levels keywords, and includes example AXCESS programming code.
Introduction to AXCESS
Using Levels Describes how to read levels and bargraphs, how to make a preset, and how to connect levels. It includes explanations of the concepts involved and example AXCESS programming code. Operator Types Describes how to use operator types. It shows how to change and compare values, describes the various types of operators, and lists operator keywords. It includes explanations of the concepts involved and example AXCESS programming code. Variable Types and Conversions Describes how to use variable types and conversions, ASCII codes, integer arrays, the variable assignment method, and contains a list of variable and conversion keywords. It includes explanations of the concepts involved and example AXCESS programming code. Two-Dimensional Arrays Describes how to use two-dimensional arrays, explains storing and retrieving values, grouping data, finding strings, removing strings, and uppercase vs. lowercase. It includes explanations of the concepts involved, and example AXCESS programming code. IF and the Boolean Expressions Describes how to use the IF statement, Boolean expressions, nesting, the SELECT...ACTIVE statement, and lists Boolean keywords. It includes explanations of the concepts involved, and example AXCESS programming code. While Keywords Describes using the WHILE keywords, including explanations of the concepts involved, and example AXCESS programming code. Using Buffers Describes how to create and use buffers, and lists buffer keywords. It includes explanations of the concepts involved, and example AXCESS programming code. Waits and Timer Keywords Describes how to use WAITS and TIMER keywords, explains the wait list, and lists WAITS and TIMER keywords. It includes explanations of the concepts involved, and example AXCESS programming code.
Introduction to AXCESS
Using Time, Date, and Day Describes how to use TIME , DATE and DAY keywords, and lists the keywords. It includes explanations of the concepts involved, and example AXCESS programming code. Using Subroutines Describes defining and calling subroutines. It includes explanations of the concepts involved, and example AXCESS programming code. Include Files and System_Calls Describes how to use INCLUDE files and SYSTEM_CALLS to manage large programs, and lists INCLUDE files and SYSTEM_CALLS keywords. It includes explanations of the concepts involved, and example AXCESS programming code. Pre-Processor Statements Describes how to use pre-processor statements, including INCLUDE files and SYSTEM_CALLS. It includes explanations of the concepts involved, and example AXCESS programming code. Debugging Describes debugging your AXCESS program, describes types of errors, and lists compilation errors and warnings, and run time errors. It also contains information on tracking down your errors and viewing variables. Compiler Error Messages Lists and describes compiler error messages. The External_Control Protocol Describes how to control AXCESS from the outside using EXTERNAL_CONTROL protocol. It includes explanations of the concepts involved, and example AXCESS programming code. Appendix Contains a listing of all the reserved identifiers you can use with the AXCESS program, a ASCII code chart, which lists hexadecimal values for all ASCII characters, and a listing of abbreviations used in the chart. Accessing the AMX BBS Describes how to use the Worldgroup program to access the AMX BBS. Technical Support Gives the phone numbers to call for AMX technical support. Glossary Contains keywords and descriptions of terms used throughout this manual.
Introduction to AXCESS
Index Lists topics, key words, and terms used throughout this manual.
Required Equipment
The following equipment is required to operate the AXCESS Control System: IBM-compatible computer with: - 3.5-inch disk drive or CDROM drive - Minimum of 512K of memory - MS-DOS version 2.0 or higher - Serial or bus mouse AXCESS software CardFrame AXC-EM Central Controller AMX Programming Cable
Installation Software
AMX provides the necessary software on the AMX Control Disc (CD-ROM), or on two 3.5-inch disks. The CD (or disks) contain a number of files: the editor/compiler program, support files, pre-written block files, code library files, and documentation files. For up-to-date information on the software, insert the AMX Control Disc in your CDROM drive, or insert disk 1 into your floppy disk drive, and open the Readme.TXT file.
AXCESS/AXCESSX
There are two versions of the AXCESS program: "AXCESS" and "AXCESSX". They are identical, except that AXCESSX uses extended memory. Typically, you would always use AXCESSX, to take advantage of your computer's extended memory. AXCESS is designed for computers that do not have extended memory.
Introduction to AXCESS
AXCHAN.TXT Lists channels for AXCESS devices. AXPOWER.TXT Lists power consumption for devices that can be connected to the AXlink bus (12V DC). CAMCALLS.TXT Lists camera system calls. NEWCALLS.TXT Contains the most current list of new system calls. README.TXT Lists changes and new features since the last release of AXCESS/AXCESSX. SNDCMD.TXT Contains the most current list of send commands. DEVICE.TXT Lists device ID numbers for AXCESS devices. This file is located in AMXTOOLS\AMXDOS\SOFTWARE\Deviceid.TXT . It is available after the AXCESS software has been installed.
Insert disk 1 into your floppy disk drive. In the File Manager (or Explorer in Windows 95), double-click INSTALL.BAT from the directory window for your disk drive (usually A or B). Follow the instructions that appear on your screen.
3.
Introduction to AXCESS
Insert the AMX Control Disc into the CD-ROM drive. In the File Manager (or Explorer in Windows 95), double-click SETUP.EXE from the directory window for your CD-ROM drive. Follow the instructions that appear on your screen
3.
Integrated Setup
Run SETUP.EXE from the root directory to install the following:
AXCESS/AXCESSX AXWire AXCENTWire IRLIB/IRLIBX OLDesign OpenAXCESS PCDesign PCTouch SKDesign SOFTROM TPDesign TPDesign3 TPDOC/TPDOCX VTInterface
Setup Options
The setup wizard allows you to choose one of the following installations: TYPICAL Installs all applications listed above, which requires the AMX Control Disc. COMPACT Installs minimum files necessary to run applications, and requires the AMX Control Disc. CUSTOM Installs all selected applications to the hard drive, which requires the Control Disc CD-ROM.
Introduction to AXCESS
Launching AXCESS If AXCESS was installed from the AMX Control Disc (CD-ROM)
To launch the AXCESS program, click on the Windows start menu and select AMX Control Disc. This opens a listing of all files that were installed from the AMX Control Disc. In this list, select AXCESSX to launch the program.
Introduction to AXCESS
Getting Started
Overview
This section describes how to set device numbers for the devices on AXlink, and lists recommended device numbers. It also describes how to force the AXCESS Control System into monochrome mode (for use with LCD or plasma-type monitors), and how to connect the system, and describes the blinking LED status indicator.
Device Numbers
Device Number A unique number from 1 to 255 designating each device connected to AXCESS via AXlink
Each device on AXlink must have a unique device number. For card cages, the device number of a card is set by the slot number and the DIP switch setting on the Server Card. For box devices, the address is set with a dipswitch on the device itself. 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. The card in slot 3 is the Server Cards DIP switch setting plus 2. This pattern continues until slot 16. For example, if the DIP switch on the Server Card is 17, then 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 device has 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. Figure 1 shows the recommended device numbers for AMX CardFrames and other devices. These numbers are only for the card in slot 1 of each CardFrame; for each consecutive device, add one to the appropriate number. We recommend that all panels, infrared (IR) receivers, and radio frequency (RF) receivers start on device number 128, and that the number increase with each device. All AXB-boxes start at device number 96, and increase with each device. The AXB-FD (floppy disk drive) starts at 127 and decreases with each AXB-FD. When numbering panels, start with RF and IR, then SoftWire panels such as the AXU-MSP8 or AXUSPL4, and then touch panels. Two-way RF, wireless Wave systems should start at device number 192.
Getting Started
Recommended device numbers DIP Switch Settings CardFrame # or device type 1 2 3 4 5 6 Boxes (AXB-XXX) AXB-FD Panels (AXT-XXX and AXM-XXX) Wave system (2way RF) Device # 1 17 33 49 65 81 96 127 128 192 1 1 1 1 1 1 1 0 1 0 1 2 0 0 0 0 0 0 0 1 0 1 3 0 0 0 0 0 0 0 1 0 0 4 0 0 0 0 0 0 0 1 0 0 5 0 1 0 1 0 1 0 1 0 0 6 0 0 1 1 0 0 1 1 0 0 7 0 0 0 0 1 1 1 1 0 0 8 0 0 0 0 0 0 0 0 1 0
Video Monitors
The AXCESS Control System automatically detects whether your monitor is color or monochrome. However, if your monitor reports being a CGA monitor, but has no color (such as LCD or plasma-type monitors), you must force the AXCESS Control System into monochrome mode. To do this, launch AXCESS by typing:
C:\AMXTOOL\AMXDOS\AXCESS> AXCESS /B
At this point, the AXCESS program should be installed on your computer. The next step is to connect the system. To supply power to the CardFrame, plug in the power supply from the power outlet to the AXCESS Control System. The green two-pin Phoenix connector should be plugged into the lower right corner of the back of the CardFrame. Next, the AMX Programming Cable must be connected from the communications port of the computer to the nine-pin connector on the Central Controller. Figure 2 lists common solutions to resolve communication problems.
10
Getting Started
Communications problem resolutions Cause The baud rate of the AXCESS Control System is different than that of the Central Controller. Resolution The AXCESS Control System baud rate can be found with the Configure... option in the Communications menu, and an explanation of setting the Central Controller baud rate is in the AXC-EM instruction manual. Set both to the same setting. The AXCESS Control System com port number can be found with the Configure... option in the Communications menu. Make sure it matches the correct Central Controller communications port. The AXCESS Control System communications settings can be found with the Configure... option in the Communications menu, and an explanation of changing these settings for the Central Controller is in the AXC-EM instruction manual. Both should be set to eight data bits, no parity, and one stop bit. Inspect the cables pinout. The cable connection chart in the AXC-EM instruction manual should help you determine the solution
The communications port number of the AXCESS Control System is different than that of the communications port in which the Central Controller cable is plugged. The communications settings of the AXCESS Control System are different than that of the Central Controller.
Getting Started
11
12
Getting Started
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 option and press <Enter> to select it. To exit out of the menu and return to the text editor, press the <Esc> key.
13
File Menu
Press <F1> to enter the File menu, shown in Figure 3. The File menu allows you to open, create, save, or print an AXCESS program file or include file. This menu also has commands for compiling your AXCESS program, changing the current directory, and viewing the current version information. Each File menu option is described below.
Figure 3 File menu
Open
This option lists existing AXCESS program files (files with the DOS extension .AXS) in the current directory, as shown in Figure 4. To open a file, move the cursor down with the arrow keys and select the file by pressing <ENTER>. To quickly locate a file, press the first letter of the filename and the cursor will jump to the filenames that begin with that letter. Once you are in the text editor, changes can be made to your program.
Figure 4 Open option of the File menu
14
The following functions are available with the Open option. They appear at the bottom of the screen when you are in this menu. <F1> (File information): Displays basic information about the highlighted file. This information includes the filename, date and time the file was last modified, and the file size. <F2> (Delete file): Allows you to delete an unwanted file. Highlight the file to be deleted, and press <F2>. AXCESS will then ask you if you are sure you want to delete the file. <F3> (Rename file): Allows you to change the name of a file you highlight. <F9> (Open a non-program file): Allows you to open any text file in the editor. It does not have to be a file related to AXCESS. You can use this function 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, as shown in Figure 4. An include file is an AXCESS program file which 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. AXCESS loads the file New.OVL (which must be present in the current directory), and inserts a few headings and comments to help you in your programming as shown in Figure 5.
15
With a new file open, the editor is now ready for you to begin a new program.
Save
This option saves the currently open file. AXCESS prompts you to name your file, as shown in Figure 6. 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>.
Figure 6 File Save prompt
To save a new file as an include file, instead of pressing <Enter> after typing in the filename, press the <F1> key. Conventional DOS filenames consist of a maximum of eight characters ,not including the extension. AXCESS allows a maximum of 57 characters, and spaces are acceptable, to allow greater flexibility in naming your file. 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 recommended that you save often and keep a backup copy of all programs. Pressing <Ctrl-S> also activates the Save command.
16
Compile
This option compiles the source code into executable code. Source code is another name for the AXCESS program that you type and edit, and 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 Central Controller, use the Send option in the AX File menu. The Compile window is shown in Figure 7.
Figure 7 Compile window
This feature also tells you if the AXCESS system is unable to compile your program. If this is the case, an error list appears. The cursor appears at the first error. For information about correcting these errors, refer to the Text Editor section. 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 does not activate 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 to which the printer cable is connected. The Print window is shown in Figure 8.
Figure 8 Print Window
17
Change dir
This option allows you to change the working directory. The working directory is the directory that you will load files from and save files to. Selecting this option opens the Change Directory window that allows you to map the DOS path to a different directory, as shown in Figure 9.
Figure 9 Change Directory window
After a new directory path is entered, AXCESS rebuilds its lists of available files for the new directory.
Version
This option opens a window that shows the current version of the AXCESS PC program you are running, plus information on the amount of memory available, as shown in Figure 10.
Figure 10 Change Directory window
Options
This option allows you to set color highlighting for certain parts of your program (syntax highlighting). Use this feature to make your program easier to read and to make particular parts of the program easier to visually locate. Selecting this option opens the File Option window, shown in Figure 11.
18
Press the Return key to toggle Syntax Highlighting on/off. When syntax highlighting is on (an X appears in the Enable box), the highlighting options are available. To highlight a type of syntax in your program, select the syntax type from the list, then select the desired highlight color. Press ESC to close this window. The highlights that were specified will now appear in your program. To save the highlighting in the program, press F10. The highlights will appear every time the file opened. To remove all highlighting, toggle the Enable box off.
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 Menu
Press <F2> to enter this menu. The AX File menu, shown in Figure 12, allows you to transfer both the executable code and the source code of a file to the Central Controller. Also use this option to retrieve source code from the Central Controller.
Figure 12 AX File menu
19
Retrieve
This option retrieves the source code from the Central Controller, if possible. If you cannot retrieve the source code, the source code may not have been saved. There are two possible reasons why the source code was not saved in the Central Controller: There was not enough memory in the Central Controller to store the source code. The Source-send option is toggled off. For detailed information on the Sourcesend option, see Source-send later in this section. Always save the source code on either the hard drive or a floppy disk. Do not rely on the Central Controller to keep all of the source code in memory.
Send
Downloading The sending of data from computer to a device (such as a Central Controller).
This option sends the current executable code to the Central Controller or other devices on the AXlink bus. If possible, the source code is also stored in Central Controller or data device memory. If there is not enough room in the Central Controller for the program, AXCESS will stop downloading and give you a warning. When this happens, try sending 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 Central Controller will not be the same as the file in the text editor, but instead the last compiled code. Pressing <Ctrl-P> also activates the Send command.
Uploading The sending of data from a device (such as a Central Controller) to a computer.
20
Source-send
Note It is a good idea to leave this option turned on. The only reasons to turn the Sourcesend option off are to speed up downloading time during program development, or because you know the source code is too large to send.
This option toggles on and off. The current status is listed at the right of the Sourcesend option. With Source-send on, AXCESS will download the executable code and the source code to the Central Controller or data device when you select the Send option, memory permitting. This allows the Retrieve option to reload the source code from the Central Controller. If Source-send is off, AXCESS downloads only the executable code, which cannot be retrieved from the Central Controller.
Verify
As a safeguard, this option checks to see if your compiled program is the exactly the same as the one in the Central Controller. It is possible that the Central Controller would not have the latest compiled version of your program. If your compiled program fails this test, recompile the program and send it to the Central Controller.
Send w/password
Warning If the password is forgotten there will be no way to retrieve the source code from the Central Controller, so be careful not to forget it!
This option is identical to the Send command except that it also allows you to specify a password which will be needed to retrieve the program in the future. This password can only be numerical, using up to four digits. No alphabetic characters are allowed in the password. When a password-protected program is retrieved from a Central Controller, AXCESS prompts 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 Central Controller so that only authorized persons can retrieve it.
21
Options
This command opens the Option window (Figure 13), where you can set various options concerning compile-time warning messages, error messages and other compiler options. The options are divided into Compiler messages and Compiler Options.
Figure 13 Option window
Press the return key to toggle these selections on/off. The compiler messages are described below: Parameter mismatch: This option enables errors when a parameter of the wrong type is passed to an AXCESS function Assignment of unlike types: This option enables warnings when a variable or constant of one type is assigned to a variable of a different type Variable is not used: This option enables warnings when a variable declared anywhere in the program is not actually used DEFINE_CALL is not used: This option enables warnings when a DEFINE_CALL subroutine declared in the program is not actually used The Compiler Options section of this window has only one option to turn on or off: Separate DEFINE_CALL list. Compiling with this option on causes all DEFINE_CALL subroutines to be stored in a separate section of the Central Controller 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.
22
Diagnostics Menu
Press <F3> to open the Diagnostics menu, shown in Figure 14. The Diagnostics menu allows you to view and compare the devices on AXlink to the devices defined in the current program stored in the Central Controller.
Figure 14 Diagnostics menu
23
Firmware The software that resides in the EPROMs in many of the AXCESS devices. This software makes these devices operate. Figure 17 Show Current Versions window
Watch variables
This option opens the Variable Watch window, which allows you to observe the contents of selected variables while the program is running. When this option is selected, AXCESS prompts you for the type of variable to watch.
24
Communications Menu
Press <F4> to open the Communications menu, shown in Figure 18. This menu lets you communicate directly to the Central Controller. 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.
Figure 18 Communications menu
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. Anything that is typed 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 Central Controller, modems or other RS-232 devices, and to debug RS-232-controlled devices. 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. Select Configure to open a window listing the choices, as shown in (Figure 19). With the arrow keys, move the cursor next to the item you need to change. Pressing <Enter> selects that item. Selected items are indicated by a check mark
Figure 19 Configure window
25
Send file
This option is not the same as the Send option in the AX File menu. Instead, it allows you to transfer files between two computers through a connecting serial cable or modem. Both computers must be running the AXCESS program to complete the transfer.
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 contains the file to be sent. Select Receive file on the other computer to begin transferring the 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, as shown in Figure 20.
Figure 20 Pass Thru window
When you have selected two communications ports, press <F10> to establish 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.
26
Help Menu
Note For this menu to work, the file HELP.OVL must be present in the current directory. Figure 21 Help menu
Press <F6> to open the Help menu, shown in Figure 21. The Help menu provides brief definitions of keywords, a short sample program, a list of AXCESS cards, AXCESS boxes and AXCESS panels. The help menu also contains a list of SYSTEM_CALL s and Master (error) Messages.
Help on Help
Contains brief instructions on how to use the Help menu. Use the cursor keys to highlight a topic. Press Enter to select. Press <F10> to back up one level.
Editor
The Editor menu item contains two options in a sub-menu: Edit Concepts Contains a brief description of the text editor, and related concepts including the status bar, insert/overwrite mode, and text blocking. Refer to the Text Editor section for detailed information on the text editor. Edit Keys Contains a list of commands used in the editor. Refer to Editing commands in the Text Editor section for a list of the editor commands.
Keywords
Contains brief descriptions of all AXCESS keywords. Keywords include TIME , DATE and DAY keywords, INCLUDE_FILE and SYSTEM_CALL keywords, and VARIABLE and CONVERSION keywords. For a complete listing of AXCESS keywords, refer to Section A of the Appendix.
27
Sample Program
This menu item opens a sample AXCESS program. The purpose of the "Sample" program is to show the correct structure and format of a basic AXCESS program.
AXCESS Cards
Contains a list of AXCESS cards.
AXCESS Boxes
Contains a list of AXCESS boxes.
NEW_CALLS
Contains a list of NEW_CALL s, categorized by type, as shown in Figure 22:
Figure 22
NEW_CALLS listed by type in
NEW_CALLS Generic button calls Audio Calls CAMERA Calls CASSETTE Calls CD Calls DAT Calls DVD Calls Joystick Calls LASER DISC Calls PRODIGY Calls MISCELLANEOUS Calls SLIDE Calls SCREEN Calls SWITCHER Calls VCR Calls 1-5 VCR Calls 6-10 VOLUME Calls Video Proj Calls OLD to NEW
For a full listing of NEW_CALLS , refer to Newcalls.TXT, included on the AMX Control Disc. It is located in AMX Control Disc/Axcess Docs/Axcess Docs folder. For the most up-to-date listing of SYSTEM_CALLS , refer to Newcalls.TXT, available on the AMX BBS. For information on accessing the AMX BBS, refer to Worldgroup Readme
28
on the AMX Control Disc, or refer to the Accessing the AMX BBS section of this manual.
Master Messages
Contains a list of Master Messages, categorized by type, as shown in Figure 23:
Figure 23 Master Messages Master Messages To/On/Off Define Call And Others Dim Array Dim Array General
29
30
Text Editor
Overview
This section describes how to use the text editor and covers related concepts such as blocking, search and replace, push windows, simulated button press and compilation errors.
Editor Basics
The AXCESS system provides a simple text editor for manipulating text in your programs. Whenever a menu is not displayed on the screen, the editor is active. Cursor movement around the screen is controlled by the arrow keys. <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> jumps to the beginning of the program, and <CtrlEnd> jumps to the end.
If you do not have an extended keyboard, make sure the <Num Lock> feature on the keyboard is off so you can use the keypad instead.
Text Editor
31
Editing commands
Figure 24 lists the commands used in the editor.
Figure 24 Editing commands Editing commands Command
<ALT-Fx (1-12)> <ALT-B>
Function Return to bookmark Matching brace Copy block Delete block Find Push statement Get block from disk Insert Push statement Go to line Block entire line Move block Go to next error Go to previous error Search and replace text Search for text Unmark block Print block Write block to disk Delete to end of line Delete current line Undo last delete
Command
<CTRL-Fx (1-12)> <CTRL-A>
Function Set bookmark Simulate pressing button Compile Toggle error window on/off Open File Send program to master Go to terminal Clear stop watch Exit Shift block left Shift block right Go to beginning of program Go to end of program Go to beginning of current line Go to end of current line Go up one screen of text Go down one screen of text Toggle insert/overwrite mode Start/stop stop watch
<ALT-C> <ALT-D>
<CTRL-C> <CTRL-E>
<ALT-F> <ALT-G>
<CTRL-O> <CTRL-P>
<ALT-R>
<CTRL-END>
<ALT-S>
<HOME>
<ALT-U>
<END>
<ALT-O>
<PG UP>
<ALT-W>
<PG DN>
<ALT-Z>
<INS>
<ALT-MINUS> <ALT-EQUAL>
<CTRL->
Press the <Ins> key to toggle the insert/overwrite mode. In insert mode, every character you type is inserted at the current cursor position. In overwrite mode, any character under the cursor is overwritten with the new one.
32
Text Editor
If you would like to delete an entire line in the program, type <Alt-minus sign>. If you accidentally delete the wrong line, press <Alt-=> to undo the last command (up to 100 lines). In the editor, there is a status line near the bottom of the screen. This tells you which line the cursor is currently on, the amount of available memory, and the current insert/overwrite mode.
Blocking
This feature allows you to treat one section of text as a complete block. Then the block can be copied, moved, or deleted as a whole. 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 and last <Alt-L> 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>. Once a block of text 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. 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. To delete the entire block, type <Alt-D>, and the block is erased.
Note A number of pre-written blocks are included on the AXCESS distribution diskette.
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. Although the block is saved to disk, it also remains in your current program. To retrieve a block from disk, position the cursor in the program at the point where you would like to insert the saved text block. Type <Alt-G> and supply AXCESS with the blocks filename. The retrieved block is then inserted into your program. Press and hold the Ctrl/left arrow keys on the keyboard to shift the selected block and shift it one character to the left. Press and hold the Ctrl/right arrow keys on the keyboard to shift the selected block and shift it one character to the right. This is useful for indenting large blocks of code.
Text Editor
33
Once you are finished manipulating a block, it must be unmarked by typing <Alt-U>. The block then returns to a normal background color, and you can resume editing.
The AXCESS system allows you to search for a particular line or fragment of text, such as cassette or VHS. This is useful when you want to view all references to a certain device. Move the cursor to the line where you want to begin searching and type <Alt-S>. AXCESS asks you for the line of text you would like to find. The search function is not case sensitive. This means that an entry of CASS will return 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. Position the cursor as you did for the search command, and type <Alt-R>. AXCESS asks you for the text you are searching for, and 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). As a safety precaution, AXCESS asks if you would like to replace the line or fragment case by case.
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 control 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 detailed information on PUSH statements, refer to the Using Input and Output section. There is a small Push window (magenta on color monitors) in the bottom left corner of the screen. The 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 Central Controller 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. When button 2 on the Touch Panel on AXlink is pressed, the Push window displays:
34
Text Editor
PUSH[TOUCH_PANEL,2]
Note Be careful to follow the correct syntax (no spaces). If the PUSH statement does contain spaces, the search function will not find it, and it will not appear in the PUSH window.
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, first press the button and its PUSH statement will appear in the Push window. Position the cursor in the program, where the statement should be inserted and type <Alt-I>. The PUSH statement will then 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.
Compilation Errors
After compiling a program, 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 beginning of the first line in the file, and the type of error or warning is highlighted in the window. Once you finish correcting the mistake, you can proceed to the next error by typing <Alt-N>. The cursor appears at the next error. To go back to previous errors, type <Alt-P>. The cursor will move to the previous error. After the first error is corrected, it is recommended that you recompile the program. Any single error could be causing many more later in the program. For example, if you did not define the device VHS2 early in the file, every line that references VHS2 is
Text Editor
35
considered to be wrong. When you define VHS2 in the appropriate section, all the other lines are correct. When the program is recompiled, those errors are repaired. You can remove the error window if you need more space on the screen, if for example 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. Press <Ctrl-E> again to bring the error window back on the screen.
36
Text Editor
37
However, the above program section executes the same even if it looks like this:
IF(X = 1) {PUSH[PANEL,1] {Y = 2 Z = 3}}
The syntax is identical, but the spacing is different. The first method is recommended because it is easier to read, and adheres to AMX programming conventions.
38
Function Combine several statements into a function 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 Enclose the expression after an If statement Enclose a mutually exclusive set in the Define section Enclose DEFINE_CALL parameter list Group a mathematical operation
()
Parentheses
Several different statements grouped into one is called a compound statement. 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 list this error if the numbers are different.
PUSH[DEVICE, CHANNEL] { ON [DEVICE, CHANNEL] X=5 } (*Output command*) (*Input request*)
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]
39
PUSH[PANEL,1] { ON [RELAY_CARD,5] }
In this example, since there is only one statement after the line PUSH[PANEL,1] , braces are not necessary.
You can place any number of comments in your program, the compiler will pass over them. They have no effect on the actual operation of the program. Comments are especially helpful in long programs, where you can label different sections for future reference. If you have used comments to indicate different sections of the program, when you have to make any changes to the program, you can look for the label of the section that you are looking for. For example:
(* This section will define all the devices used. *) DEFINE_DEVICE VCR = 1 CD = 2 VPROJ = 3 RELAY = 7 LIGHTS = 8 TP = 128 (* AXC-IR/S: VCR *) (* AXC-IR/S: CD PLAYER *) (* AXC-IR/S: VIDEO PROJECTOR *) (* AXC-IR/S: SCREEN *) (* AXC-IR/S: LIGHTS *) (* AXU-CA1 COLOR VIDEO PANEL *)
40
Comments can also be used to label statements or lines of code, for your reference. As illustrated in the next example, descriptions of PUSH statements can be useful:
DEFINE_PROGRAM PUSH[TP,33] { PULSE[RELAY,SCREEN_DN] PULSE[LIGHTS,LIGHT_LOW] PULSE[VPROJ,VPROJ_IN_4] } PUSH[TP,34] { PULSE[RELAY,SCREEN_DN] PULSE[LIGHTS,LIGHT_OFF] PULSE[VPROJ,VPROJ_IN_1] } PUSH[TP,35] { PULSE[RELAY,SCREEN_UP] PULSE[LIGHTS,LIGHT_FULL] PULSE[VPROJ,VPROJ_IN_2] } (* CD PRESET *) (* VCR PRESET *) (* SLIDE PRESET *)
These comments will help you find the SLIDE preset, VCR preset, and the CD preset of the Touch Panel much more quickly.
Identifiers
Identifiers A combination of letters, numbers, or underscores that represent 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:
41
Identifiers must begin with a letter followed by any combination of letters, numbers, or underscores. No spaces are allowed. Valid identifiers: "CD3" , "TOUCH_PANEL" Invalid identifiers: "3VHS" , "CD PLAYER" , "*RGB4" The identifier must have fewer than 26 characters. Identifiers are not case-sensitive. For example, Touch_Panel is the exact same identifier as TOUCH_PANEL . Each identifier must be unique. Once you define VHS3 , do not choose that same name later for a different identifier.
Keywords
Keywords are certain words that are reserved for AXCESS 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.
42
Using Mainline
Overview
Mainline The only section of the program that is executed continuously by the Central Controller. Also known as the DEFINE_PROGRAM section. Note The only definition sections that have executable code are DEFINE_START and DEFINE_PROGRAM . DEFINE_CALL sections are not considered definition sections.
An AXCESS program typically consists of several definition sections, such as DEFINE_DEVICE , DEFINE_VARIABLE , and DEFINE_PROGRAM . Each definition section has a different function. Not all definition sections are required for a complete program. However, the DEFINE_PROGRAM section is required because it contains the program code that is executed by the Central Controller. This section of program code is also known as mainline. It is executed continuously as long as the Central Controller has power. When the Central Controller is powered up, it first executes the code in the DEFINE_START section. Then it starts at the beginning of mainline, which is the first line of program code after the DEFINE_PROGRAM header. While executing mainline, the Central Controller processes the statements in the program, taking whatever actions are defined by the program. At the end of mainline, the Central Controller does some internal processing, then returns to the top of mainline to start another loop (Figure 26). During this time, the Central Controller operations include: Checking the WAIT and WAIT_UNTIL lists Turning off expired PULSE s Handling Central Controller RS-232 communications Updating the AXlink communications bus After the Central Controller handles these tasks, it executes mainline again. The following sections describe what happens during each of these operations.
43
44
45
46
Definition Sections
Overview
This section contains information on writing an AXCESS program, using definition sections. It includes explanations of programming concepts, as well as specific instructions and examples of AXCESS programming code.
DEFINE_DEVICE
DEFINE_CONSTANT
DEFINE_VARIABLE
DEFINE_LATCHING
DEFINE_MUTUALLY_EXCLUSIVE
DEFINE_START
DEFINE_PROGRAM
The program will not operate any differently if you do not have any statements under one of the headings. However, you should keep the headings there for reference. Although the definition sections are not used in the main program, they create the materials that the main program needs to run. For example, devices and their channels are given names, channels are given different characteristics, and variables are formed in the definition sections. Even the immediate startup procedures of the AXCESS Control System are contained in a definition section. If you develop a good
Definition Sections
47
understanding of the DEFINE statements, you can build an excellent foundation for the main part of your program.
Defining Devices
Device number A unique number from 1 to 255 designated to each device connected to AXCESS via AXlink.
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. For example, 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 allows you to name the devices. Whenever you use this device name in your program, AXCESS will automatically use the corresponding device number to reference the device. The first step in writing a program is defining the devices in your system. For example, 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 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 Touch Panel will be used to control all of these devices. Your DEFINE_DEVICE section should look like this:
DEFINE_DEVICE VCR CD CASS RELAY LIGHTS VPROJ TP =1 =2 =3 =4 =5 =6 = 128 (* AXC-IR/S: VCR *) (* AXC-IR/S: CD PLAYER *) (* AXC-REL8: VCR *) (* AXC-REL8: SCREENS AND DRAPES *) (* AXC-REL8: LOW VOLTAGE LIGHTING *) (* AXC-IR/S: PROJECTOR *) (* AXU-CVA COLOR VIDEO PANEL *)
Note The devices included in this code are used for example purposes only. It is not a specific recommendation or endorsement.
From this point on, you can reference device 1 with the name VCR, device 2 with the name CD, and so on.
48
Definition Sections
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 check that all devices are under this heading. 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. For detailed information on device numbers, see Device Numbers.
Defining Constants
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.
Transport functions Common functions of devices such as VCRs and cassette decks. For example: Play, Stop, Pause, Fast Forward, and Rewind.
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.
Definition Sections
49
DEFINE_CONSTANT PLAY STOP PAUSE FFWD REW FSRCH RSRCH REC =1 =2 =3 =4 =5 =6 =7 =8 (* VCR, CD AND CASS CONSTANTS *)
SCREEN_UP SCREEN_DN
=1 =2
(* RELAY CONSTANTS *)
=1 =2 =3 =4
= 11 = 12 = 13 = 14
50
Definition Sections
The value of the constant PLAY is now set to 1. Also, STOP has a value of 2. Both of these values cannot be changed anywhere in the program. With these constants set, if you need to activate the play function of the VCR later in your program, use the constant PLAY , and AXCESS knows to use channel 1. You dont have to remember that it is channel 1 of the device. More than one constant can have the same number. For example, PLAY and FWD can both equal 1. You may see this if two cards do not have the same channels for the same functions. For example, PLAY on the VCR control card might be channel 1, and FWD on the slide control card could also be channel 1. By definition, the same constant cannot reference more than one number. This might seem obvious, but this type of error could work its way into large programs. If you make this mistake, AXCESS notifies you with a DUPLICATE SYMBOL error message upon compiling.
Defining Variables
Variables are places to store data that will change as the program is executed. Think of a variable as a random containernearly anything can be placed in it. For example, a variable can represent any number from to 65,535. Variables cannot hold a negative number. If one variable is subtracted from another, the result will always be positive. If you subtract a larger number from a smaller number, the result wraps around at 65,535. For example, 20 subtracted from 10 is 65,525.
DEFINE_VARIABLE TEMP BUFFER[1] INTEGER CAM_PRESET[1] (* Single variables *) (* Array variables *) (* Integers and variables *)
When the system is turned off, variables retain their values. If a certain variable equals 3 when AXCESS is shut down, it will remain 3 when the system is reactivated. This function has both advantages and drawbacks. If you need the variables to be reset when the system is turned on, they must be reset manually in the DEFINE_START section.
Definition Sections
51
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.
Defining Latching
Latching A defined behavior of status that causes its output channel to stay on or off until activated once more. Momentary A defined behavior of status that causes its output channel to be activated as long as the corresponding button is pressed.
In this definition section, latching channels and variables are defined. A latching channel is a channel that only changes its state once per push. If a latching channel is activated by a TO keyword, it changes its state, and when the TO is stopped by releasing the button that started it, the channel does not go back to its previous state (like a momentary channel). The channel stays either on or off. The status of a latching channel will reflect the on/off state of the channel. Here is an example:
DEFINE_LATCHING [RELAY,SYSTEM_POWER] [VCR,PLAY]..[VCR,REWIND] VAR1
In this example, the device-channel [RELAY,SYSTEM_POWER] is defined as latching. The next line uses double periods (..) to define a range of device-channels as latching. Finally, the variable VAR1 is defined as latching.
52
Definition Sections
The first set defines two channels as mutually exclusive. The second set defines a range of channels as mutually exclusive.
Defining Start
DEFINE_START marks the section of programming that will be executed only once
immediately following power-up or system reset. They cannot be executed again until another AXCESS power-up. The keyword TO cannot be used in the DEFINE_START section; instead, use ON , OFF , or PULSE . For information on these keywords, refer to Changing the State of a Channel in the Using Input and Output section. When the AXCESS Control System is turned on, the program that was last loaded into the Central Controller is in operation, and 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. In your program, you may want to reset all three decks to stop (using SYSTEM_CALL s), turn on the lights, open the drapes, and raise the screen when AXCESS is powered up. Here is what the DEFINE_START section would look like:
DEFINE_START PULSE[LIGHTS,LIGHT_FULL] PULSE[RELAY,DRAPES_OPEN] PULSE[RELAY,SCREEN_UP] SYSTEM_CALL 'FUNCTION' (VCR,STOP,) SYSTEM_CALL 'FUNCTION' (CD,STOP,) SYSTEM_CALL 'FUNCTION' (CASS,STOP,)
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 is powered down.
Definition Sections
53
Mainline The section of the program, also known as the DEFINE_PROGRAM section, that is executed continuously by the Central Controller.
Defining Program
Define_Program marks the beginning of mainline, telling the compiler that the
following statements make up the actual executing program. Before you begin the main program, you must have the DEFINE_PROGRAM header. This header tells AXCESS that you are beginning the actual program at this point. It is used like this:
DEFINE_PROGRAM (* Your program starts here. *)
The DEFINE_PROGRAM header marks the start of what is called mainline. Mainline is the section of the program that actually runs while the Central Controller 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 Control System. The most important feature of mainline is that it runs in a continuous loop. While most programming languages have a beginning and an end, mainline is like a circle: when the Central Controller gets to the end, it loops back to the top and passes through it again, as shown in Figure 27:
Figure 27 AXCESS continually loops through mainline
Program Name
AXCESS uses a long file name that gets embedded into the program the first time it is saved to provide a more descriptive name for AXCESS programs. This will appear in the first line of the program:
PROGRAM_NAME='long file name goes here'
This name is managed by AXCESS and is automatically updated every time the file is saved.
54
Definition Sections
In mainline you define what happens when remote inputs occur. To get inputs into the program, and generate an output, use channels. Almost all methods of control using an AXCESS Control System require the use of channels on devices, as shown in Figure 28. Every channel has two aspects: the input function and the output function. 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 Central Controller 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 statements in the program associated with the input change. The following six keywords are used in conjunction with input changes:
55
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. statements 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 . For example:
PUSH PUSH[device,channel] { (* Statement *) }
Multiple PUSH statements can be specified to execute the same action. For example:
PUSH[TOUCH_PANEL,1] PUSH[RADIO,64] { (* Statement *) }
56
Release
The RELEASE keyword is used in the same way as 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 Central Controller 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 .
Release_Device
Note
PUSH_DEVICE and RELEASE_ DEVICE cannot both have a RELEASE_DEVICE
non-zero value during the same pass through mainline. At least one of them will always be zero.
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.
Push_Channel
PUSH_CHANNEL is the same as PUSH_DEVICE , except that the channel number that was most recently turned on is stored inside the variable.
Release_Channel
Note
PUSH_CHANNEL and RELEASE_ CHANNEL cannot RELEASE_CHANNEL stores the channel whose button was most recently released. This system variable is used in a program in the same manner as PUSH_CHANNEL .
both have a non-zero value during the same pass through mainline. At least one of them will always be zero.
57
The next series of keywords allow you to activate channels. This activation is called an output change, which is a message to the output function of a channel. See Figure 29.
Figure 29
[ DEVI CE, Ch a n n e l ] Ch a n n e l ] Ch a n n e l ] Ch a n n e l ]
Ch a n n e l ] Ch a n n e l ] Ch a n n e l ]
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 activating channel 5 on an infrared/serial card causes it to generate the infrared pattern it has stored at location 5.
58
These keywords can be used in conjunction with variables. When a variable is activated with one of these keywords, turning it ON gives it a value of 1, and turning it OFF gives it a value of . Here are brief definitions of each of the output change keywords:
On
The ON keyword turns on a channel or variable. If the channel or variable is already on, its status will remain unchanged. Here are two examples:
ON [1,2]
This turns on channel 2 of device 1. This sets the value of the variable TEMP to 1.
ON [TEMP]
A variable is considered ON if it contains a non-zero number; in this case, the value is 1. If a variable contains the value , it is considered OFF .
Off
The OFF keyword turns off a channel or variable. If the channel or variable is already off, its status will remain unchanged. Here are two examples:
OFF [1,2]
This turns off channel 2 of device 1. This sets the value of the variable TEMP to .
OFF [TEMP]
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. For more information on mutually exclusive sets, refer to the Mutually Exclusive section in Channel Characteristics.
59
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 activates 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 placed 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. For detailed information, refer to Multiple Waits in the Waits and Timer Keywords section. It cannot be placed in the DEFINE_START section. The channel or variable will act under the rules set by DEFINE_LATCHING , DEFINE_MUTUALLY_EXCLUSIVE , and DEFINE_TOGGLING . For more information, refer to the Channel Characteristics section. You will learn about these definitions later, when you add more to your program.
Min_To
This keyword operates like the TO keyword, except that the specified channel or variable stays on for a minimum amount of time, even if the corresponding devicechannel is released. The time duration is determined by SET_PULSE_TIME . MIN_TO follows the same conditions of operation as the TO keyword.
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 , in the Defining Start section. The PULSE keyword was used to activate a lighting preset, a drapes change, and a screen change. 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
60
in tenths of seconds, and the AXCESS default is one half-second. The PULSE time remains the same value until it is changed in the program. Here is an example of SET_PULSE_TIME :
SET_PULSE_TIME(12)
This sets the current duration of future PULSE s to 1.2 seconds. It is always a good programming practice to return pulse time to the default setting, .5 seconds, as shown in the following example:
SET_PULSE_TIME(5)
Direct Assignment
Direct Assignment Generating an output change by assigning a value to a device-channel.
Direct assignment is another method of generating an output change, that does not involve using 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:
[TP,1] = 1
This statement will send an output change to channel 1 of device TP, telling the channel to turn on since AXCESS interprets any non-zero number as ON . Putting this statement in mainline will set the channel ON permanently. Using direct assignment is most appropriate in feedback statements. For controlling devices, the keywords ON , OFF , and TO are more appropriate.
61
TO[RELAY,DRAPES_STOP]
In this code, there are actually five separate, but similar statements. In each statement, first there is the keyword PUSH followed by a device-channel reference, in this case [TP,1] . This tells AXCESS to 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 that for as long as channel 1 on device 128 is activated, then turn on device 1, channel 1. Remember, TP is a device definition for device 128, and RELAY is a constant with a value of 1, as is SCREEN_UP . Always be precise with your syntax. Use numbers for input channels, and device names for devices, as shown in the example above.
62
Channel Characteristics
Overview
This section contains information on channel characteristics and how to change the way the status of an output channel behaves. It includes explanations of channel concepts, and examples of AXCESS programming code. In this chapter, you will learn how to change the status behavior, which in turn changes the way a channel reacts when it is activated by the output change keywords.
Channel Characteristics
63
both. These inputs and outputs are referred to in the AXCESS program as a devicechannel, which is written like this:
TO[DEVICE,Channel]
This the device-channel is the most fundamental concept of the AXCESS Control System, as it is the most common way that AXCESS communicates to the outside world.
Defining Latching
Momentary A defined behavior of status that causes its output channel to be activated as long as the corresponding button is pressed.
The default status of all channels is momentary. 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 slide projectors 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 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 (assuming it was previously off). However, when the TO keyword stops activating the channel (its corresponding button is released), the channel does not go back to OFF (like a momentary channel), it stays ON . It only returns to OFF when the channel is reactivated by a TO keyword. 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 devicechannel [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 Touch Panel button. Also, your drape motor needs latched relays to operate. Here are the definitions:
DEFINE_LATCHING [RELAY,SYSTEM_POWER]
Latching A defined behavior of status that causes its output channel to stay on or off until activated once more.
If you have a series of consecutive channels to be defined, you can use double periods (..) as a shortcut. The use of double periods will specify a range of channels between the first and last channel. For example, if the lights in your system need latched
64
Channel Characteristics
relays to operate, instead of defining each one right after the other, follow this example:
[LIGHTS,LIGHT_FULL]..[LIGHTS,LIGHT_OFF]
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. The three kinds of mutually exclusive channels are momentary, latching, and toggling. They are each described below:
Warning Be sure to find out which devices need mutually exclusive channels. Do not wait until you test the program, as you could damage some devices.
Channel Characteristics
65
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 .
You will also define the lighting relays as mutually exclusive so that you can utilize 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 was 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_DN]) ([RELAY,DRAPES_OPEN],[RELAY,DRAPES_CLOSE],[RELAY,DRAPES_STOP]) ([LIGHTS,LIGHT_FULL]..[LIGHTS,LIGHT_OFF])
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.
66
Channel Characteristics
Channel Characteristics
67
TO[RELAY,SYSTEM_POWER]
PUSH[TP,1]
(* SCREEN UP *)
TO[RELAY,DRAPES_STOP]
PUSH[TP,9]
(* LIGHTS FULL *)
TO[LIGHTS,LIGHT_OFF]
68
Channel Characteristics
This section accomplishes several tasks: Pressing button number 8 on the Touch Panel alternately latches and unlatches the SYSTEM_POWER channel (channel 1) on card RELAY . A press of the Screen Up button latches on the SCREEN_UP channel on device RELAY , after unlatching SCREEN_DN . The Screen Down button acts the same way as the Screen Up button, but with the opposite channels. Pressing Drapes Open or Drapes 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 turns off, but leaves its status on. To turn off the status of a channel in a mutually exclusive group, use the TOTAL_OFF keyword. 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. The DRAPES_STOP channel is momentary mutually exclusive, whereas the other drape channels are mutually exclusive latching. When the Drapes Stop button is pressed, AXCESS makes sure the other drape channels are off, then engages the DRAPES_STOP channel. Unlike the DRAPES_OPEN and DRAPES_CLOSE channels, however, the DRAPES_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
This section describes how to assign feedback to a button. Feedback refers to the lighting of a button during and after it is pressed. AXCESS does 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 conditional feedback. For example:
Channel Characteristics
69
When RELAY channel 1 (the constant value of SCREEN_UP ) is on, the light of TP button 1 will also be on. When the channel is off, the light will be off. 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.
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 .
One way of creating an output change is to assign a value directly to the devicechannel. If the value that you are assigning is another device-channel reference it tells AXCESS to take the output status of channel SCREEN_UP on device RELAY , and send it as an output change to channel 1 of device TP. Since the device-channel [RELAY,SCREEN_UP] is defined 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 Touch Panel.
When TP button 1 (Screen Up) is pressed, RELAY channel 1 (SCREEN_UP ) is turned on. Relay channel 1 in turn causes the buttons feedback to be turned on. The feedback statements can also be grouped together in a feedback section at the end of the program. as shown below:
[TP,3] = [RELAY,DRAPES_OPEN] [TP,4] = [RELAY,DRAPES_CLOSE] [TP,5] = [RELAY,DRAPES_STOP]
70
Channel Characteristics
Note The additional feedback statements for your program are listed in the next section. But first, try to write them on your own.
This feedback section will act no differently if each statement is placed under its corresponding PUSH statement. Feedback statements can be placed anywhere in the program. However, it is recommended that you organize them in your program so that they can be easily located. While grouping all of the feedback statements at the end of the program is acceptable, in larger programs it can be confusing to skip from the top where the PUSH statement is located to the bottom where the feedback statements are located. Smaller programs may be easier to manage if all the PUSH es 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, as shown in Figure 31.
Define_Combine
is used to make two or more devices appear to be the same device in an AXCESS system. This keyword is usually placed right below DEFINE_DEVICE , and contains a list of devices that are to be combined. An example of this is:
DEFINE_COMBINE DEFINE_COMBINE (TP,TP1)
Channel Characteristics
71
This combines TP and TP1 so that all channels of the two devices are identical but both devices appear to report as if they were the first device in the list. For example, if a feedback statement is written for TP , both TP and TP1 will reflect the feedback. If a PUSH statement is written for TP , a PUSH from TP or TP1 on that channel will cause the code below the PUSH to execute. This is commonly used to combine two Touch Panels where the functionality of both panels is identical. In this case, AXCESS actually thinks that both panels are one panel.
Device and channel keywords DEVICE_ID DO_PUSH DO_RELEASE GET_PULSE_TIME MASTER_SLOT SET_PULSE_TIME DEFINE_COMBINE DEFINE_LATCHING DEFINE_MUTUALLY_EXCLUSIVE DEFINE_TOGGLING
Device_ID
Every AXCESS device has a unique device ID number identifying its device type, such as an Infrared/Serial Card or a Touch Panel. The DEVICE_ID keyword returns the ID number of a specified device; if the device does not exist in the system, DEVICE_ID returns . This keyword is usually used for determining whether or not a device is present in the system. For example:
IF (DEVICE_ID(VCR)) (* If the card exists, these statements are executed *) { SEND_STRING , VCR is online, 13, 1 }
For a current list of device numbers for AXCESS devices, refer to the Deviceid.TXT text file, included on the AMX Control Disc. Deviceid.TXT is located in the AMXTools\AMXDOS\Software folder.
72
Channel Characteristics
Do_Push
Caution This keyword is useful only in limited situations, and its use is strongly discouraged.
This keyword causes an input change from off to on to occur on a specified devicechannel without the device-channel being activated by external means. Here is the format:
DO_PUSH (device,channel)
The DO_PUSH keyword holds the PUSH for one half-second. It then releases the channel by generating another input change for the device-channel from on to off. The effect is the same as someone pressing a button on a panel for one half-second. The release can be delayed by repeating the DO_PUSH before the half-second time period elapses. This keyword is useful only in limited situations, and its use is strongly discouraged.
Do_Release
Caution This keyword is useful only in limited situations, and its use is strongly discouraged.
This keyword causes an input change from on to off to occur on a specified devicechannel without the device-channel being deactivated by external means. Here is the format:
DO_RELEASE (device,channel)
If a RELEASE statement corresponding to the device-channel is present in the program, it will be executed. The DO_RELEASE keyword also forces the release of a devicechannel turned on by DO_PUSH .
Get_Pulse_Time
This system variable contains the current duration of PULSE s and MIN_TO , as set by SET_PULSE_TIME . Time is measured in tenths of seconds, and the default is one halfsecond. For example:
SET_PULSE_TIME(12) P_TIME = GET_PULSE_TIME
Channel Characteristics
73
Master_Slot
Note If this keyword is used in any system other than an AXF-BP (large CardFrame), MASTER_SLOT will always return to .
This system variable returns a number which represents the slot in which the Central Controller is plugged; represents slot 1, and 1 represents slot 2.
Set_Pulse_Time
To set the length of time for PULSE , use the keyword SET_PULSE_TIME . Time is measured in tenths of seconds, and the default is one half-second. The PULSE time remains the same value until it is changed in the program. Here is an example of SET_PULSE_TIME :
SET_PULSE_TIME(12)
This sets the current duration of PULSE s to 1.2 seconds. It recommended that you return pulse time to the default setting, .5 seconds, as in the following example:
SET_PULSE_TIME(5)
Define_Combine
This definition section allows the combination of functionally identical devices, such as identically programmed Touch Panels and Softwire Panels. When the program references one of these devices, all other combined devices in the set are also referenced. The set of devices, called a combine list, must be enclosed in parentheses. For example:
DEFINE_COMBINE (PANEL1,PANEL2,PANEL3)
Note Input and output changes occurring on non-combined panels will not affect combined panels, and vice versa.
This combines the three devices PANEL1 , PANEL2 , and PANEL3 . If an input change occurs on any of the three devices, AXCESS sees the input as coming only from the first device in the list (PANEL1) . If button [PANEL2,12] is pressed, AXCESS will see the input as coming from [PANEL1,12] due to the combination. Likewise, any output change that is sent to any device in the list will automatically be sent to all devices in the list. This includes level changes. For example, the statement ON [PANEL3,5] will turn on channel 50 for all three devices in the list. DEFINE_COMBINE is typically located immediately after the DEFINE_DEVICE section of a program.
74
Channel Characteristics
Define_Latching
In this definition section, latching channels and variables are defined. A latching channel is a channel that only changes its state once per PUSH . That is, if a latching channel is activated by a TO keyword, it changes its state; when the TO is stopped by releasing the button that started it, the channel does not go back to its previous state (like a momentary channel). The channel stays either on or off. The status of a latching channel will reflect the on/off state of the channel. For example:
DEFINE_LATCHING [RELAY,SYSTEM_POWER] [VCR,PLAY]..[VCR,REWIND] VAR1
In this example, the device-channel [RELAY,SYSTEM_POWER] is defined as latching, and the variable VAR1 is defined as latching.
Define_Mutually_Exclusive
Members of a mutually exclusive set are placed in parentheses underneath the DEFINE_MUTUALLY_EXCLUSIVE keyword. The double period (.. ) shortcut specifies a range of device-channels to be defined as mutually exclusive. For example:
DEFINE_MUTUALLY_EXCLUSIVE ([RELAY,SCREEN_UP],[RELAY,SCREEN_DOWN]) ([RELAY,DRAPE_OPEN]..[RELAY,DRAPE_STOP])
The first set defines two channels as mutually exclusive. The second set defines a range of channels as mutually exclusive.
Define_Toggling
To make a channel toggling, it must be defined as both mutually exclusive and toggling. The DEFINE_TOGGLING section is usually located directly after the DEFINE_MUTUALLY_EXCLUSIVE section. Here is an example:
Channel Characteristics
75
Another method of programming select groups is to use one variable, assigning different values to it depending on what is selected. This method is more powerful than the previous method, providing more flexibility while using less code. You will add just one variable, CUR_CAMERA . This will be the select variable. Then assign the device number of the currently selected camera to this variable. Here is your Select buttons code:
DEFINE_DEVICE CAMERA_1 CAMERA_2 CAMERA_3 = 97 = 98 = 99 (* AXB-CAM: PAN/TILT *) (* AXB-CAM: PAN/TILT *) (* AXB-CAM: PAN/TILT *)
Select variable A variable whose value determines which device in a group is currently selected.
CUR_CAMERA = CAMERA_3
76
Channel Characteristics
Use variables to simplify your program. The following example shows how to reduce the number of control sections from three to just one by using the variable CUR_CAMERA as the device number in the TO statements, instead of using CAMERA 1 , CAMERA 2 , and CAMERA 3 . Heres the section of code:
PUSH[TP,6] (* TILT UP *)
TO[CUR_CAMERA,PAN_LEFT]
In the example above, no IF statement is required, and this is the only camera control section of programming needed in the program. Using this method, to adjust CAMERA 2, first press the Camera 2 Select button. This assigns the value 98 (the constant value of CAMERA 2 ) to the variable CUR_CAMERA . Now the device-channel references of the TO control statements will reference device number 98 (the CAMERA 2 device). Pressing button number 6 on the Touch Panel will activate [CUR_CAMERA, TILT_UP] , which AXCESS will interpret as [98,36] . The feedback statements for the selection buttons are shown below:
[TP,57] = (CUR_CAMERA = CAMERA_1) [TP,58] = (CUR_CAMERA = CAMERA_2) [TP,59] = (CUR_CAMERA = CAMERA_3)
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.
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 . Only one of these will be evaluated as true because a variable cannot have two different values at one time. Therefore, the direct assignment will assign a 1 (On) to the Touch Panel button for which the expression is true, and a (Off) to those that are false. Assigning a 1 to a device-channel is the same as turning that device-channels output ON .
Channel Characteristics
77
Sample Program A complete example program using a subroutine is given below. Here are the basic requirements for the program: The devices used are one infrared/serial card, three AXB-CAM boxes, and one AMX Touch Panel. The device numbers are 6, 97, 98, 99, and 128 , respectively. The infrared/serial cards will transmit infrared code to a video projector. The Touch Panel will have three buttons. Here are the functions to be associated with each button: Button 57: Projector to input 5, recall Preset 1 on Camera 1. Button 58: Projector to input 6, recall Preset 1 on Camera 2. Button 59: Projector to input 7, recall Preset 1 on Camera 3. Here is the actual program:
DEFINE_DEVICE VPROJ CAMERA_1 CAMERA_2 CAMERA_3 TP =6 = 97 = 98 = 99 (* AXC-IR/S: PROJECTOR *) (* AXB-CAM: PAN/TILT *) (* AXB-CAM: PAN/TILT *) (* AXB-CAM: PAN/TILT *) (* AXU-CVA: COLOR VIDEO PANEL *)
= 128
DEFINE_CALL 'CAMERA MACRO' (WHICH_CAM) { PULSE[VPROJ,WHICH_CAM-CAMERA_1+15] (* SELECT INPUT 5,6 OR 7 *) PULSE[WHICH_CAM,11] } DEFINE_PROGRAM PUSH[TP,57] { (* CAMERA 1 *) (* RECALL PRESET 1 *)
78
Channel Characteristics
CUR_CAMERA = CAMERA_1 CALL 'CAMERA MACRO' (CAMERA_1) } PUSH[TP,58] { CUR_CAMERA = CAMERA_2 CALL 'CAMERA MACRO' (CAMERA_2) } PUSH[TP,59] { CUR_CAMERA = CAMERA_3 CALL 'CAMERA MACRO' (CAMERA_3) } (* CAMERA 3 *) (* CAMERA 2 *)
= 128
The section above defines the five devices used in the program.
DEFINE_CALL 'CAMERA MACRO' (WHICH_CAM) {
Channel Characteristics
79
The section above begins the subroutine. Notice that the sequence must begin with a brace, regardless of the size of the subroutine.
PULSE[VPROJ,WHICH_CAM-CAMERA_1+15] (* SELECT INPUT 5,6 OR 7 *) PULSE[WHICH_CAM,11] } (* RECALL PRESET 1 *)
The section above is the heart of the DEFINE_CALL . The first statement PULSE s the function on the video projectors controller card corresponding to the input desired on the projector. Since the functions on IR cards for video projectors have the switcher inputs located at 1120, you can add 10 to the desired input number to obtain the needed IR function number. For instance, if WHICH_CAM contains 98 (you selected Camera number 2 and input number 6 on the projector) the first PULSE statement will activate function 16, which is usually the input 6 Select function on video projector cards. The next PULSE recalls PRESET 1 on the selected camera.
DEFINE_PROGRAM PUSH[TP,57] { CUR_CAMERA = CAMERA_1 CALL 'CAMERA MACRO' (CAMERA_1) } PUSH[TP,58] { CUR_CAMERA = CAMERA_2 CALL 'CAMERA MACRO' (CAMERA_2) } PUSH[TP,59] { CUR_CAMERA = CAMERA_3 CALL 'CAMERA MACRO' (CAMERA_3) } (* CAMERA 3 *) (* CAMERA 2 *) (* CAMERA 1 *)
80
Channel Characteristics
The main program starts in the above section. The code inside each PUSH sets the current camera variable, then calls the camera macro with the selected camera passed as the WHICH_CAM parameter.
Channel Characteristics
81
82
Channel Characteristics
Defining Arrays
In the program developed in the previous sections, you used a variable. A variable can only hold one value at a time. However, if you need a variable to hold several values at once, you can use an array. An array is a single variable that has more than one storage location. Arrays must be defined as variables in 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. For more information on identifiers, refer to Identifiers in the Simply the Basics section of this manual. Second, the number of storage locations in the array must be indicated. A maximum of 255 locations can be specified, and each location holds a value from to 255. 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 below) to pick the preset you want to use. Here is your array declaration:
DEFINE_VARIABLE CAM PRESETS[6]
This declares a new variable, PRESETS , which is shown in Figure 33. The variable CAM PRESETS is an array which can hold six distinct values, as defined by the number 6 inside the brackets.
83
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 CAM PRESETS to the variable CAM PRESET_1 . Retrieving a value from an array does not in any way change the array. See Figure 34.
Figure 34 The value in CAM_PRESETS[3] is assigned to the variable
CAM_PRESET_1
CAM_PRESETS[3] CAM_PRESETS_1
You can place values into a storage location by setting the particular location equal to the needed value. For example, CAM_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:
CAM PRESETS[2]=6
The number 6 is placed into the second location, as shown in Figure 35.
Figure 35 The storage location CAM_PRESET[2] is assigned a value of 6.
CAM_PRESETS
84
From now on, anytime CAM_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:
DEFINE_VARIABLE STORE_VOL_PRESET VOL_PRESETS[1] VOL_PSET DEFINE_PROGRAM PUSH[TP,32] (* STORE *) (* 1 WHEN WE STORE VOLUME PRESET *) (* 1 VOLUME PRESETS *) (* INDEX FOR ABOVE ARRAY *)
STORE_VOL_PRESET = NOT STORE_VOL_PRESET [TP,32] = (STORE_VOL_PRESET) PUSH[TP,25] PUSH[TP,26] (* PRESET 1 *) (* PRESET 2 *) (* PRESET 3 *) (* PRESET 4 *) (* PRESET 5 *) (* PRESET 6 *) (* PRESET 7 *)
string to an AXCESS device, which then interprets the string as a command for an action.
The first PUSH [TP,32] is the Store button, which toggles the STORE_VOL_PRESET variable using the NOT operator. The NOT operator inverts the state of whatever follows it. The PUSH statement is immediately followed by a feedback statement for the Store button.
85
The next seven pushes, PUSH [TP, 25] through PUSH [TP,31] , are the buttons for PRESETS 1 through 7. Inside the block is an IF statement which uses the state of the variable STORE_VOL_PRESET to determine whether to assign the volume cards level to a location in the VOL_PRESETS array, or to send a command to the volume card telling it to go to a previously stored level. To place the variable VOL_LEVEL into the array VOL_PRESETS at the correct location, 24 must be subtracted from PUSH_CHANNEL to find the index value.
Strings
In many cases you may need to transfer a series of data 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. Examples of strings include names and the actual command portion of SEND_COMMAND statements. 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 Central Controller, these strings cannot be changed, except when a new program is loaded into the Central Controller. Here is an example of a string literal assigned to an array:
PRESETS='FOUR'
Note 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. Figure 36 The string FOUR is assigned to the array PRESETS
When AXCESS processes this assignment, it places the F (ASCII value 70) in location 1 of PRESETS , (ASCII value 79) in location 2, and so on, as shown in Figure 36. String FOUR is placed in the array PRESETS .
86
Single and double quotes are interpreted in two different ways by AXCESS. Single quotes enclose string literals, double quotes enclose string expressions. A string expression combines several types of data into a single string. A string expression can contain any ASCII value ( to 255),variables, string literals, and arrays. The difference 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:
DEFINE_PROGRAM TEMP = "SCREEN_UP,5,,'NO',X"
Note A string expression cannot contain another string expression; i.e., a set of double quotes cannot enclose another set of double quotes. Figure 37 A string expression is assigned to the array TEMP .
Assuming that SCREEN_UP 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 values: 1, 5, , N, O, 1 , as shown in Figure 37. 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.
TEMP
SCREEN_UP
Arrays as Strings
There are two ways of referencing data in arrays in AXCESS programs. Each location can be referenced as an individual value, or each array can be referenced as a group of values. 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, as shown in the following example:
87
DEFINE_VARIABLE S1[1]
This small section of code will send two strings to the card named CARD : first TEST TWO , then TEST ONE . We assigned a string expression to S1 and then sent it to the card; the entire contents of the string expression was sent. Suppose that during power-up of the AXCESS Control 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 CAM_PRESETS array. It is recommended, however, to use a string expression to set all six at once, as shown below:
DEFINE_START CAM_PRESETS = ,3,9,128,191,255 (* set all preset values at power-up *)
String Lengths
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:
LENGTH = LENGTH_STRING (CAM_PRESETS)
Here are examples of some assignments, and what the above line of code would return to the variable length in each case:
PRESETS = 'FOUR' PRESETS = 'ONE' PRESETS = "12,5,'123'" PRESETS = "PLAY,5,,'NO',X" (* LENGTH = 4 *) (* LENGTH = 3 *) (* LENGTH = 5 *) (* LENGTH = 6 *)
88
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 CAM_PRESETS variable, the array will only contain the string GOODBY , dropping the final E because CAM_PRESETS was defined to hold a maximum of six locations. The length of CAM_PRESETS would also be set to 6. If you attempt to assign an array that exceeds the storage allocations, the system will generate a run time error message: BAD SET LENGTH . 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 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 CAM_PRESETS as shown below, the length will not change. If the length was previously 3, it will still be 3.
PRESETS[1] = 'W' PRESETS[2] = 'O' PRESETS[3] = 'R' PRESETS[4] = '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 CAM_PRESETS to 4, you would use the statement:
SET_LENGTH_STRING(CAM_PRESETS,4)
After execution, the string length value of the array CAM_PRESETS is 4. String lengths play an important role in the handling of strings. The following string expression contains an array in the expression:
NEW_STRING = "5,TEMP,'GO'"
As AXCESS constructs a string from this string expression, the number of characters from the array NEW_STRING it will add will be equal to the TEMP string's length value. If TEMP 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:
89
TEMP[1] = 1 TEMP[2] = 2 TEMP[3] = 3 TEMP[4] = 4 TEMP[5] = 5 TEMP[6] = 6 SET_LENGTH_STRING(TEMP,3) NEW_STRING = "5,TEMP,'GO'" (* NEW_STRING now equals "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:
DEFINE_PROGRAM TEMP[1] = SCREEN_UP TEMP[2] = 5 TEMP[3] = TEMP[4] = 'N' TEMP[5] = 'O' TEMP[6] = X CAM_PRESETS = TEMP
The contents of the array CAM_PRESETS after this code is executed will depend on the length value of the TEMP variable. If this were the entire program, TEMP would have a default length of , so nothing would be copied into CAM_PRESETS . To assure that CAM_PRESETS holds a copy of TEMP , you would first need to set the length value of the TEMP array with this line inserted before the copy statement:
SET_LENGTH_STRING(TEMP,6)
The line above, when executed with the previous code example, renders the result shown in the example below.
90
TEMP = "SCREEN_UP,5,,'NO',X"
After this, the length value of TEMP is 6, so the first 6 locations of TEMP will be used in all cases where you refer to the entire array.
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. For 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.
91
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.
STR = RIGHT_STRING (PRESETS,2)
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)
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.
Find_string
The keywords explained previously are helpful when you know where certain parts of strings are located within a string array. However, there will be times when you don't know where certain parts of strings are located. 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 sequence. For example, if you dont know the exact contents of the TEMP array, but you want to find out if it contains the string LO , (assuming that TEMP contains HELLO) the following line is executed.
X = FIND_STRING (TEMP,'LO',1)
When AXCESS executes this statement, it will search the array TEMP from the beginning, looking for the string LO . If AXCESS finds the substring, as it will in this
92
case, it returns the starting position of the substring in the TEMP array: in this case, 4. The third parameter (in this example, 1) tells AXCESS where in the string to start the search.
Remove_string
The REMOVE_STRING keyword is similar to the FIND_STRING keyword. However, when AXCESS finds the sequence it is looking for, it extracts every character up to and including the sequence, starting from the number in the third parameter. All 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)
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, a string expression, or an array. However, in the case of REMOVE_STRING , having anything except an array as the first parameter is illogical 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 Central Controller, constant values cannot be changed, as shown in the following examples:
STR = REMOVE_STRING(TEMP,12,1) STR = REMOVE_STRING(2,HELLO,1,13,HELLO,1) (* OK *) (* NO *)
93
changes the first parameter after it removes whatever characters it needs. Only variables can be changed at run time. Supply the starting position of the search as the third parameter for both FIND_STRING and REMOVE_STRING .
REMOVE_STRING
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 does not differentiate based on the case of the letters in the identifier name. Also notice that in this example the keyword if is not capitalized. This also makes no difference to the AXCESS compiler.
94
If the incoming string is 'YES' , there is no problem. The statements are executed as normal. However, 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 can be 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. Conversely, LOWER_STRING converts a string into lowercase.
Sending Strings
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. Set the length value for the array with the SET_LENGTH_STRING function. For example, if you need to send the TEMP array to a card named RS232 , you would write the following line:
SEND_STRING RS232, TEMP
95
String literals and string expression can also be sent using SEND_STRING . Here are some examples:
SEND_STRING RS232,'THIS IS A STRING LITERAL' SEND_STRING RS232,"'EXPRESSION ', TEMP,$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 TEMP 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.
Array Keywords
Array keywords that you can use in the AXCESS program are listed in Figure 38, and their descriptions follow.
Array keywords FIND_STRING LEFT_STRING LENGTH_STRING LOWER_STRING MID_STRING REMOVE_STRING RIGHT_STRING SET_LENGTH_STRING UPPER_STRING
Find_String
This keyword tells AXCESS to search through a string for a specified sequence of characters. When AXCESS finds the sequence, it returns to the beginning position of that sequence. Heres the format:
result = FIND_STRING (string, sequence of characters, starting position of search)
Left_String
This keyword returns a specified number of characters from a specified array starting from the beginning of the array. If the length of the string is less than the number of specified characters, LEFT_STRING will return the length of the string array. This keyword requires that the length value of the array be greater than . The syntax:
96
Length_String
This keyword returns the current length value of an array. This number is different from the storage capacity of an array, which is defined in the DEFINE_VARIABLE section (see Defining Variables). The length value of an array is used by several of the AXCESS string operation keywords, and this value can change during program execution. The syntax:
result = LENGTH_STRING (string array)
Mid_String
This keyword returns the specified number of characters starting at a specified location in the source string. The length value of the array must be greater than , and the returned value is an array. The syntax:
result = MID_STRING (string array, starting position, number of characters)
Remove_String
This keyword finds and removes a specified sequence of characters in a specified string array. All characters up to and including the sequence are removed. The remaining characters in the string array move up to fill in the space. If the string is not found, a null string is returned. The returned value is an array. The syntax:
result = REMOVE_STRING (string array, sequence of characters, starting position of search)
For example:
Y = ABCDEF X = REMOVE_STRING (Y,CD,1) (* X is ABCD *) (* Y is EF *)
97
Right_String
This keyword returns a specified number of characters from a specified string array starting from the end of the string array. The length value of the array must be greater than , and the returned value is an array. The syntax:
result = RIGHT_STRING (string array, number of characters)
Set_Length_String
This keyword sets the length value of an array to a specified value. The length value of an array is used by several of the AXCESS string operation keywords. The syntax:
SET_LENGTH_STRING (string array, number)
String Keywords
String keywords that you can use in the AXCESS program are listed in Figure 39, and their descriptions follow.
Redirect_String
This keyword tells the Central Controller to pass all strings from device 1 to device 2, and all strings from device 2 to device 1. This is called a redirection, and you can assign up to eight of them at one time. Here is the syntax:
REDIRECT_STRING (entry number 18, device 1, device 2)
The entry number references a particular redirection. To cancel a redirection, use the corresponding entry number and place zeros in the device number locations in the parameters. Redirections are lost if the system power is turned off.
98
Send_Command
This keyword sends device-specific commands to an AXCESS device. The syntax:
SEND_COMMAND cards device name, card command
Send_String
This device-specific keyword sends a string to an AXCESS device. In some cases, a sequence of strings can be interpreted as a command by the device. The syntax:
SEND_STRING device, string
99
100
Creating Levels
Overview
This section contains information on creating levels. It includes explanations of the concepts involved and example AXCESS programming code. Devices such as volume control cards, voltage generator cards, and pan/tilt control cards use levels to interface with the outside world. Levels are values that are related to an analog input or output on an AXCESS device. 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, and how to use bar graphs and sliders on some of the AXCESS devices.
Creating Levels
101
Figure 40 The imaginary knobs. The knob is the level, which can have a range of values.
Creating Levels
Note A few devices have level ranges larger than to 255, but the programming principles and examples in this section still apply.
In the AXCESS language, most devices have level ranges of to 255. Level values can be stored in a variable for later use. To read a level from an AXCESS device that supports levels, use the keyword CREATE_LEVEL . Here is the syntax:
CREATE_LEVEL device, level number, variable CREATE_LEVEL
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. 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 section, you will develop a new program that handles levels. This system contains 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 to display and control the volume level, as shown in Figure 41.
102
Creating Levels
DEFINE_CONSTANT VOL_UP VOL_DN VOL_MUTE =1 =2 =3 (* THESE CHANNELS AFFECT VOLUME LEVELS 1+2 *)
Creating Levels
103
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 these channels on and off, the user can raise, lower, and mute the volume levels of the card. Here is the code for the Volume Up, Volume Down, and Volume Mute buttons on the Touch Panel:
DEFINE_PROGRAM PUSH[TP,17] { OFF[VOLUME,VOL_MUTE] TO[VOLUME,VOL_UP] } PUSH[TP,18] { OFF[VOLUME,VOL_MUTE] TO[VOLUME,VOL_DN] } PUSH[TP,19] (* VOLUME MUTE *) (* VOLUME DOWN *) (* VOLUME UP *)
Ramp To change a level from one value to another smoothly over a period of time.
Notice that the Volume Up and Volume Down buttons will automatically un-mute the volume before starting to ramp the volume up or down. Also, these control channels affect both levels of the volume card simultaneously. This code handles all of the functions of your system except for the bar graph and the Volume Preset button. These are discussed in the next section, Using Levels.
104
Creating Levels
Level Keywords
Level keywords that you can use in the AXCESS program are listed in Figure 42, and their descriptions follow.
Send_Level
This device-specific keyword sends a value to a specific level of an AXCESS device. The syntax:
SEND_LEVEL device, level number, variable
Create_Level
To read a level from an AXCESS device that supports levels, use the keyword CREATE_LEVEL . Here is the syntax:
CREATE_LEVEL device, level number, variable CREATE_LEVEL
The device from which to read the level The 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 the execution of a program, AXCESS continually updates the variable to contain the value of the level with which it is associated. Since this association only needs to be done once, CREATE_LEVEL is only allowed to appear in the DEFINE_START section of a program.
Creating Levels
105
Define_Connect_Level
All level connections are listed underneath the DEFINE_CONNECT_LEVEL header. Here is how DEFINE_CONNECT_LEVEL is used:
DEFINE_CONNECT_LEVEL (device 1, level number 1, device 2, level number 2, ... )
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 it. Any number of levels may be supported per connection, and there is no limit to the number of connections. The best location for this definition section is immediately following the DEFINE_VARIABLE section.
106
Creating Levels
Using Levels
Overview
This section describes how to use levels. It includes explanations of the concepts involved and example AXCESS programming code.
Reading Levels
Note The volume card remembers that last level when it is muted so that it can un-mute 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. 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, and when the volume is muted, the variable will contain .
Making a Preset
Preset A level saved for later retrieval. When a preset is recalled, the level returns to the preset value.
A preset is a level stored for later retrieval. In this section, you will 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 VOL_PRESET . Here is the code:
DEFINE_PROGRAM PUSH[TP,2] { OFF[VOLUME,VOL_MUTE] WAIT 2 'STORE VOL PRESET' VOL_PRESET = VOL_LEVEL } RELEASE[TP,2] { CANCEL_WAIT 'STORE VOL PRESET' SEND_COMMAND VOLUME,"'PL',ITOA(VOL_PRESET)" } (* VOLUME PRESET *) (* VOLUME PRESET *)
Using Levels
107
Note The feedback for the Volume Preset button is lit whenever the current volume level equals the value of the PRESET variable.
The PUSH of the Preset button turns off the mute and starts a two second wait. When the wait expires, the current volume level (VOL_LEVEL ) will be stored in the variable VOL_PRESET . On the release of the button, the WAIT to store the VOL_PRESET is canceled and the current value of the Preset is sent to the volume card to be recalled.
Using Bargraphs
To continuously display the current level of the volume card on the Touch Panels bargraph, use the SEND_LEVEL keyword. Here is the syntax:
SEND_LEVEL device, level number, value
The SEND_LEVEL keyword is used to update a level in a device. Assume your bar graph display on the Touch Panel has level number 1. To keep the display updated continually, add the following line into your program, on mainline:
SEND_LEVEL TP, 1, VOL_LEVEL
Since this code resides in mainline, it will be executed continually, thus making sure that the bar graph always 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
A unique feature of Touch Panel bar graphs is that you can touch and slide the TP bar graph to raise or lower the level. The level tracks the movement of your finger. However, to do this you must set up a connection between the bar graph and the volume level. This is the function of the DEFINE_CONNECT_LEVEL keyword. is not a keyword used inside mainline, but a definition section, like DEFINE_DEVICE or DEFINE_START . 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:
DEFINE_CONNECT_LEVEL
108
Using Levels
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 in the connection 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 bar graph to the volume card levels:
DEFINE_CONNECT_LEVEL (TP, 1, VOLUME, 1, VOLUME, 2)
This connects level number 1 on the Touch Panel (the bar graph) and levels 1 and 2 on the volume card. 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 (for example, 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 takes care of updating the bar graph.
Using Levels
109
110
Using Levels
Operator Types
Overview
This section contains information on operator types. It includes explanations of the concepts involved and example AXCESS programming code.
In your AXCESS program, you may need to increase the value of a variable, to see if that variable has reached a certain value, or to compare different values to each other. The tools that you use to perform these tasks are called operators. There are four types of operators in AXCESS: arithmetic, relational, logical, and bitwise. This section describes each type of operator, and illustrates how they work in conjunction with each other.
Arithmetic Operators
Arithmetic operators create a numeric value from one or more operations, such as addition, multiplication, and division. They are listed in Figure 43. Here is an example of arithmetic operators in an AXCESS program:
X=7+5 Y=X*3
Symbol
/ %
In the example above, X = 12 and Y = 36. There is an order of precedence for arithmetic operators; that is, some operations are performed first and others second. Figure 50, later in this section, lists the precedence of operators within AXCESS. For example, multiplication operations (*) are performed before addition operations (+). Here is an example that illustrates this precedence:
Operator Types
111
X=7+5*3
Reading this expression left to right, X = 36. However, since multiplication takes precedence, X = 22 (5 * 3 = 15, and 7 + 15 = 22). For detailed information on precedence, refer to Precedence Among Operators at the end of this section.
Relational Operators
Relational operators, compare two numeric values and produces a true or false result. These operators appear in Figure 44. Here is an example of these operators in practice:
X = 12 Y = 15 IF (X > Y) (* Statement 1 *) ELSE (* Statement 2 *)
Relational operators Symbol < > = Function Less than Greater than Equal to Symbol <= >= <> Function Less than or equal to Greater than or equal to Not equal to
Notice that the result of the expression (X > Y) determines the path that AXCESS takes. Since X is less than Y, Statement 1 is bypassed and Statement 2 is executed. You do not have to specify two paths. However; if there is no ELSE present, AXCESS will skip the statement or compound statement underneath the false relational expression.
112
Operator Types
When a condition or expression is evaluated as true, it is given the value of 1; if the condition or expression is false, it is given the value of . When AXCESS encounters an IF, it continues to the next statement only when the result of the IF statement is a non-zero (true) value. Otherwise, AXCESS does not execute the statement directly under the IF statement. It is possible, then, to assign a relational expression to a variable. For example:
DEFINE_PROGRAM X=9 Z = (X > 5) IF (Z) { SEND_STRING ,"'X IS GREATER THAN 5',$D,$A" } (* X IS GREATER THAN 5 *)
In this case, Z will be equal to 1 since the expression (X > 5) is true. As a result, the following IF statement is also true and AXCESS executes Statement 1. Only one relational operator should appear within a set of parentheses; two or more of these operators can produce unexpected results. For example:
X=5 IF (1 > X > 3) { SEND_STRING ,"'THIS STATEMENT NEVER GETS EXECUTED',$D,$A" }
In the example above, 10 > X is evaluated first. AXCESS assigns this part a value of 1 (1 means true). Finally, 1 > 3 is evaluated. Since this is false, Statement 1 is not executed. Since you cannot compare X to two different values in this manner, you should use a logical operator.
Operator Types
113
Logical Operators
Logical operators Operators in AXCESS that compare two conditions or, in the case of NOT , invert one condition, producing a true or false. These operators are also known as Boolean operators.
Logical operators, or Boolean operators, are similar to relational operators in that they produce a true or false result. Instead of using greater than or less than signs, logical operators use the following keywords that have different rules.
AND Both
OR At
least one of the conditions must be true for the result to be true. one condition can be true for the result to be true.
XOR Only
NOT This
keyword uses only one condition. If this condition is true, the result is false; if the condition is false, the result is true.
Figure 45 provides a quick reference guide for the results of a logical expression.
114
Operator Types
Figure 47 shows a sample logical expression table that compares two conditions. Since both (X = 5) and (Y = 4) are not true, the result of the expression is false and Statement 2 is executed. If both conditions had been true, Statement 1 would be executed instead.
Figure 47 Sample logical expression table to compare two conditions
is used differently than the other logical operators since it only requires one condition. For example:
NOT DEFINE_PROGRAM IF (X < 5) X=X+1 ELSE X=
In this case, X acts like a counter. If X does not equal 5, its value is increased by one. Eventually X will equal 5, and the Else statement will set it back to .
Operator Types
115
Unlike relational operators, logical operators can appear more than once in an expression. For example:
X=2 Y=7 Z = 12 IF ((X = 2) AND (Y > 4) OR (Z <= 8)) { (* Statement 1 *) }
There is also an order of precedence among the logical operators, listed in Figure 50, later in this section. Since the operators AND and OR have the same precedence, AND is evaluated first since it appears first. Both (X = 2) and (Y > 4) are true, so the result of this part of the expression is true. If you treat this part as one unit, you can see that its result is actually the first condition of the OR operator. Although the second condition (Z <= 8) is false, the entire expression is true since OR requires only one condition to be true. As a result, Statement 1 is executed. For detailed information on precedence, see Precedence Among Operators at the end of this section.
Bitwise Operators
Bitwise operators Operators in AXCESS that perform bit-by-bit logical operations on one byte or between two bytes.
Bitwise operators perform the same logical operations mentioned earlier, but on a bitby-bit basis. These operators are BAND , BOR , BXOR , and BNOT. They are similar to logical operators. For example, the keyword BAND performs a logical AND operation between two bytes on a bit-by-bit basis. Instead of producing a true or false result, bitwise operations form a new byte. For example:
X = $A1 BAND $8A
The variable X now equals $8 (see Figure 48). The AND operation is applied to the first bit of each value (1 and 1), setting the first bit of the result to 1. This is done again for each bit of the values, producing a new byte.
116
Operator Types
Figure 48 Band applies the logical operator And on a bit-by-bit basis. Since both bits are true in the first location, the resulting bit is also true.
Abbreviations
Instead of typing AND and BNOT in your programs, you can use some abbreviations for the logical and bitwise operators. For example, the characters && can take the place of AND , and ~ can replace BNOT . Use the method that you are comfortable with; one way is easier to read, and the other is faster to type. Figure 49 lists the logical and bitwise operators you can use in the AXCESS program.
Figure 49 Logical and bitwise operators in AXCESS that can be used instead of keywords Logical and bitwise operator abbreviations Abbreviation
&& || ^^ !
Abbreviation
& | ^ ~
Function Bitwise And (Band) Bitwise Or (Bor) Bitwise Xor (Bxor) Bitwise Not (Bnot)
Operator Types
117
If the operators are in the same level of precedence, the equation is solved from left to right. For example:
X = 12 / 3 * 5
Since multiplication and division are both in level 2, multiplication does not take higher precedence over division, and X is equal to 20. If you need to manually establish precedence for a certain operation, use parentheses to enclose the operation. Multiple levels of precedence can be created with additional parentheses. For example:
X = ((4 + 6) / (2 + 3)) + 1
The first operations solved are (4 + 6) and (2 + 3), since these operations are enclosed by the innermost parentheses. Next, 10 is divided by 5 in the second level of parentheses. Finally, 1 is added, making X equal to 3. Equations involving parentheses can become complex through many different levels of precedence. Remember that the number of left parentheses must equal the number of right parentheses in order for the expression to work. Parenthesis can be used to force the order of precedence. By adding parentheses around the OR portion of the statement, as shown in the example below, AXCESS is forced to evaluate that portion first. In this example, the result of this part of the expression is true, becoming the second condition to the AND operator. Since both portions of the AND statement are true, statement 1 executes.
118
Operator Types
Operator Keywords
Operator keywords and abbreviations (logical and bitwise) that you can use in the AXCESS program are listed below.
And (&&)
The logical operator AND is used to evaluate two conditions. These conditions must be true for the entire expression to be true. AND is typically used in IF statements to check for multiple true conditions. For example:
IF((X = 1) AND (Y = 2)) { (* These statements are executed if the above And statement is true; that is, if X = 1 is true and Y = 2 is true. *) }
Operator Types
119
Not (!)
The logical operator NOT is used when the opposite of a condition makes the expression true. For example:
IF (NOT (X = 2)) { (* If X 2, these statements are executed *) }
Or (||)
The logical operator OR is used to evaluate two conditions. At least one of the conditions must be true for the entire expression to be true. OR is typically used in IF statements to check for a true condition. For example:
IF ((X = 1) OR (Y = 2)) { (* These statements are executed if the above OR statement is true *) }
XOR (^^)
The logical operator XOR is used to evaluate two conditions. Only one of the conditions can be true for the entire expression to be true. XOR is typically used in IF statements to check for a single true condition. For example:
IF ((X = 3) XOR (Y = 1)) { (* These statements are executed if only one of the above conditions is true *) }
120
Operator Types
BAND (&)
is a bitwise operator used to perform a bitwise And operation between two bytes. Each of these bytes can be a constant value, number, or variable. The result of the operation can be tested with an IF statement or assigned to a variable. Here is an example:
BAND X = 5 BAND 14 (* X is equal to 4 *)
BNOT (~)
BNOT
is a bitwise operator used to perform a bitwise Not operation on a byte. Each bit of the byte is inverted; that is, each 1 bit becomes , and vice versa. The result of the operation can be tested with an IF statement or assigned to a variable. Here is an example:
X = BNOT 1 (* X is equal to 155 *)
BOR (|)
is a bitwise operator used to perform a bitwise Or operation between two bytes. Each of these bytes can be a constant value, number, or variable. The result of the operation can be tested with an IF statement or assigned to a variable. Here is an example:
BOR X = 1 BOR 6 (* X is equal to 14 *)
BXOR (^)
BXOR
is a bitwise operator used to perform a bitwise exclusive Or operation between two bytes. Each of these bytes can be a constant value, number, or variable. The
Operator Types
121
result of the operation can be tested with an IF statement, or assigned to a variable. Here is an example:
X = 1 BXOR 6 (* X is equal to 12 *)
122
Operator Types
ASCII Codes
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 the following example, assume that TEMP[3] holds the letter R. There are actually three ways you can reference this array location, shown in this example using IF statements:
DEFINE_PROGRAM IF (TEMP[3] = 'R') { SEND_STRING ,"'TEMP[3] IS EQUAL TO "R"',$D,$A" } IF (TEMP[3] = $52) { SEND_STRING ,"'TEMP[3] IS EQUAL TO "R"',$D,$A" } IF (TEMP[3] = 82) { SEND_STRING ,"'TEMP[3] IS EQUAL TO "R"',$D,$A" }
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 that the number 52 is a hexadecimal number.
123
All three methods (letters, decimal ASCII codes, and hexadecimal ASCII codes) can be used interchangeably. Use whichever method is easiest for the task at hand.
Integer Arrays
All of the arrays discussed to this point have a range of values in each location of to 255. The range of values in a single variable is to 65,535, and when a value greater than 255 is assigned to an array location, the number is truncated above 255. For example, if the number 500 is assigned to a location in an array, the actual number that is assigned is 244. The easiest way to find the actual number is to subtract 256 from the number until the number is less than 256 (in this example, 500 256 = 244). To create an array in which each location can contain values greater than 255, use an integer array. An integer array is just like a normal array, except that each location can hold values from to 65,535. Also, string keywords (i.e. FIND_STRING , REMOVE_STRING , MID_STRING , etc.) do not work on integer arrays. To declare an integer array, place the keyword INTEGER in front of the array definition in the DEFINE_VARIABLE section. If you want your CAM_PRESETS array to be an integer array, you would include the keyword INTEGER before the array identifier:
DEFINE_VARIABLE INTEGER CAM_PRESETS[6] (* CAMERA PRESETS *)
Note An integer array takes up twice as much AXCESS memory than would a normal array of the same storage capacity.
This declares an integer array with six locations; each location can hold values from 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. For more information on truncating values, refer to Defining Variables in the Definition Sections section of this manual. 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.
Note If your array is only going to hold alphanumeric values, it is not necessary to make it an integer array.
124
ATOI
The ATOI keyword stands for ASCII to integer. 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) (* NUM = 123 *) (* NUM = 456 *) (* NUM = 789 *)
Note The three keywords ITOA , ITOHEX , and ATOI automatically set the length value of the resulting string.
If the string contains all non-numeric characters (such as HELLO ), ATOI returns the integer . However, if there are any numeric characters embedded in 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.
INTEGER
This keyword can only be used in the DEFINE_VARIABLE and LOCAL_VAR sections when declaring arrays. It is placed in front of the array name to denote the array as an integer array. For more information, see the above discussion on integer arrays.
125
ITOA
which is short for integer to ASCII, creates a string that represents the decimal value of a number. Here are some examples:
ITOA , DEFINE_CONSTANT CONST = 456 DEFINE_VARIABLE STR[5] VAR
DEFINE_PROGRAM VAR = 789 STR = ITOA(123) STR = ITOA(CONST) STR = ITOA(VAR) (* STR = 123 *) (* STR = 456 *) (* STR = 789 *)
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.
ITOHEX
ITOHEX is short for integer to hexadecimal. ITOHEX works in the same 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:
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.
126
Two-Dimensional Arrays
Overview
Two-dimensional array A storage place holding multiple one-dimensional arrays.
The previous sections described how to group data into arrays and how to manipulate those arrays as single units. This section describes how to group multiple arrays together into one two-dimensional array. Two-dimensional arrays provide greater flexibility and power for more complex applications. This section includes explanations of the concepts involved, and example AXCESS programming code.
To understand the structure of the two-dimensional array, refer to the basic single variable. A variable holds only one value at a time. Using arrays, you can create a variable that can hold many values. Reference the desired value in the array with an index value. This allows you to store several related values, and access any 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 onedimensional arrays which can be referenced with an index value. To declare a twodimensional array:
DEFINE_VARIABLE NAMES[1][3]
Note A two-dimensional array can be declared with the INTEGER keyword, just like a onedimensional array can. This allows values in the range to 65,535 to be assigned to locations within the twodimensional array.
While a one-dimensional array has a single storage capacity value, a two dimensional array has two. NAMES is a two-dimensional array that can hold ten one-dimensional arrays, with a storage capacity of 30 characters each. The total storage capacity of NAMES is 10 characters by 30 characters, for a total of 300 characters. The variable NAMES can be used to store up to 10 names, with a maximum length of 30 characters each. Figure 54 depicts the structure of the array NAMES .
127
Storing values
The method of storing values into a two-dimensional array is similar to that of a onedimensional 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 You can assign entire two-dimensional arrays to other two-dimensional arrays For example:
DEFINE_VARIABLE NAMES[1][3] PEOPLE[8][2] ONE_NAME[3] A_VALUE DEFINE_PROGRAM A_VALUE = 1 ONE_NAME = 'EMMITT SMITH' NAMES[1][1] = 6 NAMES[1][2] = A_VALUE NAMES[2] = 'TROY AIKMAN' (* statement 5 *) (* statement 2 *) (* statement 3 *) (* statement 4 *) (* statement 1 *) (* two-dimensional array *) (* another two-dimensio nal array *) (* one-dimensional array *) (* single-value variable *)
128
Figure 55 shows what the two-dimensional array NAMES will look like after this code is executed.
Figure 55 The two-dimensional array NAMES after the assignments Note In this example, 6, 10, 1, 2, and 3 are decimal values, while all of the letters are ASCII characters. Note A two-dimensional array is like an array of onedimensional arrays.
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 twodimensional array, as shown in 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 in whole one-dimensional arrays. Once the above example has executed, the LENGTH_STRING function returns the first three rows of NAMES :
X = LENGTH_STRING (NAMES[1]) X = LENGTH_STRING (NAMES[2]) X = LENGTH_STRING (NAMES[3]) (* X will contain *) (* X will contain 11 *) (* X will contain 15 *)
Retrieving values
Retrieving values from a two-dimensional array is done in the same way as from a one-dimensional array. 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: By cell (single values) By row (an array of values) As a whole
129
Single locations (or cells) are retrieved by using two index values. The first index value specifies the row, the second specifies the location in that row. For example:
A_VALUE = NAMES[3][6]
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 that 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 . The third method of accessing a two-dimensional array is to assign it to another twodimensional array:
PEOPLE = NAMES
This will copy the entire contents of NAMES into PEOPLE , regardless of the length values of the individual rows. This method copies the entire contents of the two dimensional array, including length values of the rows. PEOPLE[2] contains TROY AIKMAN and has a length value of 11, just like NAMES[2] . In the original example, the two-dimensional array PEOPLE is defined with a size 8 by 20, and NAMES is 10 by 30. When AXCESS copies from a two-dimensional array into a smaller one, any information that falls outside the ranges of the smaller array is not copied.
130
Introduction
While your first program may seem complicated, it doesnt show the real power of the AXCESS language. At this point, the program is button-for-button. This means that each button has only one function, with no special conditions or considerations. The control panel has a separate section of buttons for each piece of equipment. In many cases, you may 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. You could set one button for each piece of equipment to select a camera, and one set of camera control buttons. Your panel could now look like the one in Figure 56.
Figure 56 Revised Touch Panel layout for your program. The functions are the same, but there are fewer buttons.
131
This configuration has seven fewer buttons than it had before. In this configuration, the user selects the camera with the Select button, then controls it with the camera control buttons. This will not be a button-for-button program because the camera control buttons have three possible functions each. In the program, you will use Boolean expressions to select the correct function of the camera control buttons.
Boolean Expressions
A Boolean, or relational expression is used to tell AXCESS whether or not to execute a particular function or functions in the program. When your program tells AXCESS to branch off in a different direction, the program can either continue in the direction it is going, or it can jump to a different section of the program. In this case, AXCESS must use a Boolean, or relational expression to judge certain conditions before continuing. A Boolean expression can have one of two results: true or false. In AXCESS, any nonzero value is true, while a zero value is false. When AXCESS evaluates a Boolean expression, it assigns a 1 for a true result, and a 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, as shown in this example:
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.
132
If the Boolean statement is true, then Statement 1 is executed and Statement 2 , underneath the ELSE statement, is ignored. If the Boolean statement is false, then Statement 2 is executed. Statement 1 is automatically ignored if the expression is false.
Default statement A statement (or compound statement) that executes if none of the conditions being tested comes true.
A last ELSE statement (not ELSE IF ) can be placed at the end as a default statement. Then, if AXCESS does not find a true IF or ELSE IF statement, it executes the final ELSE statement. This last statement is not necessary.
Nesting
Once AXCESS is following 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. An IF can be nested within an IF within an IF, and so on. When you are nesting IF...ELSE statements, be sure to use braces. Look at the following incorrect example:
133
The alignment of the ELSE statement with the IF (X = 5) suggests that they should be associated. The second IF statement in this example is not intended to have an ELSE counterpart. However, AXCESS pairs the second IF statement with the ELSE , because the compiler associates the ELSE with the closest IF statement. Using 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 braces, you isolate the IF (Y = 1) statement from the IF...ELSE set of statements.
134
Note If too many IF...ELSE IF statements are chained together, they could cause a run-time error.
Each one of the Boolean expressions is evaluated in order, until one is found to be true. The statements associated with that true expression are then executed, and then the path flows to the statements that follow the closing brace. Using SELECT...ACTIVE is preferable to using multiple IF...ELSE IF statements since it uses less memory, and runs faster. When using the IF...ELSE set of statements, the code following the ELSE is the default statement. If the condition of the IF is false, then the default statement following the ELSE is executed. If none of the conditions in a SELECT...ACTIVE statement are true, no code of any ACTIVE statement will be executed, since SELECT...ACTIVE has no default statement. The following example shows how to create your own default statement for a SELECT...ACTIVE :
SELECT { ACTIVE (condition) : (statement) ACTIVE (condition) : (statement) ACTIVE (condition) : (statement) ACTIVE (1) : (default statement) }
135
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 ACTIVE s statement the default statement.
The previously discussed IF and IF...ELSE statements could only base the program flow on one condition. However, you can combine two of these conditions with a Boolean operator. The Boolean operator sets the conditions for the end result. The Boolean operators used in the AXCESS Control System are AND , OR , XOR , and NOT . Figure 57 lists the Boolean operator abbreviations (symbols) that can be used in place of the Boolean operators.
Operator
& |
^^
!
^
~
If the end result of the Boolean expression is true, AXCESS continues with Statement 1 . If the end result is false, AXCESS ignores Statement 1 .
The following text formula can also be followed to find that result:
136
If <STATEMENT 1> is <its condition (true or false)> then the result of the expression is <result of statement conditions> .
is <its condition>,
The result is found by basing the conditions of the statements against specific rules set by the Boolean operator:
AND Both
OR At
least one of the conditions must be true for the result to be true. one statement can be true for the result to be true.
XOR Only
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.
For example, 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 as shown in Figure 59.
Figure 59 An example of how a Boolean expression table is used to compare multiple conditions.
The Boolean expression tables in Figure 60 are a quick reference guide for the result of a Boolean expression.
137
Boolean Keywords
Boolean keywords that you can use in the AXCESS program are listed in Figure 61, and their descriptions follow.
Select...Active
The SELECT...ACTIVE statement allows easy placement of several branches from one path. This is the syntax:
SELECT { ACTIVE (expression 1) : (* Statement 1 *) ACTIVE (expression 2) : (* Statement 2 *) ACTIVE (expression 3) : (* Statement 3 *) (* ...etc. *) }
Each one of the expressions is evaluated in order, 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, as it uses less memory and runs faster.
138
Else
If the corresponding IF statement is false, the program will jump to this section of the IF...ELSE set of statements.
If
The IF statement provides conditional branching of program flow. Every IF statement must be followed by an expression enclosed in parentheses. This provides the beginning of a conditional execution of statements. For example:
IF (expression) (* Statement 1 *)
If the expression is true, AXCESS executes Statement 1 and then continues with whatever statements follow. If the expression is false, Statement 1 is ignored. If Statement 1 is a compound statement, it must be enclosed in braces. The IF...ELSE statements are similar to the basic IF statement, with the addition of an alternative instruction. If the expression is false, AXCESS executes a statement independent of the true expression. For example:
IF (expression) (* Statement 1 *) ELSE (* Statement 2 *)
If the expression is true, then Statement 1 is executed and Statement 2 , underneath the ELSE statement, is ignored. If the expression is false, then Statement 2 is executed. Statement 1 is automatically ignored if the expression is false. The IF...ELSE IF set of statements allow an essentially unlimited number of paths. AXCESS stops at the first true expression and executes the following statement. Upon completion, it goes on to the rest of the program. For example:
139
IF (expression) (* Statement 1 *) ELSE IF (expression) (* Statement 2 *) ELSE IF (expression) (* Statement 3 *) (* As many Else If statements as memory allows... *)
A last ELSE statement (not ELSE IF ) can be placed at the end as a default statement. In that case, if AXCESS does not find a true IF or ELSE IF statement, it executes the final ELSE statement. This last ELSE statement is not necessary.
140
While Keywords
Overview
This section contains information on WHILE keywords. It includes explanations of the concepts involved and example AXCESS programming code.
While Keywords
The WHILE family of keywords allow the program to loop through a certain section of a program until a condition becomes true. 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 statements immediately following the WHILE . If the condition is true, AXCESS executes the statements, and then rechecks the WHILE s conditional expression. If the condition is still true, the statements are executed again. This sequence continues until the condition is evaluated as false. When the condition becomes false, program execution continues with the statements following the WHILE s block of code. For example:
DEFINE_VARIABLE RELAY_INDEX (* FOR TURNING ON RELAYS *)
In this example, the variable RELAY_INDEX is first set to 1. Next, the WHILE statement checks to see if RELAY_INDEX is less than or equal to 14. Since it is (making the statement true), AXCESS executes the compound statement directly following the WHILE. Since RELAY_INDEX equals 1, the device-channel referenced by [RELAY,1] is turned on, and RELAY_INDEX is incremented by one. Then the program loops back to the WHILE
While Keywords
141
statement. This loop continues until RELAY_INDEX becomes 15, 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 effectively turns on the first 14 channels of device RELAY . The limitation on using the WHILE keyword is that the amount of time AXCESS spends executing any WHILE cannot exceed 0.5 seconds. This is because the Central Controller 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. To prevent an AXCESS program from stalling mainline too long, there is a 0.5 second timeout on WHILE loops. AXCESS will forcibly exit the WHILE after 0.5 seconds, regardless of the operation it is executing.
Long_While
In cases where a WHILE loop takes longer than one half-second to execute, change the WHILE keyword in question to a LONG_WHILE . The difference between a WHILE and a LONG_WHILE is that after each loop through the statement, the AXlink bus is updated. This makes the statement or compound statement following a LONG_WHILE a mini-mainline, for as long as the condition of the LONG_WHILE is true. Therefore, LONG_WHILE has no timeout period. You must provide a way out of your LONG_WHILE (by allowing the condition to become false), otherwise the program will become stuck inside the LONG_WHILE and no other code outside of the loop will be executed. See the following example:
LONG_WHILE s
Caution You must 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.
142
While Keywords
DEFINE_VARIABLE WHILE_TIMEOUT DEFINE_PROGRAM RELAY_INDEX = 1 WHILE_TIMEOUT = WAIT 3 (* FORCE LONG_WHILE TO TIMEOUT AFTER 3 SECONDS *) (* FOR LONG_WHILE TIMEOUT *)
WHILE_TIMEOUT = 1 LONG_WHILE ((RELAY_INDEX <= 14) && (!WHILE_TIMEOUT)) { ON[RELAY,RELAY_INDEX] RELAY_INDEX = RELAY_INDEX + 1
} In the example above, a variable called WHILE_TIMEOUT (a flag used to force the program out of the LONG_WHILE ) is added. Before starting the LONG_WHILE loop, first initialize the timeout flag to , and set the RELAY_INDEX ( the relays that will turn on first) to 1. Then start a three-second wait to set WHILE_TIMEOUT to 1. The WAIT keyword tells the Central Controller that the following code needs to be executed at some later time. The time is specified right after the WAIT keyword in tenths of a second. In this example, WAIT 3 is three seconds. The Central Controller remembers that in three seconds it should execute the line of code WHILE_TIMEOUT = 1 . Now start the LONG_WHILE . The statements inside the LONG_WHILE execute until the condition after the LONG_WHILE becomes false. This occurs either when RELAY_INDEX reaches a value greater than 14, or the WHILE_TIMEOUT variable becomes 1. Inside the LONG_WHILE , turn on the relay RELAY_INDEX , and then increment RELAY_INDEX . The LONG_WHILE will turn on relays 1-14 . If the master were to spend more than three seconds turning on these relays, it will exit the LONG_WHILE and execute the code following the LONG_WHILE .
While Keywords
143
Medium_While
During the execution of a LONG_WHILE , AXCESS scans AXlink, as 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 can be used. This keyword operates like a LONG_WHILE , but it ignores input changes from AXCESS devices. These input changes are not lost, but will remain pending until the Central Controller scans for them againeither before the next pass through mainline, or after a pass through a LONG_WHILE . 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 Central Controller or maybe even a reloading of the systems programming.
Caution You must provide a way out of your MEDIUM_WHILE (by allowing the condition to become false), the program will become stuck inside the MEDIUM_WHILE and no other code outside of the loop will be executed.
144
While Keywords
Using Buffers
Overview
This section contains information on using buffers. It includes explanations of the concepts involved and example AXCESS programming code.
Receiving strings
Buffer An array variable that is associated with a particular device for the purpose of string 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 syntax:
CREATE_BUFFER device, array
Important
CREATE_BUFFER can only be
The CREATE_BUFFER keyword directs AXCESS to place any data received from the specified device into the specified array. When AXCESS places the bytes into the array, it increments the length value for the array and then places the bytes into the array at the current end of the array. See Figure 62 for a pictorial explanation.
Using Buffers
145
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 and use the array manipulation keywords discussed previously in the Arrays and Strings section.
BUFFER Figure 62 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.
Storing characters
Serial data Data that is sent one byte at a time.
When a device sends string information to the Central Controller, the Central Controller places the incoming information into the buffer created for that device, and updates the buffers length value. These actions are executed after the Central Controller has passed through mainline. Since all data going in and out of these devices is serial, 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 and shifts the contents of the buffer to the left, and inserts the new character at the end of the buffer, as shown in Figure 63.
Note A buffer is said to be full when its length value is equal to the storage capacity. Figure 63 Inserting a character into a full buffer causes the first character to be dropped
146
Using Buffers
Retrieving characters
Use the keyword GET_BUFFER_CHAR to retrieve characters. This keyword has a twopart operation:
1.
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. 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.
2.
The parameter passed to GET_BUFFER_CHAR must be an array, but does not need to be a buffer. Remember that 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 only one character will be returned. These examples show how to create an array called SWT_BUFFER with a capacity of a hundred characters, and how to make it a buffer associated with a device named SWT .
DEFINE_DEVICE SWT =1 (* AXC-232: AUTOPATCH 4YDM *)
DEFINE_VARIABLE SWT_BUFFER[1] TEMP_CHAR DEFINE_START CREATE_BUFFER SWT,SWT_BUFFER (* BUFFER FOR SWITCHER *) (* FOR PARSING ABOVE *)
Now all string data sent to the Central Controller from the device SWT will go into the array SWT_BUFFER . Getting the data out of the buffer as soon as it enters is usually a two-step process, as shown in this example:
Using Buffers
147
DEFINE_PROGRAM IF (LENGTH_STRING(SWT_BUFFER)) { TEMP_CHAR = GET_BUFFER_CHAR(SWT_BUFFER) IF (TEMP_CHAR = 'T' || TEMP_CHAR = '.') { SEND_STRING ,"'SWITCH COMMAND COMPLETE',$D,$A" } }
These two lines of code are actually one IF statement. The condition of the IF is the result of the LENGTH_STRING keyword. If there are not any characters in the buffer (the length value of SWT_BUFFER is ), 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 SWT_BUFFER , tells AXCESS to retrieve the first character in SWT_BUFFER , and place it into the variable CHAR , as shown in Figure 64.
Figure 64 Getting the next character out of a buffer with GET_BUFFER _CHAR .
I C
Characters should be continuously retrieved and removed from the buffer so that incoming strings have enough spaces to enter completely. Be sure to place a GET_BUFFER_CHAR statement in a position to do this. Remember, AXCESS is constantly
148
Using Buffers
running through the main program, and will execute the GET_BUFFER_CHAR statement as long as it is in its path of execution. To get the data of the SWT_BUFFER using REMOVE_STRING , use the following code:
IF (LENGTH_STRING(SWT_BUFFER) AND (FIND_STRING(SWT_BUFFER,'T',1) OR FIND_STRING(SWT_BUFFER,'.',1))) { TRASH = REMOVE_STRING(SWT_BUFFER,'T',1) IF (LENGTH_STRING(TRASH) = ) TRASH = REMOVE_STRING(SWT_BUFFER,'.',1) SEND_STRING ,"'SWT ACK',13,1"
}
The code above is similar and has the same effect as the previous code. The IF condition is looking to see if SWT_BUFFER has any characters in it with a FIND_STRING and then it looks to see if the string contains either a 'T' or a '.', since this is the result it is looking for. Once these two conditions are met, then we attempt to remove a 'T' from the buffer. If that attempt fails, then the length of TRASH will be . Only then will it attempt to remove the '.' since it did not find a 'T'. The REMOVE_STRING will remove all characters up to and including the 'T' or the '.'. So if the SWT_BUFFER contained a CI1O1T , then after the line of code:
TRASH = REMOVE_STRING(SWT_BUFFER,'T',1)
would be equal to 'CI1O1T' . Once the proper response from the switcher is verified, it AXCESS prints out the message SWT ACK to the terminal.
TRASH
Buffer Keywords
Buffer keywords that you can use in the AXCESS program are listed in Figure 65, and their descriptions follow.
Using Buffers
149
Clear_Buffer
AXCESS provides a single keyword which clears a buffer: CLEAR_BUFFER . Here is how it is used:
CLEAR_BUFFER BUFR
Null string An empty set of single quotes, which represents a string literal with no content and a length value of .
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.
Create_Buffer
Use the CREATE_BUFFER keyword to create a buffer. This keyword can only appear in the DEFINE_START section of your program, and has the following syntax:
CREATE_BUFFER device, array
directs AXCESS to place any strings received from the specified device into the specified array. When AXCESS places the byte into the array, AXCESS increments the length value for the array and then places the byte at the end of the array. When the array is full, all bytes in the array are shifted to make room for the new byte at the end.
CREATE_BUFFER
Though the array is acting as a buffer, it is still an array and can be treated as one. You can access its individual locations, send it to a device, assign it to other arrays, assign other arrays to it, and use keywords to manipulate the array.
150
Using Buffers
Create_Multi_Buffer
This keyword is similar to CREATE_BUFFER , except it creates a multi-buffer that can accept strings from a group of cards. This keyword can only appear in the DEFINE_START section of your program, and has the following syntax:
CREATE_MULTI_BUFFER starting device, ending device, array
directs AXCESS to place any strings received from the specified range of devices into the specified array.
CREATE_MULTI_BUFFER
Three header bytes are present before each string in a multi-buffer. The first header byte is the hexadecimal value $FF , which marks the beginning of a new string. The next byte is the number of the device that received the string, and then the length of the string follows. For example, if the string HELP is received by device 1, these are the contents of the corresponding multi-buffer:
$FF, 1, 4, H, E, L, P
These header bytes are used by the keyword GET_MULTI_BUFFER_STRING which returns only HELP . The GET_MULTI_BUFFER_STRING is discussed later in this section.
Get_Buffer_Char
This keyword is used to remove characters from a buffer. It has a two-part operation:
1.
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. 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.
2.
Using Buffers
151
Note All buffers are arrays, but not all arrays are buffers.
The parameter passed to GET_BUFFER_CHAR must be an array, but does not need to be a buffer. The keyword will operate identically in either case. Only one byte (character) will be returned, and this value can be assigned to a variable, array, or a cell in an array.
Get_Multi_Buffer_String
To access characters coming into a multi-buffer, you must first use GET_MULTI_BUFFER_STRING to transfer these characters into another array. The syntax:
device = GET_MULTI_BUFFER_STRING (buffer, array)
The next string in the specified buffer is assigned to the specified array. All three header bytes for the string are stripped before the string enters the array. The result of a GET_MULTI_BUFFER_STRING statement is the device number of the card that received the string.
152
Using Buffers
The most common keyword relating to time is WAIT . The WAIT keyword is used to activate functions after a specified delay time has elapsed. When a WAIT is encountered, 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 Central Controller 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. Time 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. An example application of a time delay would be if your system has two relays controlling system power. One could be for the audio amplifier, and the other for the rest of the equipment (rack power). In these cases, a time delay is desired between powering up the source equipment and powering up the audio amplifier, to avoid noise. 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
153
(the next available relay on the card), the line to add to the DEFINE_CONSTANT section looks like this:
DEFINE_CONSTANT AMP_POWER =7
You will also change the constant identifier SYS_POWER to RACK_POWER . When the System Power button is activated, you want the rack power to come on first (relay 3). After a 1-second delay, 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:
DEFINE_PROGRAM PUSH[TP,8] { IF ([RELAY,RACK_POWER]) { CANCEL_WAIT 'AMPS ON' OFF[RELAY,AMP_POWER] WAIT 1 'SYSTEM OFF' OFF[RELAY, RACK_POWER] } ELSE { CANCEL_WAIT 'SYSTEM OFF' ON[RELAY, RACK_POWER] WAIT 1 'AMPS ON' ON[RELAY,AMP_POWER] } } (* POWER ON/OFF *)
Notice the organization of the above set of statements. Here is a simplified outline of the structure of this code:
154
As shown in the outline, following the PUSH statement is a single IF...ELSE statement which has a device-channel reference for its condition. In this case, AXCESS checks that 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 perform a time-delayed power-down of the system. The first statement cancels the WAIT named AMPS ON to stop any previous attempts to turn the amps on. The second statement inside the compound statement turns off the amplifier relay. The next statement is a WAIT statement for 1 second, followed by an OFF statement to the rack power relay. AXCESS places this Wait, SYSTEM OFF , into the wait list and continues with the program. Since these statements are part of an IF compound statement, AXCESS does not execute the ELSE s compound statement. As AXCESS continues to run, the WAIT is still in the wait list. After 1 second 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 similar to the one just described, but its functions are slightly different. AXCESS first turns on the rack power, waits 1 second, and then turns on the amp power.
Multiple Waits
At this point, the System Power button completes two events, with a delay in between. In many cases, you may want to initiate a series of several events by pressing one button.
155
In this section, you will make the System Power button accomplish several more things when the power is turned on and off. For example, when the power is turned on, you may want a series of timed events to take place. First, the rack power comes on. Simultaneously, the screen starts to come down and the drapes start to close. 1 second later, the amp power comes on, just like before. After a 20 second delay, 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. After a 1 second delay, the rack power turns off. 2 minutes later, the lights go to the Off setting. Here is the code for the System Power Push for the scenario described above:
DEFINE_PROGRAM PUSH[TP,8] { IF ([RELAY,SYSTEM_POWER]) { CANCEL_WAIT 'AMPS ON' CANCEL_WAIT 'LIGHTS TO MED' OFF[RELAY,AMP_POWER] PULSE[LIGHTS,LIGHT_FULL] PULSE[RELAY,SCREEN_UP] PULSE[RELAY,DRAPES_OPEN] WAIT 1 'SYSTEM OFF' OFF[RELAY,SYSTEM_POWER] WAIT 2 'LIGHTS OFF' PULSE[LIGHTS,LIGHT_OFF] } ELSE { (* POWER ON/OFF *)
156
CANCEL_WAIT 'SYSTEM OFF' CANCEL_WAIT 'LIGHTS OFF' ON[RELAY,SYSTEM_POWER] PULSE[RELAY,SCREEN_DN] PULSE[RELAY,DRAPES_CLOSE] WAIT 1 'AMPS ON' ON[RELAY,AMP_POWER] WAIT 2 'LIGHTS TO MED' 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.
Naming Waits
When a WAIT is given a unique name, it can be either canceled, paused, or restarted. To name a WAIT , place a name in single quotes after the WAIT statement. For example:
WAIT 3 DELAY
There are certain considerations in naming WAIT s: They should not be previously defined constants or variables. They cannot be names that have already been assigned to buffers or subroutines. For detailed information on buffers refer to Using Buffers. For detailed information on subroutines refer to the next section, Using Subroutines. They can contain spaces, unlike other AXCESS identifiers.
157
places a WAIT on hold. The WAIT does not continue counting 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. nullifies every WAIT currently in the list.
CANCEL_ALL_WAIT
The keywords PAUSE_ALL_WAIT and RESTART_ALL_WAIT act the same as PAUSE_WAIT and RESTART_WAIT , except they affect all WAIT s in the wait list, named and unnamed. You could use a named WAIT in your System Power Push routine, as shown in the example above. For example, if the user just turned off the power, AXCESS now has a 2-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 LIGHTS_OFF WAIT will still happen. In this case, the lights will turn off even after the user has just turned them on. 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, add the WAIT name to the WAIT in the power-off section. can appear inside other WAIT s. This is called nesting WAIT s. It is not necessary to nest WAIT s in your program here, but here is how it is done:
WAIT s DEFINE_PROGRAM PUSH[TP,6] { WAIT 2 'SCREEN UP' { ON[RELAY,SCREEN_UP] WAIT 2 'SCREEN UP TIMEOUT' OFF[RELAY,SCREEN_UP] } } (* DELAYED SCREEN UP *)
158
In this example, AXCESS waits 20 seconds, turns on the Screen Up relay, waits 20 more seconds, then turns off the Screen Up relay. Any timed sequence of events can be accomplished with or without nested WAIT s. In many cases, using nested WAIT s is more readable than non-nested WAIT s
The first time this is executed, the WAIT is placed into the wait list. If this line is executed again before the WAIT expires, the line is ignored, because the WAIT is already in the wait list. 1/2 second after the first execution of this statement, the value in variable FLASH is inverted. If FLASH was it will be changed to 1, and if it was nonzero it will be changed to . 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.
The WAIT_UNTIL keyword is not a true timing keyword, in that 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_UNTIL s go into another list which is similar to the wait list, called the WAIT_UNTIL list. Just as it does with WAIT s, AXCESS checks to see if any WAIT_UNTIL conditions have become true with each pass through mainline. 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.
159
Misusing Wait_Until
Note AXCESS cannot detect this sort of logic error, so be sure that each WAIT_UNTIL statement can become true.
Since AXCESS only checks the status of pending WAIT_UNTILs after completely running mainline, be sure that its condition has a chance to become true, or the purpose of the WAIT_UNTIL statement will be defeated. It is not necessary to use WAIT_UNTIL in your program yet, but the following program segment illustrates the possible misuse of WAIT_UNTIL :
DEFINE_PROGRAM WAIT_UNTIL (Y = 4) { X= Y= }
Y=4 Y=3
In this example, Y will never equal 4 at the end of mainline. The WAIT_UNTIL in this case is useless. This problem could make its way into a large program. AXCESS cannot detect this sort of logic error, so be sure that each WAIT_UNTIL statement can become true.
160
Set_Timer
AXCESS provides a simple timer. It cannot be stopped or paused, only set. Like a WAIT , time is measured in increments of tenths of seconds. There is only one such timer available, and therefore has somewhat limited use. To set the timer, the SET_TIMER keyword is used. You must specify a number between and 65,535, and the timer will start counting up from that point. After the timer reaches 65,535, it wraps around to 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, as shown in the following example:
DEFINE PROGRAM IF (GET_TIMER >= 1) { SEND_STRING ,TIMER VALUE IS 1,$D,$A }
In this example, a greater-than sign was combined with the equal sign ().The timer could 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 will be 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 Control System is turned off. When the system is reactivated, the timer is reset to .
161
162
163
DEFINE_VARIABLE PULSING_LIGHTS DEFINE_PROGRAM IF ((TIME = '23::') AND (NOT PULSING_LIGHTS)) { PULSE[LIGHTS,LIGHT_OFF] ON[PULSING_LIGHTS] WAIT 2 'PULSING TIMEOUT' OFF[PULSING_LIGHTS] } (* 1 IF PULSING LIGHTS SO IT HAPPENS ONLY ONCE *)
The statements following the IF statement will be executed every day at 11:00 PM. To change the code so that the lights turn off at every hour, the statement would be changed to read:
IF ((TIME = '??::') AND (NOT PULSING_LIGHTS)) { PULSE[LIGHTS,LIGHT_OFF] ON[PULSING_LIGHTS] WAIT 2 'PULSING TIMEOUT' OFF[PULSING_LIGHTS] }
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.
The question mark (?) acts like a wildcard character, allowing any character to be in its place. Since question marks are used in place of the hour, the comparison will be true, once an hour, when the minutes and seconds are , causing the lights to turn off.
164
Date
The system variable DATE returns the current date in the form of the string MM/DD/YY , in which MM equals month, DD equals day, and YY equals year. The wildcard character ? is allowed for string comparisons. For example:
IF (DATE = 12/25/??) { (* These statements are executed every Christmas *) }
Day
The system variable DAY returns the current day of the week in the form of one of the strings MON , TUE , WED , THU , FRI , SAT , or SUN . For example:
IF (DAY = MON) { (* These statements are executed every Monday *) }
Time
The system variable TIME returns 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 (military time) format For example:
165
166
Using Subroutines
Overview
This section covers using subroutines, creating local variables, and passing parameter. It contains explanations of the concepts involved and example AXCESS programming code.
Subroutines
In larger programs, you may want 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. The most common usage of subroutines is to execute the same group of instructions from different places in the program. Using a subroutine allows you to avoid having to retype those instructions over and over in the program. Instead, you can just call the subroutine.
Defining a subroutine
In AXCESS, subroutines are created using the DEFINE_CALL statement. The subroutine name follows the DEFINE_CALL keyword, enclosed in single quotes. There are certain restrictions for subroutine names: They cannot be previously defined contents or variables. They cannot be names that have already been assigned to BUFFER s or WAIT s. 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:
Using Subroutines
167
DEFINE_CALL 'PRESET LIGHTS' (CARD,PRESET) { PULSE[CARD,PRESET] LIGHT_PRESET = PRESET } DEFINE_START CALL 'PRESET LIGHTS' (LIGHTS,LIGHT_FULL) DEFINE_PROGRAM PUSH[TP,7] (* LIGHTS OFF *)
Spaces in the subroutine name are allowed, since it is a string literal. The subroutines code must be enclosed in braces. Regardless of how long the subroutine is, it must be in this format.
Calling subroutines
To tell AXCESS to execute a subroutine, use the CALL keyword and the name of the subroutine in single quotes. For example, to execute the previous subroutine, 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.
168
Using Subroutines
Local Variables
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 program can any code access the two variables LOC_VAR and LOC_ARRAY , since 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 .
Using Subroutines
169
A local variable can also have the same name as a global variable. The local variable takes precedence in its scope, and the global variable is hidden. For 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. Local variables are usually temporary flags, loop counters, and other variables a subroutine may need to do its work.
Parameters
Parameter 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 (the Caller).
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 an example subroutine declaration using parameters:
DEFINE_CALL 'DO SWITCH' (CARD,INPUT,OUTPUT) { SEND_STRING CARD,"'CI',ITOA(INPUT),'O',ITOA(OUTPUT),'T'" }
This subroutine is defined as having 3 parameters, CARD , 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:
DEFINE_PROGRAM PUSH[TP,49] (* SWITCHER 1 *)
This calls the subroutine DO SWITCH and assigns the value SWT to CARD , 3 to INPUT , and 7 to OUTPUT . The DO SWITCH subroutine uses a string expression to construct the string CI3TT and then sends the string to the card named SWT . The same subroutine can be used with different parameters to produce different strings. Here are some examples:
DEFINE_PROGRAM
170
Using Subroutines
PUSH[TP,5]
(* SWITCHER 2 *)
A parameter variable can be modified inside a subroutine, like any other type of variable. After the 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. For example:
DEFINE_CALL 'SQUARE' (NUMBER) { NUMBER = NUMBER * NUMBER } DEFINE_PROGRAM PUSH[TP,65] { X=5 CALL 'SQUARE' (X) SEND_STRING ,"'X NO EQUALS 25',$D,$A" } PUSH[TP,66] { X = 25 CALL 'SQUARE' (X) SEND_STRING ,"'X NO EQUALS 625',$D,$A" }
Using Subroutines
171
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 (squaring it) and assigns the result back to itself. AXCESS then reassigns NUMBER back to the variable X, so that upon return from the subroutine, X will contain its previous value squared. However, if a constant value is passed to the routine, a reassignment 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 reassign it to the constant value 5. A routine in which a parameter is expected to return a result should not be called with a constant value as that parameter. 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, as shown below:
DEFINE_CALL SQUARE (NUMBER,RESULT) { RESULT = NUMBER * NUMBER }
CALL SQUARE (X,Y) (* on return, X will contain 25 and Y will contain 625 *)
172
Using Subroutines
It is important to note that the reassignment of the parameter variable to the callers variable happens after the subroutine is finished and before any other code is executed. This could lead to a 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? *)
In this example, GLOBAL contains the value 1 at the comment statement. In the subroutine BUGGY , after GLOBAL is set to 2 , AXCESS reassigns the value in PARAM to the variable in the CALL statement which called BUGGY in this case, GLOBAL . The parameter variable PARAM contains the value 1 at the end of the subroutine, and this value is reassigned to the variable in the CALL statement GLOBAL .
Call
To tell AXCESS to execute a subroutine, use the CALL keyword and the name of the subroutine in single quotes. For example, to execute the subroutine LIGHTS OFF , type the following where you want the CALL to occur:
Using Subroutines
173
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.
Define_Call
In AXCESS, subroutines are created using the DEFINE_CALL statement. The subroutine name follows the DEFINE_CALL keyword, enclosed in single quotes. There are certain restrictions for these subroutine names: They cannot be previously defined constants or variables. They cannot be names that have already been assigned to BUFFERS or WAIT s. They are case-sensitive. For example, Test and TEST are not the same. Subroutines must be defined before they can be used. For this reason, DEFINE_CALLS are typically placed right before the DEFINE_START section of the program. Here is the format:
DEFINE_CALL subroutine name { (* The subroutine goes here *) }
Spaces in the subroutine name are allowed because 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.
Local_Var
This keyword is used inside a DEFINE_CALL to declare local variables. 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 determines the parts 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.
174
Using Subroutines
A local variable can have the same name as a local variable in another subroutine. 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. 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. Local variables are also static, meaning that they retain their values between calls to the subroutine.
Using Subroutines
175
176
Using Subroutines
Include files
Typically, 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. In some cases, a program may be too large to fit into your computers memory. 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. To include a file in a program, use the keyword INCLUDE , followed by the filename in single quotes. For example:
DEFINE_PROGRAM (* Program statements can go here *) INCLUDE TEST.AXI (* More program statements can go here *)
177
When the compiler reaches the INCLUDE statement, it jumps into the specified file and continues compiling. When it has reached the end of that file, it comes back to the line following the INCLUDE statement and continues compiling. as shown in Figure 68.
Figure 68 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, not the AXCESS Control System. What you decide to put into include files is up to you. Here are several suggestions for 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
178
Include files are loaded and edited using the AXCESS editor much like normal program files. 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.
Library file A special file containing AXCESS program code. These files are used only for SYSTEM _CALLS .
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. In this example, 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
179
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, as shown in Figure 69.
Figure 69 Compilation flow using an include file
When using SYSTEM_CALL s, you do not have to implicitly include the file with the subroutine you wish to use; AXCESS does this for you automatically. The SYSTEM_CALL is like a combination of the INCLUDE and CALL keywords.
Factory System_Calls
Factory System_Calls Prepared SYSTEM_CALLS that handle many of the most common programming requirements in AXCESS Control Systems.
AMX has written a number of SYSTEM_CALL s to handle many of the most common programming requirements in AXCESS Control Systems, called Factory SYSTEM_CALL s. They are included as library files on the AXCESS distribution diskette. These SYSTEM_CALL s are divided into several categories including VCRs, switchers, laser discs, and others. Factory SYSTEM_CALL s follow a standard naming convention, and the SYSTEM_CALL s in each group take the same parameters. For an up-to-date listing of factory SYSTEM_CALL s, refer to Newcalls.TXT and Camcalls.TXT on the AMX Control Disc, or check the AMX BBS. For information on accessing the AMX BBS, refer to
180
Worldgroup Readme on the AMX Control Disc, or refer to the Accessing the AMX BBS section of this manual. The purpose of the factory SYSTEM_CALL s is to maintain a consistent look and feel for the control panels, regardless of how the deck behaves from its own remote control. For example, 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_CALL s were written to take into account the behaviors of different 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.
Look and feel The way the system 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.
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)
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_CALL s call the same routine. This is acceptable for most SYSTEM_CALL s, but there are occasions where this could cause problems, as shown in the following example. In this example, make a new library file which has WAIT statements in its subroutine. Here is a listing:
181
DEFINE_CALL SEND (CARD,STR1[1],STR2[1]) { 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 2 seconds between sends. The following line will send the string AMX , followed 2 seconds later by the string AXCESS to SWT , defined as card 3:
SYSTEM_CALL SEND (SWT1,AMX,AXCESS)
This code compiles and works fine. The following code and related paragraphs describe the effect of adding another SYSTEM_CALL to the program:
SYSTEM_CALL SEND (SWT1,AMX,AXCESS) SYSTEM_CALL SEND (SWT2,GOOD,TIMES)
In this case, 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 SWT1 , and starts the named WAIT . The next SYSTEM_CALL resets the parameter variables to all new values, and sends the string GOOD to card SWT2 . However, since the WAIT is already in the wait list, the second WAIT is ignored. 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 SWT2 , and STR2 will contain the string TIMES , so TIMES is sent to device number SWT2 .
Instance number A number enclosed in brackets after the SYSTEM_CALL keyword to denote which copy of the compiled library file to call.
The string AXCESS is never sent to card SWT1 . This is because the STR2 parameter variable in the subroutine is overwritten by the second SYSTEM_CALL before the WAIT comes due. This is the problem with using WAITS in SYSTEM_CALL subroutines. The solution is to use an instance number to force the compiler to compile two separate copies of the subroutine. Here is an example of the same SYSTEM_CALL s using instance numbers:
182
The number in the brackets is the instance number. The instance number tells the compiler to compile multiple copies of the routine, and have the different SYSTEM_CALL s each call a separate copy. The compiler does 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, as shown in Figure 70.
Figure 70 How AXCESS modifies the DEFINE_CALL name in the library file using the instance number
The process of converting the instance number to ASCII and appending it to the DEFINE_CALL name is called name mangling. When an instance number is used in a SYSTEM_CALL , AXCESS mangles the names of the DEFINE_CALL and any WAIT s, WAIT_UNTILS , and variables inside 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. For example, if a SYSTEM_CALL were made with the instance number equal to 1 , the DEFINE_CALL would be named SEND1 , and the WAIT would be named SS WAIT1 .
183
All SYSTEM_CALLS using the same instance number call the same copy of the library file. For example:
SYSTEM_CALL [1] SEND (SWT1,HOW,FEE) (* calls copy 1 *) SYSTEM_CALL [2] SEND (SWT2,DO,FI) (* calls copy 2 *) SYSTEM_CALL [2] SEND (SWT2,YOU,FO) (* calls copy 2 *) SYSTEM_CALL [3] SEND (SWT3,DO,FUM) (* calls copy 3 *)
SEND1
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.
184
Pre-Processor Statements
Overview
Pre-processor statements Statements that are processed prior to compilation.
This section contains information on pre-processor statements. Pre-processor statements include INCLUDE files and SYSTEM_CALLS . It includes explanations of the concepts involved and example AXCESS programming code.
Include file and System_Call keywords INCLUDE SYSTEM_CALL _ _DATE_ _ #DEFINE #WARN #END_IF _ _FILE_ _ #IF_DEFINED #IF_NOT_DEFINED _ _LINE_ _ _ _NAME_ _ _ _TIME_ _ _ _ VERSION_ _
Include
When the compiler reaches the INCLUDE statement, it jumps to the specified file and continues compiling. When it has reached the end of that file, it comes back to the line following the INCLUDE statement and continues compiling. The code compiled in the Include file is compiled 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, not the AXCESS control system. The syntax:
INCLUDE DOS filename
Include files are loaded and edited using the AXCESS editor much like normal program files. Like program files, the AXCESS name (not the DOS name) of the INCLUDE file is stored on the first line of the file in a PROGRAM_NAME declaration.
Pre-Processor Statements
185
Include files are saved with the DOS extension AXI. For more details, refer to the next section, Include Files and System_Calls
System_call
The SYSTEM_CALL keyword is similar to the CALL keyword, except that the subroutine resides in a special file called a library file. When this keyword is used, the compiler generates a CALL to the subroutine in the library file and automatically includes the library file for compilation. The library file is actually compiled after the main program file is compiled.
_ _Date_ _
At compile time, this keyword is replaced by a string (MM/DD/YY ) that contains the compile time date. For example:
(* The program was compiled on May 24, 1998 *) SEND_STRING , _ _DATE_ _
#Define
This keyword is actually a command to the compiler, not to the Central Controller. It is used to define a symbol. Here is the format:
#DEFINE symbol name
The symbol can be any identifier that is not already used elsewhere in the program. When the symbol is defined using #DEFINE , it can only be referred to by one of the other preprocessor keywords, such as #IF_DEFINED and #IF_NOT_DEFINED .
#Warn
This compiler directive keyword forces a warning message to be displayed after the program is compiled. Its purpose is to remind the user of certain conditions that were placed in the program. For example:
#WARN This is obsolete code
186
Pre-Processor Statements
#End_If
This keyword marks the end of an #IF_DEFINED or #IF_NOT_DEFINED block of code.
_ _File_ _
At compile time, this keyword is replaced by a string that contains the DOS filename of your program. For example:
(* The program was saved as SAMPLE.AXS *) SEND_STRING , _ _FILE_ _
#If_Defined
This keyword is used to achieve conditional compilation. The syntax:
#IF_DEFINED symbol (* Statement *) #END_IF
The code inside the two preprocessor keywords is compiled only if the symbol following the #IF_DEFINED is defined. A symbol is considered defined if it meets one of the following conditions: It has been defined as a variable in the DEFINE_VARIABLE definition section It has been defined as a constant in the DEFINE_CONSTANT definition section It has been defined as a device in the DEFINE_DEVICE definition section It is a name of a DEFINE_CALL subroutine It has been defined using #DEFINE
#If_Not_Defined
This is essentially the same as #IF_DEFINED , except the code enclosed by the #IF_NOT_DEFINED and the #END_IF will be compiled only if the symbol is not defined.
Pre-Processor Statements
187
_ _Line_ _
At compile time, this keyword is replaced by a constant that contains the line number the keyword is on. For example:
(* This is line number 23 *) SEND_STRING , _ _LINE_ _
_ _Name_ _
At compile time, this keyword is replaced by a string that contains the PROGRAM_NAME description on the first line of your program. For example:
PROGRAM_NAME = This is a sample AXCESS program (* Later in the program... *) SEND_STRING , _ _NAME_ _
_ _Time_ _
At compile time, this keyword is replaced by a string that contains the compile time. The format is HH:MM:SS , where HH equals hours, MM equals minutes, and SS equals seconds. The time is given in a 24-hour format (military time).. For example:
(* The program was compiled at 3:45 PM *) SEND_STRING , _ _TIME_ _
188
Pre-Processor Statements
_ _ Version _ _
The system variable VERSION returns the current version of the AXCESS compiler (available on Version 3.05 or newer). For example:
SEND_STRING ,"'COMPILER VERSION: ',__VERSION__,$D,$A"
Pre-Processor Statements
189
190
Pre-Processor Statements
Debugging
Overview
This section contains information on the various types of errors and bugs common to AXCESS programming, and some techniques for solving these problems.
Introduction
No programs are ever written without errors on the first try, and one of the most time-consuming parts of programming is debugging. Use this section as a reference to help minimize this process.
Types of Errors
There are three general types of programming errors: Compilation errors: Errors that occur at compile time. The AXCESS compiler alerts you to these errors immediately and identifies each error and the line where it is located. Run-time errors: Errors that occur after the program has been compiled and loaded into the Central Controller. These errors are caused by program statements that attempt illegal operations. Logic errors: Logic errors are errors in program design and thus are the programmers responsibility; AXCESS cannot tell if the program it is executing is accomplishing what the user intends.
Debugging
191
Sometimes the compiler generates a warning message instead of an error message; these warning messages always start with w. A warning about a particular statement means that the statement is not technically an error, but you should be careful doing it. Warnings, unlike errors, do not stop the program from compiling. Some types of warnings can be disabled using the Options... menu selection in the AX File menu. This displays a window where you can enable and disable the generation of warning messages. For more information, refer to the AX File Menu section. Following are warning messages along with brief descriptions.
192
Debugging
Run-time errors
Run-time errors Errors that occur during program execution.
In many cases, a program is compiled and sent to the Central Controller error-free, but the system does not act in the way it should. If the program code is correct, you should check for run-time errors. These errors occur in the Central Controller, usually when it could not perform a particular operation in the program.
Debugging
193
Normally, there is no way to tell if a run-time error occurred, or what type of runtime error occurred. However, the Central Controller can be placed in a special debugging mode. In this mode, the Central Controller sends run-time error messages through its RS-232 port as they occur. Using the terminal emulator in AXCESS, you can see what, if any, run-time errors are occurring. To turn this mode on, type the following command in the terminal emulator while on-line with the Central Controller:
AMX BUG
The following is a list of some common run-time error messages you may see while the debugging mode is on. An ellipsis after the message indicates that there is a group of messages that have the same beginning. For instance, BAD TO... refers to the set of errors BAD TO VARIABLE and BAD TO CHANNEL .
194
Debugging
Bad Set_Length...
These errors occur if the SET_LENGTH_STRING keyword tries to set the length value of an array to a value greater than the arrays storage capacity.
Bad While
This error occurs whenever a WHILE loop terminates due to the half-second timeout imposed on WHILE loops.
Finding run-time errors and logic errors can sometimes be difficult. Observing the values of variables during program execution, following program flow through conditional statements, and finding the locations of run-time errors are not easy tasks. However, there are some tools to help in your debugging.
Many times, you may want to know if or when your program reaches a certain point. By using the SEND_STRING keyword, you can send a message to your computer when it reaches a particular section of code. When a string is sent to device , the information is sent from the Central Controllers communications port. Here is an example:
Debugging
195
IF (X = Y) { SEND_STRING ,X EQUALS Y!, $D, $A } ELSE { SEND_STRING ,X DOES NOT EQUAL Y!, $D, $A }
In this example, you can observe at run time which branch the program takes by viewing the message sent out of the Central Controllers communications port. This technique is also helpful in locating run-time errors. By sending messages before and after suspected code, you can determine if the code contains any bugs. For example:
DEFINE_VARIABLE ARY[1] X
DEFINE_PROGRAM X = 11 SEND_STRING , BEFORE... ARY[X] = 123 (* This will cause an error *) SEND_STRING , ...AFTER, $D, $A
The resulting output from the Central Controller would look like this if the AMX BUG is on:
BEFORE...BAD ELEMENT ASSIGN BYTE ARRAY ...AFTER
By using the SEND_STRING statements, you can determine that the array assignment is causing the run-time error message. While the error in this example is obvious, in more complex programs the error may not be so obvious. In some cases, this debugging technique can prove to be invaluable.
196
Debugging
Viewing Variables
There are two ways to view the values in variables as a program is executed. You can use the SEND_STRING method to display a variables value at certain points in a program, or you can use the variable watch window. The variable watch window is accessed through the Diagnostics menu, and it can only be activated if there is a compiled program loaded in the computer and Central Controller. Figure 72 shows the variable watch window.
Figure 72 Variable watch window
The variable watch window allows you to view the contents of up to ten variables at a time. The window is updated after each pass through mainline. The displayed value of a variable is its value at the end of mainline. The bottom of the window lists the actions of some function keys and displays a speedometer that is updated on each pass through mainline. Here is a summary of the available functions: <F1> Adds a variable to watch. Only simple variables, one-dimensional arrays, and the rows of a two-dimensional arrays can be viewed. The <Ins> key also activates this function. <F2> Deletes the currently selected variable from the window. The <Del> key also activates this function.
Note The arrow keys move the highlight bar in the window, allowing you to select which variable to modify or delete.
Debugging
197
<F3> Sets the viewing mode for arrays to the current length. The number of locations that are displayed is determined by the current length value of the array. <F4> Sets the viewing mode for arrays to the length defined in the definition section. All of the locations of the array are displayed, regardless of the current length value of the array. <F5> Allows you to change the value of the currently selected variable. <F7> Toggles the Step mode between run and single step mode. In run mode, the system program is executed normally in the Central Controller. In single step mode, program execution is suspended between each pass through mainline. <F8> In single step mode, this key causes mainline to be executed once. This key only functions in single step mode. <F9> Allows you to change the way the variable is displayed. This key toggles from HEX, to ASCII, to decimal format to binary to octal, depending on the type of variable that is selected. This feature is only available on Version 3.05 or newer.
198
Debugging
199
Duplicate symbol
Duplicate definitions of variables or constants are found. All variables and constants must have unique identifiers.
200
Identifier expected
The compiler is expecting an identifier after a #DEFINE statement or after an integer declaration in the DEFINE_VARIABLE section.
201
Out of memory
The compiler has run out of memory. Free up memory either by removing any popup programs or drivers, by using extended memory, or by breaking your program into one or more include files.
Push/Release not allowed within Wait Push_Channel not allowed within Wait Release_Channel not allowed within Wait Push_Device not allowed within Wait Release_Device not allowed within Wait
These keywords are not allowed in a section of code which will be executed due to a WAIT keyword.
202
Syntax error
A syntax error is found in an expression. In most cases, this error means that a character is out of place or something is misspelled.
To not allowed within Define_Start To not allowed within mainline To not allowed within Release To not allowed within Wait
These errors occur if the TO keyword is found in an erroneous location. The TO keyword can only be associated directly with a PUSH statement.
203
Undefined identifier
An attempt was made to reference an identifier that has not been defined previously in the program.
Unmatched #End_If
An #END_IF keyword was found, but no #IF_DEFINED or #IF_NOT_DEFINED was previously compiled.
204
205
206
Sending Commands
To control AXCESS from a remote machine, you must first use the EXTERNAL_CONTROL keyword in the DEFINE_START section of your program to tell AXCESS which device the RS-232 card is. For example:
DEFINE_START EXTERNAL_CONTROL (RS232)
The device RS232 will now be used as an external control port. EXTERNAL_CONTROL can only be used once in the DEFINE_START section of your program. Next, you must send command packets to AXCESS. Figure 73 lists the command packets. Each of these packets consists of the following: An attention characterprepares AXCESS for the transmission; it is always $2A (*) for sending commands, and it is always $26 (&) for responses A command number One or more parameters
207
A checksum bytethe sum of all of the characters in the packet (except itself), modulo 256. Its purpose is to make sure that the packet was not garbled during the transmission
Figure 73 Commands that can be sent to AXCESS from a remote machine Command packets Command
TURN CHANNEL ON TURN CHANNEL OFF GET CHANNEL STATUS SEND STRING SEND COMMAND DO PUSH DO RELEASE DEVICE ID READ ADDRESS PULSE RESPONSE MASK LOAD STRING SET BYTE LEVEL SET WORD LEVEL LEVEL REQUEST
Packet structure
'*' <1> <DEVICE> <CHANNEL> <CHECKSUM> '*' <2> <DEVICE> <CHANNEL> <CHECKSUM> '*' <3> <DEVICE> <CHANNEL> <CHECKSUM> '*' <4> <DEVICE> <# OF BYTES> <STRING> <CHECKSUM> '*' <5> <DEVICE> <# OF BYTES> <STRING> <CHECKSUM> '*' <6> <DEVICE> <CHANNEL> <CHECKSUM> '*' <7> <DEVICE> <CHANNEL> <CHECKSUM> '*' <8> <DEVICE> <CHECKSUM> '*' <9> <DEVICE> <ADDRESS> <CHECKSUM> '*' <1> <DEVICE> <CHANNEL> <CHECKSUM> '*' <11> <MASK> <CHECKSUM> '*' <12> <DEVICE> <# OF BYTES> <STRING> <CHECKSUM> '*' <13> <DEVICE> <ADDRESS> <VALUE> <CHECKSUM> '*' <14> <DEVICE> <ADDRESS> <VALUE.2> <CHECKSUM> '*' <15> <DEVICE> <ADDRESS> <CHECKSUM>
For example, the following command packet (TURN CHANNEL ON ) causes channel 4 on device 3 to be turned on (the bytes are shown in hexadecimal):
<$2A> <$1> <$3> <$4> <$32>
Note
$2A (*) is always for sending
The attention byte appears first. Next, the first command ($1 ) is needed to turn a channel on. The following two bytes are the device number and channel to be activated. Finally, the checksum appears at the end. In this example, the string AMX is sent to device 3:
<$2A> <$4> <$3> <$3> <$41> <$4D> <$58> <$1A>
208
The attention byte remains the same as before, but the command changes to $4 , to tell AXCESS to send a string. The device number is next, followed by the number of bytes comprising the stringin this case, 3. The hexadecimal values for each letter of AMX is next, and the packet ends with the checksum.
Packet structure
'&' <1> <DEVICE> <CHANNEL> <CHECKSUM> '&' <2> <DEVICE> <CHANNEL> <CHECKSUM> '&' <4> <DEVICE> <# OF BYTES> <STRING> <CHECKSUM> '&' <6> <DEVICE> <CHANNEL> <CHECKSUM> '&' <7> <DEVICE> <CHANNEL> <CHECKSUM> '&' <8> <DEVICE> <DEVICE ID> <CHECKSUM> '&' <13> <DEVICE> <ADDRESS> <VALUE> <CHECKSUM> '&' <14> <DEVICE> <ADDRESS> <VALUE.2> <CHECKSUM> '&' <15> <DEVICE> <ADDRESS> <VALUE.2> <CHECKSUM>
This is the exact packet as sent previously with the exception of a different attention byte; it is $26 because this is a response. If you dont want these responses to appear, you can turn them off by sending the RESPONSE MASK command (11 ) with the appropriate mask byte. Only three responses can be turned off, and their mask bit positions are shown in Figure 75. A zero () bit turns the response off, and a one (1) bit turns the response on. For example, to turn off RECEIVE STRING responses and turn on GET PUSH and GET RELEASE responses, send the mask byte $6 as shown in Figure 76.
209
External_Control Keyword
The EXTERNAL_CONTROL keyword you can use in the AXCESS program is listed in Figure 77, and the commands description follows.
Figure 77
EXTERNAL_CONTROL
External_Control keyword
EXTERNAL_CONTROL PROTOCOL
keyword
External_Control
This keyword tells the Central Controller to use a particular AXCESS RS-232/422 Interface Card as an external control port. Once a port has been thus defined, all system functions can be controlled by an external computer or by another device using RS-232/422. This keyword can only be used in the DEFINE_START section of the program, and only once. Here is the syntax:
EXTERNAL_CONTROL (device)
210
Appendix
Overview
This section contains AXCESS-related reference material in the following subsections: AMX Programming Standards AXCESS Keywords ASCII Code Chart
ASCII Code Chart Abbreviations
PROGRAM_NAME='AMX 1, BOARDROOM, SO#99999, REV2, FA/BETA' (* DEALER ID, JOB NAME, SO#, REV#, AUTHOR'S INITIALS *)
*NOTE: When naming AXCESS or Touch Panel files, indicate that the file requires Extended Memory by following the job name with "(EXT.MEM)".
Use the /BETA flag after your initials in the program name until it is completed. Use (* !!REV1 *) or (* !!RV1 *) after lines or sections that were changed in program revisions.
STANDARD
ON [RELAY,1]
ALSO CORRECT
(* SYSTEM POWER:!!REV1 *)
ON [RELAY,SYSTEM_POWER] (* !!RV1 *)
Appendix
211
List the type and version of master (Normal, Enhanced, AXCENT2) used in the system after PROGRAM_NAME and before DEFINE_DEVICE.
STANDARD
PROGRAM_NAME='AMX01, BOARDROOM, SO#99999, REV2, XXX/BETA' (* DATE:04/08/95 TIME:01:23:45 *) (* SYSTEM TYPE: ENHANCED MASTER V3.500 *) (***************************************************) (* DEVICE DEFINITIONS GO BELOW *) (***************************************************) DEFINE_DEVICE
Keep a revision header (with the most recent revision at the top) listing program changes after PROGRAM_NAME and before DEFINE_DEVICE.
STANDARD:
PROGRAM_NAME='AMX01, BOARDROOM, SO#99999, REV2, XXX/BETA' (* DATE:04/08/95 TIME:01:23:45 *) (* SYSTEM TYPE: ENHANCED MASTER V3.500 *) (***************************************************) (* REV2: ADDED EL+ *) (* FIXED PROJ POWER GETTING OUT OF SYNC *) (* REV1: CHANGED IR CODES FOR TUNER *) (***************************************************) (***************************************************) (* DEVICE DEFINITIONS GO BELOW *) (***************************************************) DEFINE_DEVICE
Use similar device numbers for devices on the AXLINK buss in every system you program.
NOT RECOMMENDED
100 101 102 103 104 - MOST BOX DEVICES START AT 96 - FLOPPY DRIVES AT 127,126, - ALL OTHER DEVICES START HERE *) *) *) *) *)
212
Appendix
AXP-EL, AXP-EL+, AXP-LC, AXP-T/S, AXP-TLC AXP-SP, AXP-SP+ AXP-MSP8, AXP-MSP16, AXP-MSP24, AXP-MSP32 AXB-SLD, AXC-SLD, AXC-SAV AXR-RF AXR-IR, AXR-IRSM, AXC-RCVI AXP-MLCD AXP-CPI, AXP-CPIL, AXP-CPI8 AXB-FD AXP-SPL4 AXP-AI8
= = = = = = =
(* (* (* (* (* (* (*
AXB-SLD - LEFT PROJECTOR AXB-SLD - RIGHT PROJECTOR AXB-FD AXR-RF - TXC16,RC8; TXC16,RC9 AXR-RF - COMBINED AXP-EL+ - PODIUM PANEL AXP-EL+ - CONTROL ROOM PANEL
*) *) *) *) *) *) *)
List all devices in numerical order in the DEFINE_DEVICE section, using descriptive names. In a comment after the device definition, put the actual AMX model number and describe what equipment will be connected.
NOT RECOMMENDED
= 2 = 1 = 1 = 2
STANDARD
If the device is an AXR_RF or other such receiver, place the transmitter type, radio code, and frequency (if not 304MHZ) in the comment.
NOT RECOMMENDED
*) *)
STANDARD
= 128 (* AXR-RF; ROOM 1: TXC16,RC8; TXC16,RC9 *) = 129 (* AXR-RF; ROOM 2: TXC32,RC10; TX-SK+,RC1-5 *)
Put the DEFINE_COMBINE section after all device definitions and before the DEFINE_CONSTANT section.
NOT RECOMMENDED
Appendix
213
DEFINE_DEVICE (* devices here *) DEFINE_COMBINE (* makes things more obvious *) DEFINE_CONSTANT (* constants here *)
Include files should be listed after all DEFINE_CALLs and before DEFINE_START.
STANDARD
Comments and code should be in upper case. Line comments (except for those in the DEFINE_DEVICE section should start at column 36, and section comments should take an entire line, padded with asterisks.
NOT RECOMMENDED
(*********************) (* POWER OFF DEVICES *) (*********************) (* system power off *) (* Amp power off *)
(* POWER OFF DEVICES *************************************) OFF [SYS_PWR,1] (* SYSTEM POWER OFF *) OFF [PWR_AMP,2] (* AMP POWER OFF *)
CALL names and WAIT names are case sensitive and can be in upper and lower case.
EXAMPLE* These two CALLs are different!
DEFINE_CALL 'SYSTEM POWER' { OFF [AMP,AMP_PWR] WAIT 20 'VCR Power' OFF [VCR,VCR_PWR] } DEFINE_CALL 'System Power' {
214
Appendix
OFF [RELAY,2] OFF [RELAY,3] (* SYSTEM POWER OFF *) (* AMP POWER OFF *)
} Braces should be aligned with the commands for which they are used.
NOT RECOMMENDED
} No line should extend beyond the edge of the screen, and multi-line commands should be aligned.
NOT RECOMMENDED
IF(SYSTEM_POWER AND(SYSTEM_POWER AND([INPUT,TV_POWER]OR IN | CALL 'CHANGE CHANNEL' (TUNER,CHANNEL) | [TP,169]=SYTEM_POWER AND ([INPUT,TV_POWER] OR [(INPUT,VCR_|
STANDARD
IF(SYSTEM_POWER AND (SYSTEM_POWER AND ([INPUT,TV_POWER] OR | INPUT,VCR_POWER]))) | CALL 'CHANGE CHANNEL' (TUNER,CHANNEL) | [TP,169] = SYTEM_POWER AND ([INPUT,TV_POWER] OR |
Appendix
215
[INPUT,VCR_POWER])
PUSH statements should all have comments indicating which button on the panel uses the command.
NOT RECOMMENDED
PUSH[TP,25] TO [RELAY,3]
STANDARD
PUSH[TP,25] TO [LIGHTS,LIGHTS_OFF]
(* LIGHTS OFF *)
Many programmers choose to assign more descriptive names in DEFINE_CONSTANT, rather than to simply use channel numbers.
STANDARD
Make sure the names given to variables and are indicative of their usage.
216
Appendix
PUSH[SWP,8] TO [RELAY_3,1]
ALSO CORRECT*
PUSH[SWP,8] TO [CASS_1,CASS_PLAY]
*NOTE: If you choose not to use descriptive names for constants you must comment your code! Similar sections of code should be kept together and commented as such.
NOT RECOMMENDED
(* LIGHTS OFF *)
(* LIGHTS ON
*)
(* TRANSPORT CONTROL ***************************) SYSTEM_CALL 'VCR1' [1] (VHS,TP,1,2,3,4,5,6,7,0,0) (* LIGHTING CONTROL ****************************) PUSH[TP,26] TO [RELAY,4] (* LIGHTS ON [TP,26]=[RELAY,4] PUSH[TP,25] TO [RELAY,3] [TP,25]=[RELAY,3]
*)
(* LIGHTS OFF *)
There should be no space between a PUSH (and a RELEASE) statement and its opening bracket. Conversely, there should always be a space for TO, MIN_TO, ON, OFF, and PULSE statements; there should be no spaces within the brackets for any case.
NOT RECOMMENDED
(* LIGHTS OFF *)
(* LIGHTS OFF *)
Appendix
217
Feedback for buttons should follow the PUSH statements with which they are associated.
NOT RECOMMENDED
(* LIGHTING CONTROL ****************************) PUSH[TP,25] TO [LIGHTS,LIGHTS_ON] (* LIGHTS OFF *) PUSH[TP,26] TO [LIGHTS,LIGHTS_OFF] (* LIGHTS ON *) [TP,25]=[LIGHTS,LIGHTS_ON] [TP,26]=[LIGHTS,LIGHTS_OFF]
ALSO ACCEPTABLE
(* LIGHTING CONTROL ****************************) PUSH[TP,25] TO [RELAY,3] (* LIGHTS OFF *) [TP,25]=[RELAY,3] PUSH[TP,26] TO [RELAY,4] [TP,26]=[RELAY,4] (* LIGHTS ON *)
Do not use constants or variables for PUSH statements in mainline (except for AXCINP8 cards and similar devices).
NOT RECOMMENDED
PUSH[TP,VCR_SELECT] CURRENT=VCR
STANDARD
PUSH[TP,86] CURRENT=VCR
(* VCR SELECT *)
218
Appendix
Every DEFINE_CALL should at least have a descriptive name and descriptive names for all parameters and local variables.
NOT RECOMMENDED
DEFINE_CALL 'DO SOMETHING' (C,N) LOCAL_VAR LOOP (* LOOP COUNTER *) { LOOP= WHILE (LOOP < N) { LOOP=LOOP+1 OFF [C,LOOP] } }
STANDARD
DEFINE_CALL 'TURN RELAYS OFF' (CARD,RELAY_NUMBER) LOCAL_VAR LOOP,PRE (* LOOP COUNTER *) { PRE=1 LOOP= WHILE (LOOP<PRE) LOOP=LOOP+1 (* INCREMENTAL COUNTER *)
Appendix
219
List any PUSH_CHANNEL ranges used in the program above the DEFINE_DEVICE section. Include the section comment so it can be found later using the 'SEARCH' command (ALT+S).
STANDARD
PROGRAM_NAME='AMX1, BOARDROOM, SO#99999, REV2, XXX/BETA' (* DATE:4/8/95 TIME:1:23:45 *) (* SYSTEM TYPE: ENHANCED MASTER V3.5 *) (**********************************************************) (* PUSH_CHANNEL RANGES: >=8 ----- <=89 *) (* TV TUNER CONTROL SECTION: *) (* (* KEYPAD *) [TP,8]..[TP,89] *) (**********************************************************) (**********************************************************) (* DEVICE DEFINITIONS GO BELOW *) (**********************************************************) DEFINE_DEVICE ... (**********************************************************) (* ACTUAL PROGRAM GOES BELOW *) (**********************************************************) DEFINE PROGRAM ... (* KEYPAD *) IF(PUSH_CHANNEL>=8 AND PUSH_CHANNEL<=89) { (* CODE TO EXECUTE GOES HERE *) }
AXCESS Keywords
Keywords are certain identifiers that are reserved for AXCESS commands, functions, and system variables. These are integral to the system and cannot be redefined or used as identifiers. Figure 78 contains an alphabetical list of the AXCESS keywords.
220
Appendix
AXCESS keywords #DEFINE #END_IF #IF_DEFINED #IF_NOT_DEFINED #WARN _ _DATE_ _ _ _FILE_ _ _ _LINE_ _ _ _NAME_ _ _ _TIME_ _ _ _VERSION_ _ ACTIVE AND ATOI BAND BNOT BOR BXOR CALL CANCEL_ALL_WAIT CANCEL_ALL_WAIT_UNTIL CANCEL_WAIT CANCEL_WAIT_UNTIL CLEAR_BUFFER CREATE_BUFFER CREATE_LEVEL CREATE_MULTI_BUFFER DATE DAY DEFINE_CALL DEFINE_COMBINE DEFINE_CONNECT_LEVEL DEFINE_CONSTANT DEFINE_DEVICE DEFINE_LATCHING DEFINE_MUTUALLY_EXCLUSIVE DEFINE_PROGRAM DEFINE_START DEFINE_TOGGLING DEFINE_VARIABLE DEVICE_ID DO_PUSH DO_RELEASE ELSE EXTERNAL_CONTROL FIND_STRING GET_BUFFER_CHAR GET_MULTI_BUFFER_STRING GET_PULSE_TIME GET_TIMER IF INCLUDE INTEGER ITOA ITOHEX LEFT_STRING LENGTH_STRING LOCAL_VAR LONG_WHILE LOWER_STRING MASTER_SLOT MEDIUM_WHILE MID_STRING MIN_TO NOT OFF ON OR PAUSE_ALL_WAIT PAUSE_WAIT PROGRAM_NAME PULSE PUSH PUSH_CHANNEL PUSH_DEVICE RANDOM_NUMBER REDIRECT_STRING RELEASE RELEASE_CHANNEL RELEASE_DEVICE REMOVE_STRING RESTART_ALL_WAIT RESTART_WAIT RIGHT_STRING SELECT SEND_COMMAND SEND_LEVEL SEND_STRING SET_LENGTH_STRING SET_PULSE_TIME SET_TIMER SYSTEM_CALL SYSTEM_CALL_NUM TIME TO TOTAL_OFF UPPER_STRING WAIT WAIT_UNTIL WHILE XOR
Appendix
221
NUL
001 0x01
DLE
017 0x11
(space)
033 0x21 049
0
nibble 0x0
@
repeat code
P
button 15
button 31
p
select 1,3
0x31
065
0x41
081
0x51
097
0x61
113
0x71
SOH
002 0x02
DC1
018 0x12 034
!
virtual button
1
nibble 0x1
A
0x32 066 0x42 082
Q
button 16
a
0x52 098 0x62 114
q
select 2,3
0x22
050
0x72
STX
003 0x03
DC2
019 0x13 035
button defn
2
nibble 0x2
B
button 01
R
button 17
b
button 32
r
select 1,2,3
0x23
051
0x33
067
0x43
083
0x53
099
0x63
115
0x73
ETX
004 0x04
DC3
020 0x14 036
#
source settings
3
nibble 0x3
C
button 02
S
button 18
c
button 33
s
select 4
0x24
052
0x34
068
0x44
084
0x54
100
0x64
116
0x74
EOT
005 0x05
DC4
021 0x15 037
$
preset defn
4
nibble 0x4
D
button 03
T
button 19
d
button 34
t
select 1,4
0x25
053
0x35
069
0x45
085
0x55
101
0x65
117
0x75
ENQ
006 0x06
NAK
022 0x16 038
%
do-misc
5
nibble 0x5
E
button 04
U
button 20
e
button 35
u
select 2,4
0x26
054
0x36
070
0x46
086
0x56
102
0x66
118
0x76
ACK
007 0x07
SYN
023 0x17 039
&
do-button
6
nibble 0x6
F
button 05
V
button 21
f
button 36
v
select 1,2,4
0x27
055
0x37
071
0x47
087
0x57
103
0x67
119
0x77
BEL
008 0x08
ETB
024 0x18 040
`
do-preset
7
nibble 0x7
G
button 06
W
button 22
g
button 37
w
select 3,4
0x28
056
0x38
072
0x48
088
0x58
104
0x68
120
0x78
BS
009 0x09
CAN
025 0x19 041
(
do-volume
8
nibble 0x8
H
button 07
X
button 23
h
button 38
x
select 1,3,4
0x29
057
0x39
073
0x49
089
0x59
105
0x69
121
0x79
HT
010 0x0A 026
EM
0x1A 042
)
do-tone
9
nibble 0x9
I
button 08
Y
button 24
I
button 39
y
select 2,3,4
0x2A
058
0x3A
074
0x4A
090
0x5A
106
0x6A
122
0x7A
LF
011 0x0B
SUB
027 0x1B 043
*
do-source
:
nibble 0xA
J
button 09
Z
button 25
j
button 40
z
select 1,2,3,4
0x2B
059
0x3B
075
0x4B
091
0x5B
107
0x6B
123
0x7B
VT
012 0x0C
ESC
028 0x1C 044
+
sleep 10 sec.
;
nibble 0xB
K
button 10
[
button 26
k
select none
{
0x6C 124 0x7C
0x2C
060
0x3C
076
0x4C
092
0x5C
108
FF
013 0x0D 029
FS
0x1D 045
,
read memory
<
nibble 0xC
L
button 11
\
button 27
l
select 1
|
0x6D 125 0x7D
0x2D
061
0x3D
077
0x4D
093
0x5D
109
CR
014 0x0E 030
GS
0x1E 046
write memory
+
nibble 0xD
M
button 12
]
button 28
m
select 2
}
0x6E 126 0x7E
0x2E
062
0x3E
078
0x4E
094
0x5E
110
SO
015 0x0F 031
RS
0x1F 047
.
set defaults
>
nibble 0xE
N
button 13
^
button 29
n
select 1,2
~
0x6F 127 0x7F
0x2F
063
0x3F
079
0x4F
095
0x5F
111
SI
US
/
get version
?
nibble 0xF
O
button 14
_
button 30
o
select 3
DEL
222
Appendix
Acknowledge Bell Backspace Cancel Carriage return Device control 1 Device control 2 Device control 3 Device control 4 Delete Data link escape End of medium Enquiry End of transmission Escape End transmission block End of text
Form feed File separator Group separator Horizontal tab Line feed Negative acknowledge Null Record separator Shift in Shift out Start of heading Space Start of text Substitute Synchronous idle Unit separator Vertical tab
Appendix
223
224
Appendix
Start the Worldgroup Manager program. Create a new online service item:
a. Under the File menu, select New. b. In the New dialog, click on Online Service item. c. Click on OK.
Note For modem connection, use step 3. For internet connection, use step 4.
3.
Set up the AMX BBS in the Online Service Properties dialog for dial-up (modem) connection.
a. Type AMX BBS in the name field b. Click Modem in the How to Connect section c. Enter (972) 97-2884 in the Phone Number field. If you need to use some access
number, like 9, make sure you enter it before the phone number. Also, make sure you include the long distance access code if you are not in Dallas, TX.
d. Click on Settings. This is where you set up your modem.
1) Click on the com port your modem is attached to. If you aren't sure
which port your modem is attached to, contact your MIS manager or the place you bought your computer from. AMX Cannot support computer issues.
225
2) Select your modem from the list. If you don't see your specific modem
model, choose one of the generic modems. These will usually work.
3) Click on Options. Make sure Lock Modem Speed is unchecked. You may
also wish to select the maximum baud rate your modem is capable of in the Baud Rate section. Click OK to close the dialog.
4) Click OK to close the Modem Settings dialog
Uncheck Log on as new user Enter your AMX BBS user name in the User ID field Enter your AMX BBS password in the Password field
Leave Log on as new user checked. You will need to fill in your user information the first time you log on. After you log in the for the first time, call AMX technical support to get your account updated properly.
4) Set up the AMX BBS in the Online Service Properties dialog for internet
(telnet) connection.
a) b) c) d)
Type AMX BBS in the name field Click Telnet in the How to Connect section Enter "BBS.AMX.COM " in the Host field Enter your user information in the How to Log On section:
1) If you have an account on the AMX BBS: a) Uncheck Log on as new user b) c)
Enter your AMX BBS user name in the User ID field Enter your AMX BBS password in the Password field
Leave Log on as new user checked. You will need to fill in your user information the first time you log on. After you log in the for the first time, call AMX technical support to get your account updated properly.
226
You're done!
227
228
Technical Support
Overview
Before calling AMX for assistance, check your AXlink, power, and cable connections, and the integrity of your software operating system. Reload the software to see if something in the program is causing the problem. If the problem is not resolved, reload the program from a new copy of your master disk. If you still have a service problem, refer to the list shown in Figure 81 and map (Figure 82) to determine your team. Then, call your AMX Support Team for technical assistance.
Sales and support team telephone numbers Team Central East International Special Projects Synergy Technical Support West Telephone number 800/85-AMX-85 (800/852-6985) 800/75-AMX-75 (800/752-6975) +(1) 972-907-6247 800/45-AMX-45 (800/452-6945) 800/95-AMX-95 (800/952-6995) 800/93-AMX-93 (800/932-6993) 800/55-AMX-55 (800/552-6955)
West Central
East
Technical Support
229
230
Technical Support
Glossary
Overview
This section contains keywords and descriptions of terms used throughout this manual. Analog An input or output that can have many values. Array A single variable that has more than one storage location. Arithmetic operatorsOperators in AXCESS that create a numeric value from one or more operations such as addition, multiplication, and division. ASCII A coding scheme that assigns numeric values to letters, numbers, and other characters. AXlink The AXCESS communications bus. Bargraph 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.
Glossary
231
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 one or two-dimensional array. Central Controller The AXCESS controller (processor) that controls the activities of the AXCESS system. 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. Comment A description or remark in an AXCESS program that is not considered part of the actual program; it is ignored by the compiler. Communications portPort 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 cannot be changed throughout the entire program. Decimal Base 10 numbering system.
232
Glossary
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 , DEFINE_PROGRAM , DEFINE_CONNECT and DEFINE_COMBINE . 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 designating 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 devicechannel. Downloading The sending of data from a computer to a device (such as a Central Controller). 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. 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.
Glossary
233
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. High byte A normal variable consists of 16 bits, which is equal to two bytes; one byte is the high byte, and the other is the low byte. 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 .AXI DOS extension. 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 to 65,535, inclusive.
234
Glossary
Integer array An array where each location can hold a value ranging from to 65,535. Note that an integer array will take up twice as much AXCESS memory than would a normal array of the same storage capacity. 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. 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. Logical operators Operators in AXCESS that compare two conditions or, in the case of NOT , invert one condition. A true or false result is produced. These operators are also known as Boolean operators. 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. Mainline The section of the program that is executed continuously by the Central Controller. This is also known as the DEFINE_PROGRAM section. Modem Communications device used to transfer serial data through phone lines.
Glossary
235
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 reactivated or another channel of the set is activated. Name mangling The process where the name of the DEFINE_CALL and any WAIT s and WAIT_UNTIL s in a library file are changed so that multiple separate copies can be compiled into a program. Nesting Placing code inside other code. Null string An empty set of single quotes, which represents a string literal with no content and a length value of . Offset A number used as a transparent stepping stone for other constants and variables. These constants and variables are added to the off-set to access different functions without changing their original values. Button-for-button 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.
236
Glossary
Password A series of numbers that allows access to restricted data. Pre-processor statements Statements that are processed prior to compilation. 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 .AXS extension . 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. Redirection A command that tells AXCESS to pass all strings from one device to another, and vice versa. 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 Central Controller. 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.
Glossary
237
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 Central Controller, and in its CardFrame. Source code The AXCESS program that you type and edit. Special Operators A character or group of characters that performs a specific mathematical or relational function. 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 Central Controller that can be referenced by certain keywords.
238
Glossary
Timeout A defined amount of time during which a device waits for user input until performing a default action. 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 How something interacts with the user. This is also called 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 Central Controller 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 Central Controller 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
239
240
Glossary
Index
A
Abbreviations, 117 Accessing Array Values, 84 All About Channels, 55 All About Levels, 101 All About Mainline, 43 Arithmetic Operators, 111 Array Keywords, 96 Find_String, 96 Left_String, 96 Length_String, 97 Mid_String, 97 Remove_String, 97 Right_String, 98 Set_Length_String, 98 Arrays and Strings, 83 Arrays as Strings, 87 ASCII Codes, 123 attention character, 207 AX File Menu, 19 Create S19 file, 21 Options, 22 Retrieve, 20 Send, 20 Send w/password, 21 Source-send, 21 Verify, 21 AX File Menu <F2>, 13 AXCESS documentation, 6 AXCESS/AXCESSX, 5 AXCHAN.TXT, 6 AXlink Communications Bus, 45 AXPOWER.TXT, 6 Boolean operators, 114, 136 Buffer, 145 Buffer keywords, 150 Clear_Buffer, 150 Create_Buffer, 150 Create_Multi_Buffer, 151 Get_Buffer_Char, 151 Get_Multi_Buffer_String, 152
C
Caller, 171 Calling subroutines, 168 CAMCALLS.TXT, 6 Canceling Waits, 158 Case Sensitive, 34 Change Directory window, 18 Changing and Comparing Values, 111 Changing the State of a Channel, 58 Channel Characteristics, 63 Channel Keywords, 72 Define_Combine, 74 Define_Latching, 75 Define_Mutually_Exclusive, 75 Define_Toggling, 75 Device_ID, 72 Do_Push, 73 Do_Release, 73 Get_Pulse_Time, 73 Master_Slot, 74 Set_Pulse_Time, 74 Channels, 6, 55 checksum byte, 208 command number, 207 command packets, 207, 208 Communications Menu, 25 Configure, 25 Pass thru, 26 Receive file, 26 Send file, 26 Terminal emulator, 25 Communications Menu <F4>, 13 Communications problem resolutions, 11 COMPACT Setup, 7 Compare current devices, 23 Compare Current Devices list, 24 Compilation Errors, 35, 191 Compilation Errors and Warnings, 191 (w) Cannot assign unlike types, 192 (w) Define_Call is not used, 193
B
bargraph, 108 Bitwise Operators, 116 Blinking light status, 11 Blocking, 33 Boolean expression, 77 Boolean Expression Table, 136 Boolean expression tables, 137 Boolean Keywords, 138 Else, 139 If, 139 Select...Active, 138 Boolean operator abbreviations, 136
Index
241
(w) Integer applies to arrays only, 193 (w) Long_While within While, 193 (w) Possibly too many nested levels, 193 (w) Variable is not used, 193 Compilation flow, 178 Compilation flow using an include, 180 Compile time, 87 Compiler Error Messages, 199 A "<symbol>" was expected, 199 Active keyword expected, 199 Allowed only in Define_Start, 199 Attempted Call to undefined subroutine, 199 Comment never ends, EOF encountered, 199 Conditional compile nesting too deep, 199 Constant type not allowed, 200 Define_Call must have a name, 200 Define_Call name already used, 200 Device values must be equal, 200 Duplicate symbol, 200 Evaluation stack overflow, 200 Evaluation stack underflow, 200 Identifier expected, 201 Identifier is not an array type, 201 Include file not found, 201 Invalid include file name, 201 Library file not found, 201 Maximum string length exceeded, 201 Must be char array reference, 201 Must be integer reference, 201 Out of memory, 202 Parameter mismatch in Call, 202 Program_Name must be on line 1, 202 Push/Release not allowed within Push/Release, 202 Push/Release not allowed within Wait, 202 Push_Channel not allowed within Wait, 202 Push_Device not allowed within Wait, 202 Release_Channel not allowed within Wait, 202 Release_Device not allowed within Wait, 202 String constant expected, 202 String constant never ends, EOF encountered, 202 String literal expected, 203 Subroutine may not call itself, 203 Syntax error, 203
System_Call name not same as Program_Name in <file>, 203 This variable type not allowed, 203 To not allowed within Define_Start, 203 To not allowed within mainline, 203 To not allowed within Release, 203 To not allowed within Wait, 203 Too few parameters in Call, 203 Too many include files, 204 Too many parameters in Call, 204 Type mismatch in function call, 204 Undefined identifier, 204 Unmatched #End_If, 204 Unrecognized character in input file, 204 Use System_Call [instance] name, 204 Variable assignment not allowed here, 204 Wait not found, 205 Compiler messages Assignment of unlike types, 22 DEFINE_CALL is not used, 22 Parameter mismatch, 22 Variable is not used, 22 Compiler Options, 22 Separate DEFINE_CALL list, 22 Compound Statements, 38 Configure window, 25 Connecting Levels, 108 Connecting the System, 10 Controlling Time within AXCESS, 153 Creating buffers, 145 Creating Levels, 101, 102 CUSTOM Setup, 7
D
Debugging, 191 Default statement, 133 Define_Combine, 71 Defining a subroutine, 167 Defining Arrays, 83 Defining Constants, 49 Defining Devices, 48 Defining Latching, 64 Defining momentary mutually exclusive, 65 Defining mutually exclusive latching, 66 Defining mutually exclusive toggling, 67 Defining Variables, 51 definition headings, 47 Definition Keywords Define_Program, 54 Define_Start, 53 Definition Sections, 47 Delete file, 15
242
Index
Device number, 48 Device Numbers, 9 DEVICE.TXT, 6 Diagnostics Menu, 23 Show current devices, 23 Watch variables, 24 Diagnostics Menu <F3>, 13 Direct Assignment, 61 Downloading, 20
Axcess panels & ..., 28 Editor, 27 Help on Help, 27 Keywords, 27 Master Messages, 29 Sample Program, 28 SYSTEM_CALLS, 28 Hexadecimal, 96
E
Editing commands, 32 Editor Edit Concepts, 27 Edit Keys, 27 Editor Basics, 31 EOF, 199 Expired Pulses, 44 External_Control Keyword, 210
I
Identifiers, 41 IF and the Boolean Expressions, 131 If...Else If Statements, 133 If...Else Statements, 132 Include File and System Call Keywords #Define, 186 #End_If, 187 #If_Defined, 187 #If_Not_Defined, 188 #Warn, 186 _ _Date_ _, 186 _ _File_ _, 187 _ _Line_ _, 188 _ _Name_ _, 188 _ _Version_ _, 189 Include File and System_Call Keywords, 185 Include files, 177 Include Files and System_Calls, 177 Index Value, 127 Input change, 55 Input Change Keywords, 55 Push, 56 Push_Channel, 57 Push_Device, 57 Release, 57 Release_Channel, 57 Release_Device, 57 Installation Software, 5 Installing AXCESS, 6 Installing AXCESS from disks, 6 Installing AXCESS from the AMX Control Disc (CDROM), 7 instance number, 181, 182 Integer Arrays, 124 Integrated Setup, 7
F
Factory System_Calls, 180 File information, 15 File Menu, 14 Change dir, 18 Compile, 17 Exit, 19 New, 15 Open, 14 Open Include, 15 Options, 18 Print, 17 Save, 16 Version, 18 File Menu <F1>, 13 File Option window, 19 Finding Strings, 92 Firmware, 24 Format of the Programming Language, 37
G
Getting Started, 9 Glossary, 231 Grouping feedback statements, 70
H
Help Menu, 27 Axcess Boxes, 28 Axcess Cards, 28
L
Latching, 52, 64 Level Keywords, 105 Create_Level, 105 Define_Connect_Level, 106
Index
243
Send_Level, 105 Library file, 179 Local Variables and Parameter Keywords, 173 Local Variables and Parameters, 169 Local Variables and Parameters Keywords Call, 173 Define_Call, 174 Local_Var, 174 Logic errors, 191, 195 Logical and bitwise operator abbreviations, 117 logical expression truth tables, 115 Logical Operators, 114 Look and feel, 181
P
Parameter, 170 Parameter mismatch, 22 Parts of an output channel, 63 Pass Thru window, 26 Passing values back to the caller, 171 Pausing Waits, 158 Precedence Among Operators, 117 Preset, 107 Print Window, 17 Program Name, 54 Programming Feedback, 69 Push Window, 34 Putting Input and Output Together, 61
M
Mainline, 43 Making a Preset, 107 Managing Large Programs, 177 Master Card RS-232 Communications, 44 Misusing Wait_Until, 160 Momentary, 52, 64 monochrome mode, 10 Multiple Waits, 155 Mutually Exclusive, 65
R
Ramp, 104 Reading Levels, 107 README.TXT, 6 Receiving strings, 145 Recommended device numbers, 10 Relational Operators, 112 Removing Strings, 93 Rename file, 15 Required Equipment, 5 Reserved Words, 42 Responses from AXCESS, 209 Restarting Waits, 158 Retrieving characters, 147 Retrieving values, 129 Returned packets, 209 Run time, 87 Run Time Errors Bad assign 2dim..., 194 Bad assign Call..., 194 Bad element assign..., 194 Bad off..., 194 Bad on..., 194 Bad re-assign Call..., 195 Bad run token..., 195 Bad Set_Length..., 195 Bad to..., 194 While, 195 Run-time errors, 191, 193
N
name mangling, 181 Naming and Removing Wait_Untils, 160 Naming Waits, 157 NEWCALLS.TXT, 6 Null string, 150
O
Open a non-program file, 15 Operator Keywords, 119 And (&&), 119 BAND (&), 121 BNOT (~), 121 BOR (|), 121 BXOR (^), 122 Not (!), 120 Or (||), 120 XOR (^^), 120 Operator precedence, 118 Operator Types, 111 Operators, 111 Option window, 22 Output change, 58 Output Change Keywords, 58
244
Index
S
Search and Replace, 34 Select groups, 76 Select variable, 76 Select...Active Statement, 135 Sending Commands, 207 Sending Strings, 95 Serial data, 146 Setting uppercase and lowercase, 94 Setup Options, 7 Show Current Devices list, 23 Show current versions, 24 Show Current Versions window, 24 Simply the Basics, 37 Simulated Button Press, 35 SNDCMD.TXT, 6 Special operators, 39 Special Uses of Wait, 159 Starting a New Program, 47 Statements, 38 Storing Array Values, 84 Storing characters, 146 Storing values, 128 String expression, 87 String Keywords, 98 Redirect_String, 98 Send_Command, 99 Send_String, 99 Strings, 86 Syntax Highlighting, 19 System variable, 57
Transport functions, 49 Two-Dimensional Arrays, 127 Types of Errors, 191 TYPICAL Setup, 7
U
Uploading, 20 Uppercase vs. Lowercase, 94 Using AMX BUG, 194 Using Bargraphs, 108 Using Buffers, 145 Using Input and Output, 55 Using Levels, 107 Using Subroutines, 167 Using the Menus, 13 Using Time, Date, and Day, 163
V
Variable and Conversion Keywords, 125 Atoi, 125 Integer, 125 Itoa, 126 Itohex, 126 Variable Assignment Method, 76 Variable Types and Conversions, 123 Variable watch window, 197 Video Monitors, 10 Viewing Variables, 197
W
Wait Keywords CANCEL_ALL_WAIT, 158 CANCEL_WAIT, 158 PAUSE_ALL_WAIT, 158 PAUSE_WAIT, 158 RESTART_ALL_WAIT, 158 Wait List, 153 Wait lists, 44 Wait_Until Keyword, 159 Wait_Until list, 159 Wait_Until lists, 44 Waits and Timer Keywords, 153 What's in this Manual, 1 While Keywords, 141 Long_While, 142 Medium_While, 144
T
Text Editor, 31 The AXCESS Environment, 13 The Device-Channel Concept, 63 The External_Control Protocol, 207 The IF Statement, 132 Time, Date and Day Keywords Date, 165 Day, 165 Time, 165 Time, Date, and Day Keywords, 165 Timer Keywords, 161 Get_Timer, 161 Set_Timer, 161 Tracing program flow, 195 Tracking down your errors, 195
Index
245
033-004-1818 10/98 1998 AMX Corporation. All rights reserved. AMX and the AMX logo are registered trademarks of AMX Corporation. All other trademarks contained in this document are the properties of their respective owners. AMX reserves the right to alter specifications without notice at any time.