certificaciónoficialcomm-tec

certificaciónoficialcomm-tec
Formación oficial Comm-Tec para obtener el certificado de programador de Sistemas AMX: Manual que prepara para la realización de las pruebas de conocimientos mínimos necesarios para la realización del seminario.

p

r

o

g

r

a

m

a

d

o

r

>>

manual de programación básica AMX

Manual de productos Axcess y NetLinx

Página 1 de 1

certificaciónoficialcomm-tec

Manual de programación básica AMX
Advertencia
Este manual está en inglés. Estamos trabajando para tener listo una versión completa en castellano próximamente.

Importante
Durante el presente manual se hace referencia a unos archivos de programación que puede descargarse en la siguiente dirección: http://www.amx.com/webtraining/intro_amx_prog/code_files/Tutorial_Program_Fil es.zip Necesita el programa NetLinx Studio para practicar las lecciones que encuentra en este manual. Descárgueselo desde aquí. Nota: Si alguno de los vínculos está roto, escriba un e-mail a marketing@comm-tec.es

Table of Contents
Introduction to AMX Programming ............................................................................................................... 4 What is Axcess?.......................................................................................................................................... 4 What is NetLinx? ........................................................................................................................................ 4 The AMX Language Tutorial ..................................................................................................................... 4 Unit 1: Language Basics ................................................................................................................................. 5 Chapter 1 - Simply the Basics......................................................................................................................... 5 Introduction................................................................................................................................................. 5 Format of the language ............................................................................................................................... 5 Statements and compound statements......................................................................................................... 5 Comments within the program.................................................................................................................... 6 Identifiers.................................................................................................................................................... 7 Reserved words........................................................................................................................................... 7 Special characters and operators ................................................................................................................. 7 Chapter 2 - The Definition Sections ............................................................................................................... 8 Starting a new program............................................................................................................................... 8 Defining devices ......................................................................................................................................... 8 Defining constants ...................................................................................................................................... 9 Defining variables....................................................................................................................................... 9 Startup code .............................................................................................................................................. 10 Mainline.................................................................................................................................................... 10 Chapter 3 - Using Input and Output.............................................................................................................. 11 Controlling something over there ............................................................................................................. 11 The device-channel concept...................................................................................................................... 11 All about the channel ................................................................................................................................ 11 Push........................................................................................................................................................... 11 Release...................................................................................................................................................... 12 Push_Device ............................................................................................................................................. 12 Release_Device......................................................................................................................................... 12 Changing the state of a channel ................................................................................................................ 13 ON ............................................................................................................................................................ 13 OFF ........................................................................................................................................................... 13 TOTAL_OFF ............................................................................................................................................ 13 TO ............................................................................................................................................................. 14 PULSE ...................................................................................................................................................... 14 Direct assignment ..................................................................................................................................... 14 Putting input and output together.............................................................................................................. 15 Chapter 4 - Channel Characteristics.............................................................................................................. 16 The parts of an output channel.................................................................................................................. 16 Mutually exclusive.................................................................................................................................... 16 Putting it all to work ................................................................................................................................. 17 Programming feedback ............................................................................................................................. 18 Grouping feedback statements .................................................................................................................. 18 Chapter 5 - Your First Program .................................................................................................................... 20 The program and the panel ....................................................................................................................... 20 Unit 2: Conditionals and Waits..................................................................................................................... 24 Chapter 6 – Conditional Expressions............................................................................................................ 24 Introduction............................................................................................................................................... 24 Conditional expressions ............................................................................................................................ 25 The IF statement ....................................................................................................................................... 25 The IF...ELSE set of statements................................................................................................................ 25 Repeating IF...ELSE set of statements...................................................................................................... 26 Nesting...................................................................................................................................................... 26 The SELECT...ACTIVE statement........................................................................................................... 27 Trying it out .............................................................................................................................................. 27 The “variable assignment” method ........................................................................................................... 28

More Conditional operators ...................................................................................................................... 29 Chapter 7 – The Wait Keywords................................................................................................................... 31 Controlling time within the AMX System ................................................................................................ 31 The WAIT list........................................................................................................................................... 31 Multiple Waits .......................................................................................................................................... 32 Special uses of Wait.................................................................................................................................. 33 Naming Waits ........................................................................................................................................... 33 Cancelling, pausing, and restarting Waits................................................................................................. 33 The WAIT_UNTIL keyword .................................................................................................................... 34 Misusing WAIT_UNTIL .......................................................................................................................... 34 Naming and removing Wait_Untils .......................................................................................................... 34 Unit 3: Levels................................................................................................................................................ 35 Chapter 8 – Creating Levels ......................................................................................................................... 35 Introduction............................................................................................................................................... 35 What is a level?......................................................................................................................................... 35 Creating levels .......................................................................................................................................... 35 Chapter 9 – Using Levels.............................................................................................................................. 38 Reading levels........................................................................................................................................... 38 Making a preset......................................................................................................................................... 38 Using bar graphs ....................................................................................................................................... 38 Connecting levels...................................................................................................................................... 39 Unit 4: Arrays, Strings and Buffers .............................................................................................................. 40 Chapter 10 – Arrays and Strings ................................................................................................................... 40 Introduction............................................................................................................................................... 40 Defining arrays ......................................................................................................................................... 40 Accessing and storing array values........................................................................................................... 40 Strings ....................................................................................................................................................... 41 The string expression ................................................................................................................................ 42 Arrays as strings........................................................................................................................................ 42 String lengths ............................................................................................................................................ 42 Sending strings and arrays ........................................................................................................................ 44 ASCII codes.............................................................................................................................................. 44 Integer arrays ............................................................................................................................................ 45 Chapter 11 – Working with Arrays............................................................................................................... 46 Grouping Data........................................................................................................................................... 46 Conversion keywords................................................................................................................................ 46 ITOA......................................................................................................................................................... 46 ITOHEX ................................................................................................................................................... 46 ATOI......................................................................................................................................................... 47 Array manipulation keywords................................................................................................................... 47 LEFT_STRING ........................................................................................................................................ 47 RIGHT_STRING...................................................................................................................................... 47 MID_STRING .......................................................................................................................................... 47 Finding strings .......................................................................................................................................... 48 Removing strings ...................................................................................................................................... 48 Uppercase vs. lowercase ........................................................................................................................... 49 Setting uppercase and lowercase............................................................................................................... 49 Chapter 12 – Using Buffers .......................................................................................................................... 50 Communicating to the outside world ........................................................................................................ 50 Receiving strings....................................................................................................................................... 50 Creating buffers ........................................................................................................................................ 50 Storing characters ..................................................................................................................................... 51 Retrieving characters ................................................................................................................................ 51 Clearing a buffer ....................................................................................................................................... 52 Conclusion .................................................................................................................................................... 53 Glossary ........................................................................................................................................................ 54

Introduction to AMX Programming
AMX Programming consists of the Axcess programming language and the NetLinx Programming language. Both languages are developed by AMX Corporation to allow control of devices in AMX systems. Axcess was developed in the late 1980’s as the programming language for the Axcess system. As system capabilities grew it became obvious that a major revision to the Axcess system and the Axcess programming language was necessary. In the late 1990’s AMX introduced the NetLinx system and the NetLinx programming language, a superset of the Axcess programming language.

What is Axcess?
The Axcess system is a microprocessor based control system capable of controlling the simple to the most complex devices. Its basic function is to give you complete control of every device in an AMX 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. AMX designed the Axcess programming language to be user friendly. Although there are over 90 commands, many are self-explanatory and take little time to master. If you accidentally make a mistake in your programming, the Axcess compiler finds the error and reports it to you. As a result, both minor and major changes in programming can be done quickly and easily. Axcess is not some strange language that only brilliant engineers can decipher. On the contrary, anyone with an average knowledge of computers and presentation devices should be able to understand this programming language without any difficulty.

What is NetLinx?
In the continuing evolutionary process of control systems AMX introduced the NetLinx control system. NetLinx is the most advanced control system developed in that process. The NetLinx system can not only control devices connected directly to it’s control ports and local control networks but can control and communicate seamlessly to other control systems and devices on Ethernet networks and the Internet. The NetLinx hardware takes the experience gained from more than a decade of Axcess system installations to make a more powerful control system. To enable this giant step in system development the Axcess programming language, the basis of the Axcess control system, was enhanced and supplemented to provide the programming power for NetLinx.

The AMX Language Tutorial
This tutorial takes the approach of teaching the common elements of both the Axcess and NetLinx languages while developing real world AMX control system programs. You will start with the basic commands and simple control scenarios, and progress on to more complex programming as you discover new programming functions and techniques. With the exception of additional keywords and objects in the NetLinx programming language, there are very few differences in many programs. The one thing that must be kept in mind however, is the understanding of which master processor, Axcess or NetLinx, will run the program, therefore which compiler is used to compile the program. Unless specifically noted, any references to the Axcess system and programming language will also apply to the NetLinx system and programming language.

the operator used to set a variable equal to a value is “=. As you progress through the chapters you will develop a simple Axcess program containing these basic features. For example. Statements can also involve mathematical or logical operations when operators are used. You will frequently have to group several different statements together into one compound statement. An operator is a character that performs a specific mathematical or relational function. For example.1] { IF (X = 1) { Y = 2 Z = 3 } } Statements and compound statements During programming. meaning that the source code is independent of tabs and carriage returns. The compiler will point out this error to you if the quantities are different after compiling. A keyword is a word or series of words that signifies the operation for the system to execute.RELAY]. each subsection of a section is slightly indented. it is advised to use a consistent method of code placement in order to make the code more readable.Unit 1: Language Basics Chapter 1 . In this manual. The most common example of compound statements occurs with the PUSH keyword. The braces “{ }” are used to enclose this type of statement. Because of this. The number of open braces “{” and close braces “}” must be the same in your program. that is. the statement to turn on a particular channel is ON[RELAY_CARD. Compound statements are used if several statements are to be executed in a situation where program syntax will allow just one. That keyword and all its parameters form the statement.) PUSH[PANEL.” As expected. Compound statements give you the ability to group multiple statements together into one unit. For example: PUSH[PANEL.1] { ON [RELAY_CARD. most of the keywords and operators require a complete statement.5] X = 5 } . an “outline” format is used.Simply the Basics Introduction This unit will help you start writing AMX programs. much like grouping sentences together into one paragraph. Format of the language The AMX languages can be written in a free format. However. the statement used to set variable X to the number 5 is X = 5. By the end of this unit you should be familiar with several concepts: • Basic ground rules for writing AMX programs • The device channel concept • The different sections that make up an AMX program • How Axcess executes a program • Basic input and output functions • Simple feedback. the keyword to turn a channel on is merely ON. (This keyword is explained in depth later. and you will build on this program in later units. The statements are executed in the sequence in which they are programmed.

5] } Since there is one (and only one) statement after the line PUSH[PANEL.2] (* { (* statement(s) } PUSH[T_PANEL. A comment is a description or remark that is not considered part of the actual program. channel] Enclose the location of a storage space in an array Enclose the instance number for use with a System_Call Enclose a variable to be turned on or off () Parentheses Enclose the expression after an If statement Enclose a mutually exclusive set in the Define section Group a mathematical operation Notes: The uses of braces. They have no effect on the actual operation of the program. the variable X is assigned the value of 5. If changes have to be made. but are recommended.1] ON [RELAY_CARD. braces could be added around the statement to make it easier to read: PUSH[PANEL. descriptions of Push statements are very useful. If you only needed the relay to be turned on. However.1] { ON [RELAY_CARD. *) DEFINE_DEVICE VCR = 1 (* Video cassette recorder *) CD = 2 (* Compact disc player *) You can place any number of comments in your program. you can merely look for the label of the section you need to edit. Also. Name Braces Brackets Comments within the program AMX programming languages allow you to place helpful comments inside your program.3] (* SLIDE preset *) *) VHS preset *) *) V_PROJ preset *) . and parentheses cannot be interchanged within the program. Special operators Operator {} [] Function Combine several statements into a compound statement. See the following example: (* This section will define all the devices used. Enclose the device-channel: [device.In this example. relay 5 on RELAY_CARD is turned on. brackets. The open brace indicates the beginning of the compound statement. They are especially helpful in a long program.1].1] (* { (* statement(s) } PUSH[T_PANEL. even if the text is separated over several lines. As illustrated in the next example. It is wise to use comments. braces are not needed.5] Or if you prefer. and the close brace ends it. the compiler will pass over these. PUSH[T_PANEL. Any text after (* and before *) will not be compiled. when the program is compiled. where you can label each part of the program for future reference. the statement could have been written like this: PUSH[PANEL. when button 1 on PANEL is pressed.

VCR3_SELECT o Invalid identifiers: 3VHS. For example. numbers. do not choose the same name later for a different identifier. The guidelines for identifiers are as follows: • They must begin with a letter followed by any combination of letters. constant. Special Mathematical Operators Operator () * / % + – Function Parentheses Multiply Divide Modulus Add Subtract Operator < > <= >= <> = Function Less than Greater than Less than or equal to Greater than or equal to Not equal to Equal to . and CD_SELECT could represent the current compact disc player. Touch_Panel is the exact same identifier as • TOUCH_PANEL The identifier must be unique. No spaces are allowed. Reserved words There are certain words that are reserved as keywords or functions. T_PANEL could represent an AMX Touch Panel. and the V_PROJ preset of the device T_PANEL much faster. VHS preset.{ (* statement(s) *) } This will help you find the SLIDE preset. PLAY could represent the first channel. TOUCH_PANEL. or underscores. or variable. o Valid identifiers: CD3. Special characters and operators There is also a complete set of symbols that are used within the program. PUSH cannot be used as an identifier. These symbols represent a wide variety of characters and operators. These are integral to the system and cannot be redefined or used as identifiers. CD PLAYER. Once you define VHS3. *RGB4 • The identifier must have less than 26 characters. For example. For example. • Identifiers are not case sensitive. because the system recognizes it as a keyword. Identifiers Identifiers are used to denote a device.

you can reference device 1 with the name VCR. you might want to keep the headings there for future reference. Each device connected to the master must have a unique device number. in NetLinx Studio you are not given an empty file with which to work. and variables are formed. you can start writing your first program! When you begin a new program. they create the materials the main program needs.Chapter 2 . Open NetLinx Studio and create a new program using the Axcess template. Card 1 may have device number 1. a CD player. you should first label each device in the system. However. Any time these device numbers are referenced in the program. Although the definition sections are not used within the main program. Suppose you have a VCR. Two relay cards. Whenever you use this device name in your program. channels are given different characteristics.The Definition Sections Starting a new program Now that the ground rules are laid out. also referred to as a source code file. you will be able to build an excellent foundation for the main part of your program. However. and it lets you name the devices. and lights. . and keep those that you do. It is placed at the beginning of the program. If you do not have any statements under one of these headings. This is the function of the DEFINE_DEVICE section. one in slot 4 and one in slot 5. = 128 (*AXT-CA10 TOUCH PANEL*) From this point on. device 2 with the name CD. with a long list of devices connected to the control networks.) DEFINE_VARIABLE DEFINE_LATCHING DEFINE_MUTUALLY_EXCLUSIVE DEFINE_START DEFINE_EVENT (Used in NetLinx programs only. The definition sections that are given to you are the following: • • • • • • • • • DEFINE_DEVICE DEFINE_CONSTANT DEFINE_TYPE (Used in NetLinx programs only. these numbers can be difficult for a programmer to remember. Defining devices When you start writing a program. the master checks the corresponding device. you also want to control a projection screen. If you develop a good understanding of the Define statements. will control these (the first card handles both the screen and drapes). your program will not operate any differently.) Instead.) DEFINE_PROGRAM Feel free to delete any of these headings you do not need. and 3. some drapes. Here is what your DEFINE_DEVICE section should look like: DEFINE_DEVICE VCR CD CASS RELAY LIGHTS TP = = = = = 1 2 3 4 5 (*AXC-IR/S (*AXC-IR/S (*AXC-IR/S (*AXC-REL8 (*AXC-REL8 #1*) #2*) #3*) #1*) #2*) Begin writing your program copying the programming sections you see in this tutorial. and you are controlling them with the first three cards in an Axcess CardFrame. and so on. A Touch Panel will be used to control all of these devices. Even the immediate startup procedures of the AMX control systems are within a definition section. These cards have device numbers 1. 2. Additionally. and card 2 may have device number 2. You should start writing your program by first defining the devices in your system. Devices and their channels are given names. Assigning actual names to these devices is much easier. (See the NetLinx Studio Tutorial for more information. and a cassette deck. the compiler will automatically use the corresponding device number to reference the device. there are several definition headings to signify what should be defined in each section.

but keep the DEFINE_VARIABLE header because you will be using them in the future. It obviously helps when you need the system to retain values for the variables. you don’t have to remember that it is channel 1 of the device—just use the constant PLAY and the system knows to use channel 1.535. As a general rule. . Later in your program when you need to activate the Play function of the VCR. it will remain 3 when the system is reactivated. PLAY on the VCR control card might be channel 1. Defining variables Variables are places to store data that will change as the program is executed. If you make this mistake. (If. The process of defining them is very similar to defining devices. Once the system is turned off. For example. and cassette deck devices have channels that activate the various transport functions. For instance. DEFINE_CONSTANT (* TRANSPORT (IR CARD) CHANNEL NUMBERS *) PLAY = 1 STOP = 2 PAUSE = 3 FFWD = 4 REW = 5 (* THE RELAY CARD CHANNEL DEFINITIONS *) SCREEN_UP = 1 SCREEN_DOWN = 2 SYS_POWER = 3 DRAPE_OPEN = 4 DRAPE_CLOSE = 5 DRAPE_STOP = 6 (* THE LIGHT LIGHT_FULL = LIGHT_MED = LIGHT_LOW = LIGHT_OFF = CARD CHANNEL DEFINITIONS *) 1 2 3 4 The value of the constant PLAY is 1. In your first program you will not be using variables.Defining constants Constants are identifiers whose values remain unchanged throughout the entire program. the numeric range is from 0 to 65. If a certain variable equals 3 when the Axcess control system is shut down. You could define these channel numbers as constants in your program to make it more readable. the result is 65. if you subtract 20 from 10. In your system. but this type of error could work its way into large programs.525). the VCR. Assigning a value to an identifier in this section locks that value to the identifier for the entire program. if you need those variables to be reset when the system is turned on. This function has both advantages and drawbacks. The DEFINE_MUTUALLY_EXCLUSIVE. and FWD on the slide control card might also be channel 1. You will probably come across this if two cards do not have the same channels for the same functions. variables do not lose their value. If one integer variable is subtracted from another. making it possible to use descriptive names instead of just numbers in your program. Think of a variable as an “anything box. the compiler will notify you with a “Duplicate symbol” error message upon compiling. By definition. you do subtract a larger number from a smaller number. STOP has a value of 2. Play is usually channel 1 and Stop is channel 2. and DEFINE_TOGGLING sections are also explained later.” nearly anything can be placed in here. However. CD player. Both of these values cannot be changed anywhere in the program.535. DEFINE_LATCHING. This may seem obvious. PLAY and FWD can both equal 1. a variable can represent a number. More than one constant can have the same number. the result will be positive. the same constant cannot reference more than one number. they must be reset manually within the DEFINE_START section. the result “wraps around” at 65. however. For example. such as Play and Stop. For integers.

Mainline is the heart of the AMX control system program. and quit.STOP] PULSE[CASS. This has no real function except to tell the control system where the actual program begins. Most programming languages have a beginning and an end.STOP] PULSE[CD. They cannot be executed again until another system power-up. the program that was last loaded into the system will begin to operate. continue until they are finished. the statements needed to do this should be in this section.STOP] (Pulse is explained later in more detail. Mainline Before you begin the main program. and they are run only once on power-up. However. These statements are placed under the DEFINE_START header. variables retain their values even if the system loses power. Remember. The most important feature of mainline is that it runs in a continuous loop.Startup code When the AMX control system is turned on. Mainline is like a circle: when the Master gets to the end. . you can tell Axcess to run a series of statements immediately when the system is turned on. Mainline is the section of the program that actually “runs” while the Master is operating. Here is what your DEFINE_START section should look like: DEFINE_START PULSE[VCR.) If variables need to be reset to certain values. they start at the top. it goes back to the DEFINE_PROGRAM header and passes through that section again. It is used simply like this: DEFINE_PROGRAM (* YOUR PROGRAM STARTS HERE. you may want to reset all three decks to STOP when the system is powered up. In your program. *) The DEFINE_PROGRAM header marks the start of what is called mainline. you must have the DEFINE_PROGRAM header.

Most devices. These inputs and outputs are referred to in the program as a “device-channel. When a button is pressed on a control panel. All about the channel Almost all methods of control using an AMX system require the use of channels on devices. When there is an input change. the “something over here” is usually some kind of control panel. If the channel has been turned on. In mainline you define what happens when these inputs occur. The operation or operations following this PUSH statement are only executed once after the channel is turned on. the Master executes the statement(s) in the program associated with the input change. have channels which either accept an input. ICSNet. But how do you get your inputs in the program? How do you generate an output? The answer: you use devices and channels. the same reference could look like this: [VCR. This concept of the device-channel is the most basic concept of the entire AMX control system.Using Input and Output Controlling something over there The basic idea behind remote control is to do something over here to make something happen over there. Every channel has two aspects: the input function and the output function. as it is the most common way that the program communicates to the outside world.PLAY] Using device names and constants is obviously much more readable. The device-channel concept Everything that an AMX system controls is controlled through a device in the system. There are six keywords used in conjunction with input changes: • • • • • • PUSH RELEASE PUSH_DEVICE RELEASE_DEVICE PUSH_CHANNEL RELEASE_CHANNEL Push The PUSH keyword is used to find out if a channel has had an input change from “off” to “on. The input change alerts the Master to scan your program for a reference to that input.1] This device-channel references channel 1 of device 5. If device names and constants are used instead of numbers.” which is written like this: [5.” such as when a button is pressed. the Master passes through the DEFINE_PROGRAM section once to see if the change is referenced.Chapter 3 . such as a wireless remote control panel or a Touch Panel. generate an output. ICSHub and Ethernet. In an AMX system. the corresponding PUSH statement is activated. The “something over there” can range from a simple relay to a complex lighting system. such as a Touch Panel or a relay card. the input function of the button sends an input change to your program. . Each device communicates to the master through control networks such as AXlink. or both. If so.

and PLAY is defined as a constant with a value of 1. NOTE: PUSH_CHANNEL and RELEASE_CHANNEL cannot both have a non-zero value during the same pass through mainline. RELEASE_DEVICE would be equal to the device number of PANEL. Release_Channel RELEASE_CHANNEL. This variable is set when a channel is turned on. . This variable will have the same value for only one pass through the program. A device name or constant can be used in place of a literal number.PLAY] { Y=1 } Push_Device 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 PANEL was pressed. This system variable is used in a program in the same manner as PUSH_CHANNEL. the following is the same: PUSH[PANEL. If a button for device PANEL was released. except that the statements following a RELEASE statement will be executed if the associated channel is released. This system variable is used in a program in the same manner as PUSH_DEVICE. PUSH_DEVICE will contain zero. Release_Device RELEASE_DEVICE is a system variable that stores the number of the device containing the channel whose button was most recently released.PLAY] { Y = 2 Z = 3 } Following the PUSH statement is the operation to be executed when the PUSH occurs. For example: PUSH[128. If more than one event must happen. At least one will always be zero. Push_Channel PUSH_CHANNEL is the similar to PUSH_DEVICE. At least one will always be zero. except in this case the channel number that was most recently turned on is stored inside the variable. PUSH_DEVICE would be equal to the device number of PANEL.1] { Y = 2 Z = 3 } If PANEL is defined as device number 128. RELEASE[PANEL. (See the earlier discussion on compound statements. If no channel has been turned on. stores the channel whose button was most recently released.The PUSH keyword requires two parameters: a device number and a particular channel enclosed in brackets. and it remains constant until the end of mainline is reached. a compound statement must follow the PUSH.) Release The RELEASE keyword is used in the same way as a PUSH. NOTE: PUSH_DEVICE and RELEASE_DEVICE cannot both have a non-zero value during the same pass through mainline.

For instance. If the channel or variable is already on. activating channel 5 on a relay card activates relay number 5. in this case. ON The ON keyword simply turns on a channel or variable. turning it “on” gives it a value of 1. and you want it to activate a different device-channel.2] OFF[TEMP] This turns off channel 2 of device 1. TOTAL_OFF The TOTAL_OFF keyword acts in the same manner as OFF. which is a message to the output function of a channel. the device starts the operation that is associated with the channel. The keywords to do this are: • • • • • • ON OFF TOTAL_OFF PULSE TO MIN_TO When you use one of these keywords to activate a channel in a device. whereas channel 5 on an infrared/serial card causes it to generate the infrared pattern it has stored at location 5.2] ON[TEMP] This turns on channel 2 of device 1. Here are two different examples: ON[1. This sets the value of the variable TEMP to 1. This sets the value of the variable TEMP to zero. the value is 1. The next series of keywords allow you to activate channels based on an input change. A variable is considered “on” if it contains a nonzero number. This activation is called an output change. If a variable contains the value zero. . it is considered “off. but doing so does not actually cause an output change. Following are brief definitions of each of the output change keywords. and turning it “off” gives it a value of 0. Here are two different examples: OFF[1. The channel or variable will remain off if it is already off.Changing the state of a channel So now you can respond to an input change in your program. Mutually exclusive sets are discussed later in this unit.” OFF The OFF keyword turns a channel or variable off. When a variable is activated as a channel. its status will remain unchanged. Variables can be used as output channels also. except that it also turns off the status of a channel or variable that is in a mutually exclusive set.

When the device-channel of its PUSH is released. OFF. Thus assigning a value directly to a device-channel changes the output of the channel. The MIN_TO keyword has the same conditions as the TO keyword: • • • It must be used only below a PUSH statement. It cannot be used with the WAIT keyword. . In most other situations. 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.) It cannot be placed within the DEFINE_START section. the keywords ON.1] = 1 This statement will send an output change to channel 1 of device PANEL. The PULSE keyword was used to activate the three decks’ Stop function. Once the time elapses. DEFINE_MUTUALLY_EXCLUSIVE. telling the channel to turn on since the master interprets any non-zero number as “on. When the device-channel referenced by the PUSH statement changes from OFF to ON. 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. The duration of this pulse is one halfsecond. (This will be explained later. and DEFINE_TOGGLING. and TO are more appropriate. the TO statement stops activating its device-channel or variable. refer back to the discussion on DEFINE_START. The pulse time remains the same value until it is changed within the program. the channel or variable is turned off. The channel or variable will act under the rules set by DEFINE_LATCHING. As an example. the MIN_TO starts activating the device-channel or variable in the brackets following it.PULSE The PULSE keyword turns on a channel or variable for a certain amount of time. When the device-channel of its PUSH is released. It cannot be used with the WAIT keyword. but it can be changed if necessary with the SET_PULSE_TIME keyword. It cannot be placed within the DEFINE_START section. For example: [PANEL. For example: SET_PULSE_TIME (12) This sets the current duration of future pulses to 1. The pulse time is measured in tenths of seconds.” Putting this statement in mainline will make the channel be forever on. Direct assignment There is another method of generating an output change. the TO starts activating the device-channel or variable in the brackets following it. The default value is one half-second or five tenths of a second. When the device-channel referenced by the PUSH statement changes from OFF to ON. but it does not involve the use of any keywords.2 seconds. Using direct assignment is only appropriate in feedback statements. The To keyword has several conditions: • • • It must be used only below a PUSH statement. the MIN_TO statement stops activating its device·channel or variable if the button was held for at least the minimum amount of time as set by the pulse time. MIN_TO The MIN_TO keyword is used to activate a channel or variable for at least a minimum amount of time or as long as the corresponding device-channel of its PUSH statement is activated.

followed by a device-channel reference.FFWD] } PUSH[TP. you can write the code that can actually accomplish this. “OK. replacing VCR with CD and CASS where needed. there are actually five separate but similar statements.1].1] { PULSE[VCR. and PLAY. you will have button numbers 1 through 5 activate the five transport functions of the VCR: Play.Putting input and output together Combining input and output changes into one statement is the basis of most AMX control system programming. you need to learn about the other definition sections: those that define the characteristics of a channel. since the PUSH and PULSE statements have the words TP. the corresponding PULSE statement executes.2] { PULSE[VCR. TP and VCR are identifiers for devices 128 and 8 respectively.” You may be wondering where the numbers came from. Examine the first to see how it all fits together. The PULSE statement tells the control system. Stop. in this case [TP. VCR. or one activation of channel 1 could make all three decks play at the same time.PAUSE] } PUSH[TP. Now that you have these tools. Duplicate the above section for the CD player and the cassette deck.STOP] } PUSH[TP. Remember.PLAY] } PUSH[TP.REW] } In this code. then turn the channel off. On your Touch Panel. and PLAY is a constant with a value of 1. Also be sure to use different channel numbers for the Push statements. But before you do that. channel 1 for 5 tenths of a second. Fast Forward.4] { PULSE[VCR.” If such an input change occurs. First there is the keyword PUSH. Now that you have the transport functions of your decks programmed. This tells the control system. Pause. Here is your first section of program code: PUSH[TP.3] { PULSE[VCR. if channel 1 on device 128 receives an input change from off to on execute the statement that follows. . and Rewind.5] { PULSE[VCR. you can add the rest of the functions on your panel to the program. “Turn on device 8.

[LIGHTS. . it activates its output and status only as long as the button which activated the TO keyword is pressed.. Mutually exclusive Channels can be defined as mutually exclusive. When SCREEN_UP is activated. when one is on. the Focus channel for a certain slide projector is momentary.[CD. When a channel or variable in this set is activated.. such as a relay on a relay card. the SCREEN_DOWN channel is turned off and SCREEN_UP turns on.) shortcut is used to indicate a range of channels. these two parts act exactly the same. For example. For example: DEFINE_MUTUALLY_EXCLUSIVE ([RELAY. Members of a mutually exclusive set are placed in parentheses underneath the DEFINE_MUTUALLY_EXCLUSIVE keyword. Even after the physical output stops.. The physical part is the device-dependent physical control. all the other members of the set are turned off beforehand.1 When a momentary channel is activated with a TO keyword.LIGHT_OFF]) ([VCR. it activates its physical output as long as the button is pressed. you will be shown how to change the status behavior.[RELAY.REW]) ([CD. The status is on to let you know which channel in the set was last activated. SCREEN_UP is turned off. This is called “break before make” logic.DRAPE_OPEN]. In this chapter. You also will define the lighting relays as mutually exclusive so that you can utilize the “last button pressed” logic when you program the feedback for these buttons. In most applications. “status” is understood. however.Chapter 4 .[CASS. the physical part and the status part (simply referred to as “status”).. the status still indicates that the channel is on until another channel in the mutually exclusive set is activated. in the common language of programmers. so is the other. The projector will continue to do so until the button is released. 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 behavior of status will be described in this manner. This will allow the user to look at the panel and know which lighting preset he or she activated last. The double period (. the slide projector will focus.SCREEN_UP]. the correct terminology here is the status of all channels is momentary by default.REW]) ([CASS..DRAPE_STOP]) ([LIGHTS. which in turn changes the way a channel reacts when it is activated by the output change keywords.PLAY].PLAY]. All channels are momentary by default. Since you cannot open and close a drape all at once. does not work in the same manner. When the corresponding Focus button is pressed. The corresponding SCREEN_UP status stays on even though the relay is de-energized when the button is released. When SCREEN_DOWN is activated. a button light (“lamp”) on a button panel. However. However. consider the drape and screen channels of the device RELAY. For example. The status. The status is what records the state of the physical part.[RELAY. This is sometimes called “last button pressed” feedback.SCREEN_DOWN]) ([RELAY.[VCR.. and you cannot raise a screen and lower it at the same instant (it could damage some motors if you tried!).Channel Characteristics The parts of an output channel An output channel actually has two parts. which could cause serious damage to some devices. When a channel is turned on in a mutually exclusive set. the physical output stops. When the button is released. The SCREEN_DOWN status is now the only status turned on.LIGHT_FULL]. only one channel can be turned on at a time.PLAY]. This prevents an accidental activation of more than one channel at the same time. From this point on in the manual. you can change the way the status part of an output channel behaves. They must be defined as mutually exclusive.REW]) 1 Actually. or an infrared pattern in an infrared card.

Using the shortcut.46] { TO[LIGHTS.34] { TO[RELAY.45] { TO[LIGHTS. and lighting relays: PUSH[TP.48] { TO[LIGHTS. and the third set defines the four lighting relays as mutually exclusive.SCREEN_UP] } PUSH[TP.SCREEN_DOWN] } PUSH[TP. there will always be one channel with its status on in that group. the second set defines the three drape channels as mutually exclusive. the buttons for the VCR. you can skip down to the mainline section of the program and add these lines to activate your system power.DRAPE_STOP] } PUSH[TP.43] { TO[RELAY.DRAPE_CLOSE] } PUSH[TP. Once a channel has its status turned on in a mutually exclusive group.31] { ON[RELAY.43] { OFF[RELAY.41] { TO[RELAY.DRAPE_STOP] } RELEASE[TP. This is done to achieve “last button pressed” status for those decks. drape.DRAPE_OPEN] } PUSH[TP. unless it is turned off with the TOTAL_OFF keyword. screen.LIGHT_MED] } PUSH[TP. CD player.33] { TO[RELAY.32] { OFF[RELAY.SYS_POWER] } PUSH[TP. The fourth through the last sets also use the shortcut to define the five transport functions as mutually exclusive.LIGHT_FULL] } PUSH[TP. Putting it all to work Now that you know just how all these different types of channels operate. When you add the feedback statements to the program.LIGHT_LOW] } PUSH[TP.The first set defines the two screen channels as mutually exclusive. and cassette deck will indicate the last button selected from each group.LIGHT_OFF] } This section accomplishes several tasks: .47] { TO[LIGHTS.SYS_POWER] } PUSH[TP.42] { TO[RELAY.

the light of TP button 1 will also be on.• • • • • A press of the System Power On button turns on the SYS_POWER channel on the device RELAY. (Remember. but would show the feedback of the last PUSH not the current state. A press of the System Power Off button turns off the SYS_POWER channel on the device RELAY. after turning off any LIGHTS channel that was previously on. after turning off SCREEN_DOWN. but now you want to see some feedback on your control panel. You know what to do with the input changes and how to create output changes. The master will not do this automatically. The feedback statements can also be grouped together in a feedback section at the end of the program.PLAY] When VCR channel 1 (the constant value of PLAY) is on. Once a channel has feedback on in a mutually exclusive group. Also recall that one way of creating an output change is to assign a value directly to the device-channel.PLAY] } [TP. For example: PUSH[TP. This is a very important concept. to turn off the status of a channel in a mutually exclusive group. there will always be one channel with feedback on in that group. It is followed by an equal sign (=) and the device-channel corresponding to the source of the feedback. Grouping feedback statements The feedback statement is sometimes found after the end of a Push statement. use the keyword TOTAL_OFF.1] = [VCR.PLAY] When TP button 1 (Play) is pressed. The Screen Down button acts the same way as the Screen Up button. Feedback refers to the lighting of a button during and after it is pressed. Pressing Drape Open. Feedback involves only one statement per button. because it is the basis of how feedback works. then it turns on. For example: . until turned off with TOTAL_OFF. Programming feedback So far you have been shown how a channel’s output is affected in a program.) Since the LIGHTS channels are mutually exclusive. A press of the Screen Up button turns on the SCREEN_UP channel on device RELAY. “Take the output status of channel PLAY on device VCR.1] { PULSE[VCR. and the feedback assignment will light button 1 on the control panel. but with the opposite channels. this is in effect saying to the system. The other LIGHTS channels operate in a similar fashion. a press of the Lights Full button turns on the LIGHT_FULL channel on the device LIGHTS. its status will be on if it was the last channel activated in that set. If it is off. Notice that the feedback statement is outside of the PUSH statement. For example: [TP. If the feedback statement is included in the PUSH statement it would not operate as desired. it makes sure the other drape channels are off (due to its mutually exclusive relationship). Remember that any reference to a device-channel that does not have the keyword Push or Release preceding it is referring to the output side of the channel. When the channel is off. When the Drape Stop button is released it turns off the DRAPE_STOP relay on the relay device.PLAY] as being in a mutually exclusive group. The first part of the statement references the device-channel of the button that is going to be lit.1] = [VCR.” Since you defined the device-channel [VCR. but its status(feedback) remains on. Drape Close or Drape Stop does several things. and send it as an output change to channel 1 of device TP. both VCR channel 1 (PLAY) and the Feedback (output) of the button are turned on. you must tell the system how to light the button. This is a very important concept. the light will be off. If the value that you are assigning is another device-channel reference.

1] = [VCR.PAUSE] This feedback section will act no differently if each statement is placed under its corresponding PUSH statement. Grouping all of the feedback statements at the end of the program is fine. but in larger programs it can be a hassle to skip from the top where the PUSH is located to the bottom where the feedback statements are located.[TP.3] = [VCR. and put the feedback statements for each section right below it. however. .PLAY] [TP. Smaller programs.2] = [VCR. but it does make a difference in the readability of your program. may be easier to manage if all the PUSH statements 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.STOP] [TP. Where you locate your feedback statements inside your program makes no difference to the operation of the system.

What is important is that it operates the way in which you intend. all of the feedback is at the bottom. Notice that in this system. On the next few pages is the entire source code for the program you developed in this unit.Your First Program The program and the panel This chapter contains your first finished program and a drawing of the control panel layout. PROGRAM_NAME='STEP1' (* DATE:03/15/02 TIME:12:00:00 *) (***********************************************************) (* DEVICE NUMBER DEFINITIONS GO BELOW *) (***********************************************************) DEFINE_DEVICE VCR CD CASS RELAY LIGHTS TP = = = = = 1 2 3 4 5 = 128 . If your program does not look exactly like this one. don’t worry! Ten people could write the same program and none would look exactly the same.Chapter 5 .

SCREEN_DOWN]) ([RELAY.[CASS.LIGHT_FULL].PLAY]..SCREEN_UP].[CD.STOP] PULSE [CASS.[LIGHTS.PLAY].[RELAY.DRAPE_OPEN]..LIGHT_OFF]) ([VCR.(***********************************************************) (* CONSTANT DEFINITIONS GO BELOW *) (***********************************************************) DEFINE_CONSTANT (* TRANSPORT CHANNEL NUMBERS *) PLAY = 1 STOP = 2 PAUSE = 3 FFWD = 4 REW = 5 (* THE RELAY CARD CHANNEL DEFINITIONS *) SCREEN_UP = 1 SCREEN_DOWN = 2 SYS_POWER = 3 DRAPE_OPEN = 4 DRAPE_CLOSE = 5 DRAPE_STOP = 6 (* THE LIGHT LIGHT_FULL = LIGHT_MED = LIGHT_LOW = LIGHT_OFF = CARD CHANNEL DEFINITIONS *) 1 2 3 4 (***********************************************************) (* VARIABLE DEFINITIONS GO BELOW *) (***********************************************************) DEFINE_VARIABLE (***********************************************************) (* LATCHING DEFINITIONS GO BELOW *) (***********************************************************) DEFINE_LATCHING (***********************************************************) (* MUTUALLY EXCLUSIVE DEFINITIONS GO BELOW *) (***********************************************************) DEFINE_MUTUALLY_EXCLUSIVE ([RELAY..REW]) ([CD.STOP] .[RELAY...REW]) (***********************************************************) (* STARTUP CODE GOES BELOW *) (***********************************************************) DEFINE_START PULSE [VCR.REW]) ([CASS.PLAY].DRAPE_STOP]) ([LIGHTS.[VCR.STOP] PULSE [CD.

20] { PULSE[CASS.REW] } PUSH[TP.9] { PULSE[CD.21] { PULSE[CASS.3] { PULSE[VCR.PAUSE] } PUSH[TP.19] { PULSE[CASS.PAUSE] } PUSH[TP.(***********************************************************) (* THE ACTUAL PROGRAM GOES BELOW *) (***********************************************************) DEFINE_PROGRAM PUSH[TP.17] { PULSE[CASS.4] { PULSE[VCR.PLAY] } PUSH[TP.FFWD] } PUSH[TP.REW] } PUSH[TP.5] { PULSE[VCR.FFWD] } PUSH[TP.PAUSE] } PUSH[TP.REW] } PUSH[TP.12] { PULSE[CD.PLAY] } PUSH[TP.31] { ON[RELAY.2] { PULSE[VCR.1] { PULSE[VCR.32] { OFF[RELAY.PLAY] } PUSH[TP.STOP] } PUSH[TP.SYS_POWER] } .18] { PULSE[CASS.STOP] } PUSH[TP.13] { PULSE[CD.10] { PULSE[CD.11] { PULSE[CD.SYS_POWER] } PUSH[TP.STOP] } PUSH[TP.FFWD] } PUSH[TP.

PUSH[TP.PLAY] [TP.SYS_POWER] [TP.LIGHT_LOW] [TP.41] { TO [RELAY.STOP] [TP.34] = [RELAY.LIGHT_FULL] [TP.DRAPE_STOP] } PUSH[TP.12] = [CD.47] { TO [LIGHTS.31] = [RELAY.11] = [CD.21] = [CASS.48] { TO [LIGHTS.PAUSE] [TP.SCREEN_UP] [TP.34] { TO [RELAY.43] { OFF[RELAY.46] { TO [LIGHTS.LIGHT_MED] [TP.1] = [VCR.DRAPE_CLOSE] [TP.45] { TO [LIGHTS.41] = [RELAY.REW] [TP.43] = [RELAY.18] = [CASS.PLAY] [TP.LIGHT_OFF] (***********************************************************) (* END OF PROGRAM *) (* DO NOT PUT ANY CODE BELOW THIS COMMENT *) (***********************************************************) .20] = [CASS.33] { TO [RELAY.43] { TO [RELAY.5] = [VCR.REW] [TP.17] = [CASS.LIGHT_MED] } PUSH[TP.PAUSE] [TP.42] = [RELAY.3] = [VCR.10] = [CD.DRAPE_STOP] } RELEASE[TP.42] { TO [RELAY.DRAPE_OPEN] } PUSH[TP.PLAY] [TP.FFWD] [TP.DRAPE_OPEN] [TP.19] = [CASS.REW] [TP.45] = [LIGHTS.2] = [VCR.13] = [CD.32] = (1-[RELAY.LIGHT_FULL] } PUSH[TP.DRAPE_CLOSE] } PUSH[TP.9] = [CD.SCREEN_UP] } PUSH[TP.SYS_POWER]) [TP.PAUSE] [TP.LIGHT_OFF] } (* FEEDBACK *) [TP.SCREEN_DOWN] } PUSH[TP.STOP] [TP.DRAPE_STOP] [TP.LIGHT_LOW] } PUSH[TP.FFWD] [TP.FFWD] [TP.4] = [VCR.STOP] [TP.33] = [RELAY.48] = [LIGHTS.46] = [LIGHTS.SCREEN_DOWN] [TP.47] = [LIGHTS.

Your panel could now look like the one below: You now have fewer buttons than you did before. In the program you will use conditional expressions to select the correct function of the Transport buttons. This will not be a one-to-one program because the Transport buttons each have three possible functions. What you want to happen with this panel is that the user selects the deck with a Select button.” That means that each button has one and only one function. with no special conditions or considerations. The control panel has a separate section of buttons for each piece of equipment. But suppose you want the same number of functions with fewer buttons. Additionally. it really doesn’t show the power of the AMX programming languages. then control it with the Transport buttons. and one set of transport buttons. The program is what we at AMX call “one-to-one.Unit 2: Conditionals and Waits Chapter 6 – Conditional Expressions Introduction While your first program may look complicated at first. which will have its feedback turned on when the system is powered and off when the system is not powered. you could have one button for each piece of equipment to select each deck. with a set of buttons that selects which piece of equipment the buttons control. In your program. A common solution is to have several groups of buttons with similar functions reduced to one group. . the System Power has been reduced to one toggling button.

is ignored. If the conditional expression is false. Either the master continues in the direction it is going. you might become lost. and a zero for a false result. it assigns a 1 for a true result. Every IF statement must be followed by a conditional expression enclosed in parentheses. then Statement 2 is executed. or it must jump to a different section. Statement 2.. the master executes Statement 1 and then continues with whatever statements follow. . The IF. the master executes a function independent of the “true” conditional expression. with the addition of one more branch. This provides the beginning of a conditional execution of statements. Is the left road heading north? Is the right road heading east? This is what the master must do whenever you branch off in different directions in your program.. Suddenly you come upon a fork in the road. A conditional expression can have one of two results. Remember that Statement 1 is automatically ignored if the expression is false. any non-zero value is true and a zero value is false. The IF statement The most common keyword in AMX programming that uses conditional expressions is the IF keyword. Statement 1 is ignored. If the conditional expression is false.ELSE set of statements This is similar to the basic IF statement. When the master evaluates a conditional expression. Which way should you go? If you guess. underneath the ELSE statement. Therefore you judge certain conditions before continuing. The structure is as follows: IF(conditional expression) { Statement 1 } If the conditional expression is true. If the conditional statement is false. true or false. For example: IF(conditional expression) { Statement 1 } ELSE { Statement 2 } If the conditional statement is true. Picture yourself walking along a path in the country. then Statement 1 is executed. In AMX programming.Conditional expressions A conditional expression is used to tell the system whether or not to execute a particular function or functions in the program.

This “branch within a branch” is called nesting. For example: IF(X = 5) { Statement 1A IF(Y = 10) Statement 1B } ELSE Statement 2 By using the braces. That is. ELSE set of statements.. be sure to use braces.. it goes on to the rest of the program.. An IF can be within an IF within an IF.ELSE set of statements Using IF. it executes the final ELSE statement. you isolate the IF(Y = 10) statement from the IF. The master pairs the second IF statement with the ELSE. and so on. However. the last ELSE statement is not necessary. because the compiler associates the ELSE with the “closest” IF statement.. Nesting Once the master processor is traversing along a branch (for example. When you are nesting IF. For example: IF(Conditional expression) { Statement 1 } ELSE { IF(Conditional expression) { Statement 2 } ELSE { IF(Conditional expression) { Statement 3 } ELSE { Statement 4 } } } The last ELSE statement placed at the end of the conditional branching operates as a default statement.. you can force the compiler to associate the ELSE with IF(X = 5). The master will stop conditional evaluation at the first true conditional expression and execute the associated statements. ELSE statements.Repeating IF. After completion. such is not the case. By repeating the IF.. ELSE statements multiple paths can be created. However. Statement 1 above).. The second IF statement is not supposed to have an ELSE counterpart in this example.. ELSE allows two different paths for conditional branching.. you can tell it to branch off again with another IF statement.. . The only restriction is the amount of memory available. if the master processor does not find a true IF statement. With braces. Look at the following incorrect example: IF(X = 5) Statement 1A IF(Y = 10) Statement 1B ELSE Statement 2 You can see by the alignment of the ELSE statement with the IF(X = 5) that these two should be associated.

no code of any Active statement will be executed. The preferred method of implementing “select groups” is to use one variable and change its value based on which deck is selected.ACTIVE: SELECT { ACTIVE(conditional expression 1): { Statement 1 } ACTIVE(conditional expression 2): { Statement 2 } ACTIVE(conditional expression 3): { Statement 3 } ACTIVE(1): { Default statement } } Here. is evaluated until one is found to be true.etc. You can.. they can overflow the Master processor memory and crash the entire system. it uses less memory and it runs faster.. create your own default for a SELECT.ACTIVE has no default statement.. Obviously it is much better to use SELECT. since SELECT. This allows the easy placement of several branches from one path..ACTIVE is much preferred to multiple IF. in order.ELSE statements. Trying it out Now you can write the code for your new panel layout...ELSE set of statements.. This makes the last ACTIVE statement the default statement. *) } Each one of the conditional expressions.. however.. . and will execute only if all of the conditions of the previous ACTIVEs are false. Using a SELECT.ACTIVE statement There is a way to make nesting easier: the SELECT. you will need to update your definition sections a little..The SELECT. The statements associated with that true expression are then executed. When using the IF.. Here is the format: SELECT { ACTIVE(conditional expression 1): { Statement 1 } ACTIVE(conditional expression 2): { Statement 2 } ACTIVE(conditional expression 3): { Statement 3 } (* . the last ACTIVE will always be true (remember in AMX programming a 1 is true and a 0 is false). If too many IF...ELSE statements are chained together.ACTIVE if none of the conditions evaluate as true? In such a case... however.. the default statement following the ELSE is executed... and the path then flows to whatever statements follow the closing brace.ACTIVE in such situations. Before you do. the code following the ELSE is the default statement—if the condition of the IF is false... So what happens in a SELECT...ACTIVE statement.

PAUSE] } PUSH[TP.3] { DECK=CASS } You can reduce the number of transport sections from three to just one by using the variable DECK as the device number in the TO statements. This method is actually more powerful than other methods.19] { TO [DECK. These statements for the selection buttons. Here is your Select buttons’ code: PUSH[TP. which the master will interpret as [2. For a NetLinx master you will define the variable to contain NetLinx device address information by using the DEV keyword as shown below: Axcess DEFINE_VARIABLE DECK NetLinx DEFINE_VARIABLE DEV DECK To this variable you will assign the device number of your currently selected deck. First add just one variable.21] { TO [DECK.1] { DECK=VCR } PUSH[TP.18] { TO [DECK.FFWD] } PUSH[TP. as it provides more flexibility while using a lot less code. This will be the select variable. Assigning different values to one variable depending on what is selected.20] { TO [DECK. The feedback for the transport section works in the same manner as the control section. This assigns the value 2 (the constant value of CD) to the variable DECK.STOP] } PUSH[TP.1]. CD. no mutually exclusive variables are necessary. Here’s the section of code: PUSH[TP.The “variable assignment” method This is the preferred method of programming select groups.2] { DECK=CD } PUSH[TP. First you press the CD Select button. and this is the only deck transport section of programming needed in the whole program! But how does this work? Suppose you want to play the CD player.REW] } Notice that no IF statement is necessary. however.AXS). Now the device-channel references of the TO transport statements will reference device number 2 (the CD device). Pressing button number 17 on the Touch Panel will activate [DECK. How you define this variable depends upon whether you are programming for an Axcess master or a NetLinx Master. instead of using VCR.PLAY] } PUSH[TP.17] { TO [DECK. and CASS. are something new: . The feedback statements use the DECK variable as the device from which to get the feedback.PLAY]. DECK to the program you wrote previously (or STEP1.

Here are those specific rules: AND Both statements must be true for the result to be true. On the contrary. the master first evaluates the conditional expression.2] = (DECK=CD) [TP. and a zero (”off”) to the false ones. Recall that assigning a 1 to a device-channel is the same as turning the output of a device-channel on Conditional Operators The previously discussed IF and IF.ELSE statements can only base the program flow on one condition. OR At least one of the conditions must be true for the result to be true..” The result is found by basing the conditions of the statements against the rules set by the conditional operator. NOT If the statement is true. like all feedback statements. are direct assignment output changes. the source of the assignment is a conditional expression.1] = (DECK=VCR) [TP. You can.[TP. For example: IF((X = 10) AND (Y = 5)) { Statement 1 } If the end result of the conditional expression is true. otherwise it is replaced with a zero. OR. The conditional operators can be abbreviated in your program as shown below: Conditional Operator Abbreviations Abbreviation && || ^^ ! Function Logical AND Logical OR Logical XOR Logical NOT Abbreviation & | ^ ~ Function Bitwise AND Bitwise OR Bitwise XOR Bitwise NOT In most conditional expressions. XOR Only one statement can be true for the result to be true.) Thus the direct assignment will assign a 1 (”on”) to the Touch Panel button for which the expression is true. however. the result is true. If the end result is false. only one of these will be evaluated as true because a variable cannot have two different values at one time. . XOR. however. This expression uses only one statement. the system simply ignores Statement 1. the result is false. The conditional operators used in AMX systems are AND. These are placed in between the two conditions after the IF statement. (Remember. A text formula can be followed to find that result: “If <condition 1> is <its condition (true or false)> < conditional operator> <condition 2> is <its condition>. if the condition is false. then the result of the expression is <result of statement conditions>. This operator sets the rules for determining the end result. and NOT.. the possible conditions of two statements are analyzed to achieve one result. If the expression is evaluated as true. In interpreting this kind of feedback statement. combine two of these conditions with a conditional operator.3] = (DECK=CASS) These statements. the expression is replaced with a 1. the system continues with Statement 1.

We can use the NOT operator to allow us to program the single power button on this touch panel layout.SYS_POWER] .31] { [RELAY. The code for this button is shown below: PUSH[TP.” The statement would have been true if NUM2 had been equal to 3.SYS_POWER] } Each press of the button will toggle the state of the SYS_POWER relay. using the NOT operator on a device channel will change its state from off to on or on to off. Since the state of an output channel can be on (1) or off (0). because in an AND expression both statements must be true. The feedback for this button will track the state of the relay channel: [TP.SYS_POWER] = NOT[RELAY. Insert the variables from the example into the text formula: ”If NUM1 = 5 is true and NUM2 = 4 is false.31] = [RELAY. then the result of the expression is false.Consider the following IF statement: IF((NUM1 = 5) AND (NUM2 = 4)) Assume that it has been previously defined that NUM1 = 5 and NUM2 = 3.

If you use relay 7 (the next available relay on the card). the master executes the statement or compound statement associated with the expired WAIT keyword. the master scans this list. and so on.AXS). In your program. one half-second later. a WAIT of 20 is two seconds. the source equipment is already on and there will be no “pop” when the amp is turned on. The program flow does not stop when a WAIT is encountered. and if any WAITs have come due.) Time in the WAIT list is measured in tenths of a second. Suppose in your system you have two relays controlling system power. The WAIT List The most common keyword relating to time is the WAIT keyword. you’ll just add more functions to the existing buttons.AMP_POWER] WAIT 5 OFF[RELAY. A WAIT of 10 is one second. You will build on your previous program (STEP2. Up to 50 WAIT references are allowed in the list at a time. the master places the statement associated with the WAIT keyword into a list in memory and continues on with the rest of the program. there are a variety of timing keywords available for your use. In most cases a one half-second delay is enough. One is for the audio amplifier.RACK_POWER] } ELSE { ON[RELAY.AMP_POWER] } } . This chapter will help you learn each of these keywords and show you how to apply them to your programs. Here’s the new code for the System Power button: PUSH[TP. In many cases. you will first add a constant definition for your new relay and change the name of the existing system power relay to RACK_POWER.Chapter 7 – The Wait Keywords Controlling time within the AMX System Within the AMX system.RACK_POWER] WAIT 5 ON[RELAY.RACK_POWER]) { OFF[RELAY. Instead. you want the rack power to come on first (relay 3) when the power is turned on. or they can be delayed until certain conditions are right. As for the System Power button. the amp power should turn on. a time delay is desired between powering up the source equipment and powering up the audio amplifier. When you turn the power off. which is used to activate functions after a specified delay time has elapsed. The reason is that if both are powered up at the same time. Functions can be delayed for a few seconds. (Refer to the Axcess Programming Guide for a complete discussion of mainline and the Axcess bus. but this time you will not be changing the layout of your Touch Panel. but if there is a delay. After each pass through the program.31] { IF([RELAY. there is sometimes a loud “pop” over the audio system from the source equipment. a WAIT of 15 is one and a half seconds. and the other is for the rest of the equipment (we’ll call that “rack power”). you want the reverse to happen. the line to add to the DEFINE_CONSTANT section looks like this: AMP_POWER = 7 You will also change the constant identifier SYS_POWER to RACK_POWER.

AMP_POWER] WAIT 200 PULSE[LIGHTS. Two minutes later the lights go to the Off setting.RACK_POWER]) (* power being turned off *) { OFF[RELAY. Here is the code for the System Power Push for the described scenario: PUSH[TP. and then turns on the amp power. the rack power comes on as before. One half-second later. you want a series of timed events to take place. the screen starts to come down and the drapes start to close. In this case the master checks that channel’s status. One half-second later the rack power turns off..RACK_POWER] WAIT 1200 PULSE[LIGHTS. Multiple Wait Statements Now that you know how to delay an action for a specific amount of time.First. After one half-second has elapsed.. the Medium lighting scene is selected. which is executed if the rack power is on.SCREEN_DOWN] TO[RELAY.31] { IF (device-channel) compound statement ELSE compound statement } From this simpler outline you can more easily examine what is happening here.AMP_POWER] TO[LIGHTS.DRAPE_OPEN] WAIT 5 OFF[RELAY. Otherwise the compound statement following the ELSE is executed. you can add a little pizzazz to your system.LIGHT_OFF] } ELSE (* power being turned on *) { ON[RELAY. the amp power comes on. First the amp power is turned off. Since these statements are part of an IF compound statement. the master does not execute the compound statement following the ELSE. The next statement is a WAIT statement for five-tenths of a second (same as one half-second). The corresponding WAIT is then taken out of the list. the master evaluates the condition as true and executes the first compound statement. uses a WAIT to accomplish a time-delayed powering-down of the system. The master first turns on the rack power. and the drapes are opened. the System Power button completes just two events with a delay in between. The first statement inside the compound statement turns off the amplifier relay. its functions are just slightly different. If it is on. a different sequence happens. lights go to the Full setting. the master will execute the statement immediately following the WAIT. the WAIT is still in the Wait list.RACK_POWER] TO[RELAY. waits a half-second. Now you will make the System Power button accomplishes several more things when the power is being turned on and off. At this point. look at the organization of this set of statements.31] { IF ([RELAY.SCREEN_UP] TO[RELAY. Following the PUSH statement is a single IF. At the same time. Twenty seconds after the button is pressed. the screen is raised. The first compound statement. followed by an OFF statement to the rack power relay. Here is a simplified outline of the structure of this code: PUSH[TP.LIGHT_MED] } } . First. Suppose that when the power is being turned on. The compound statement following the ELSE is nearly the same as the one just described.DRAPE_CLOSE] WAIT 5 ON[RELAY.LIGHT_FULL] TO[RELAY. As the system continues to run. which in this case turns off the rack power.ELSE statement which has only a device-channel reference for its condition. Suppose you want a series of several events to happen when you press just one button. When the power is turned off. just like before. The master places this WAIT into the WAIT list and continues with the program.

For example: WAIT 30 ’DELAY’ Once DELAY is entered into the list. • They cannot be names that have already been assigned to buffers or subroutines • They can contain spaces. Any timed sequence of events can be accomplished with or without nested Waits. it cannot be re-entered until the first has been removed (cancelled or expired). wait twenty more seconds. If a particular Wait is already in the Wait list. The program now has a two-minute WAIT in the WAIT list for the lights to go off. or restarted. If the user turns the power back on before this WAIT executes. This is called “nesting” Waits. To name a Wait. Canceling. On the next pass through mainline. unlike other identifiers. suppose the following line appears in mainline where it will be executed every pass through mainline: WAIT 5 FLASH = NOT FLASH The first time this is executed. and Restarting Wait Statements Once a WAIT is named. This in effect creates a variable whose state inverts every half-second. Since the lighting buttons are momentary. because TO cannot be used inside a Wait. however. You don’t need to nest Waits in your program here. the line is simply ignored. Nonnested Waits. you use a Pulse to actuate the relay for just a moment. This is done. Here is the same example without nesting: WAIT 200 ON[RELAY. One halfsecond after the first execution of this statement. removing it from the Wait list. Naming Wait Statements When a Wait is given a unique name. Suppose the user just turned off the power. But what if this line is executed again before the Wait expires? Since the Wait is already in the Wait list.SCREEN_UP] Special uses of Wait Any one Wait can only be placed in the Wait list once. it cannot be placed into the list a second time until the first instance is either cancelled or expired.SCREEN_UP] WAIT 400 OFF[RELAY. and if it was non-zero it will be changed to zero.SCREEN_UP] WAIT 200 OFF[RELAY. the Wait is placed into the Wait list.” The WAIT does not continue counting down until it is resumed with RESTART_WAIT. except they affect all WAIT in the WAIT list. paused. use less code. it can be cancelled. the value in variable FLASH is inverted. but here is how it is done: WAIT 200 { ON[RELAY. For instance. the system would wait twenty seconds. Waits can appear inside other Waits. but the events of the .SCREEN_UP] } In this example. CANCEL_ALL_WAIT nullifies every WAIT currently in the list.Notice the use of the PULSE keyword. then turn off the Screen Up relay. if it was zero it will be changed to 1. it can be manipulated within the program with several keywords. the Wait will again be placed into the Wait list and the cycle will repeat for the duration of the program. named and unnamed. simply place a name in single quotes after the Wait statement. PAUSE_WAIT places a WAIT on “hold. You could use a named WAIT in your System Power PUSH routine. as you may recall. CANCEL_WAIT completely nullifies a Wait. The keywords PAUSE_ALL_WAIT and RESTART_ALL_WAIT act the same as PAUSE_WAIT and RESTART_WAIT. the power-on sequence will start. Using nested Waits is in many cases more readable than non-nested Waits. Pausing. The WAIT then continues from where it was paused. There are certain considerations in naming Waits: • They should not be previously defined constants or variables. turn on the Screen Up relay.

it checks to see if a condition is true. To do this. Y will never equal four at the end of the program. a name in single quotes is placed at the end of the statement. It would be hard to make this mistake in a small program such as the one you are working on. The CANCEL_ALL_WAIT_UNTIL keyword removes all WAIT_UNTILs from the WAIT_UNTIL list. but this problem could make its way into a fairly large program. simply add the WAIT name to the WAIT in the power-off section like this: WAIT 1200 ‘LIGHTS OFF’ PULSE [LIGHTS. Once a WAIT_UNTIL has a name. The compiler cannot detect this sort of error. If not. For each one that has. The WAIT_UNTIL in this case is completely useless. You don’t need WAIT_UNTIL in your program yet. but this program segment illustrates the misuse of WAIT_UNTIL: WAIT_UNTIL (Y=4) { (* statements *) } Y=4 Y=3 As you can see. called the WAIT_UNTIL list. the system immediately executes the sequence below the WAIT_UNTIL statement. Misusing WAIT_UNTIL Since the system only checks the status of pending WAIT_UNTILs after completely running mainline. each pass through mainline the master checks to see if any WAIT_UNTIL conditions have become true. or you will defeat the purpose of the WAIT_UNTIL statement. To do this. which is definitely not what he or she wanted.LIGHT_OFF] To cancel the Wait in the power-on section. a WAIT_UNTIL can be named. Just as it does with WAIT statements. All WAIT_UNTIL statements go into another list very similar to the Wait list. it can be cancelled with the CANCEL_WAIT_UNTIL keyword. the system does not wait for a certain amount of time to elapse. . Instead. simply add this line: CANCEL_WAIT ‘LIGHTS OFF’ The WAIT_UNTIL Keyword The WAIT_UNTIL keyword is not a true “timing” keyword. In this case it would be advantageous to name that WAIT and cancel it in the poweron section of the PUSH. the master executes the statements listed directly below the WAIT_UNTIL statement. make sure that the condition has a chance to become true. so make sure each WAIT_UNTIL statement can become true one way or another. When the condition becomes true. the system keeps the WAIT_UNTIL in the WAIT_UNTIL list until its condition becomes true. Naming and removing Wait_Untils In the same manner as a Wait. which removes it from the WAIT_UNTIL list.LIGHT_OFF WAIT will still happen! The user could end up in a very dark room.

the master will continually update the variable to contain the value of the level with which it is associated. such as volume control. these values are called levels. or tell a voltage generator card the amount of voltage to generate. that is. On a volume card. Here is the syntax: CREATE_LEVEL device. Since this association only needs to be done once. . levels relate to the volume levels of the card. it can only have an “on” or an “off” state. you have used channels in devices to interact both with the user and with what he or she wants to control. On the Touch Panel. however. level number. have analog input and/or output capabilities. you use the keyword CREATE_LEVEL. Also. Devices using analog I/O internally store the values relating to the state of each of these analog inputs and outputs. and modify these levels. Volume Mute. Levels can be used to tell a pan/tilt control card where to position a camera. An analog input or output may have many different states. and pan/tilt control devices. In order to read a level from a device that supports levels. During execution of your program. voltage generator. Each knob has a range of values from 0 to 255. Several devices. variable CREATE_LEVEL takes three parameters: • • • The device from which to read the level Which level of the device to read (some devices have many different levels) The variable in which to store the level This keyword creates an association between the specified level of the device and the specified variable. Devices such as these use “levels” to interface with the outside world. Level values can be stored in a variable for later use. there will be four buttons: Volume Up. This unit will show you how to create. are not the only method of controlling some devices. Volume Down. several control panels have bar graph displays capable of displaying a level. you will develop a new program that handles levels. such as the volume control card and the pan/tilt control card. Channels. When a “level” is discussed in the text. This system will contain a volume control card to control a volume level. These knobs represent the two levels present in the volume control card. In this unit. this keyword is only allowed to appear in the DEFINE_START section of your program. and a Touch Panel for the user to control the volume card.Unit 3: Levels Chapter 8 – Creating Levels Introduction So far. What is a level? An input/output (I/O) channel in AMX control systems is usually digital in nature. There will also be a bar graph on the Touch Panel to display and control the volume level. read. it is usually referring to the value of one of these imaginary knobs. plus show you how to use bar graphs and sliders on some of these devices. Creating levels In most AMX devices levels can have a value between 0 and 255. Imagine that a volume control card has two volume knobs: one for the left speaker and one for the right. and Volume Preset.

Volume Down. and the statement in the startup code to create the association between level number 1 of the volume card and the VOL_LEVEL variable. lower. VOL_LEVEL This code defines the devices you will use. and mute the volume levels of the card. and Volume Mute buttons on the Touch Panel: . a variable in which to store the volume level value.Here are some code excerpts to get started: DEFINE_DEVICE VOLUME TP = 1 = 128 DEFINE_CONSTANT (* Three channels to control both outputs together *) V_UP = 1 V_DN = 2 V_MT = 3 DEFINE_VARIABLE VOL_LEVEL PRESET (* This will store the volume level value of the card *) (* This will store the preset level value*) DEFINE_MUTUALLY_EXCLUSIVE DEFINE_START CREATE_LEVEL VOLUME. By turning on and off these channels the user can raise. Here is the code for the Volume Up. 1. It also defines some constants that give names to the different channels available in the volume control card.

V_DN] [TP. ramping both up and down together.V_MT] TO[VOLUME.3] = [VOLUME.V_DN] } PUSH[TP. 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.V_MT] Notice that the Volume Up and Volume Down buttons will automatically un-mute the volume before starting to ramp the volume up or down.1] = [VOLUME.DEFINE_PROGRAM PUSH[TP.2] = [VOLUME. Also.V_UP] [TP.V_UP] } PUSH[TP. .V_MT] TO[VOLUME.2] { OFF[VOLUME.1] { OFF[VOLUME. V_MT] = NOT[VOLUME. You will add the code for these in the next chapter. V_MT] } [TP.3] { [VOLUME.

As the volume ramps up. In order to keep the display updated continually.) Making a preset Now you are going to add the code necessary to create a preset. ITOA(PRESET)" OFF[VOLUME. wait times are measured in increments of one-tenth of a second—then the current level of the card (stored in VOL_LEVEL) is saved into the variable PRESET. Note that the feedback for the Volume Preset button is turned on whenever the current volume level equals the value of the PRESET variable. as the user ramps the volume level up. the current level of the volume card is stored in the variable PRESET. "'P0L'. you use the SEND_LEVEL keyword. A preset is a level stored for later retrieval. In your program. If the time is greater than two seconds—remember. VOL_LEVEL decreases and the level indicated on the . As the volume ramps down. the variable will contain zero. If the button is pressed for less than two seconds.. you will add the following line into your program (on mainline): SEND_LEVEL TP.V_MT] } [TP.4] = (PRESET = VOL_LEVEL) This code uses the WAIT and CANCEL_WAIT keywords to test the amount of time between the PUSH and the RELEASE of the Preset button. What you will do here is give the Volume Preset button a dual role. level number. VOL_LEVEL will contain 255. here is the code: PUSH[TP. the value in VOL_LEVEL increases.Chapter 9 – Using Levels Reading levels When a level is associated with a variable using CREATE_LEVEL. If the button is pressed and held for two seconds. Assume your bar graph display on the Touch Panel has level number 1. When the volume is ramped up to the maximum.4] { CANCEL_WAIT ‘VOL_PRESET’ SEND_COMMAND VOLUME. If the button press is less than two seconds the WAIT is cancelled then a command is sent to the volume card to go to the level saved in PRESET. thus making sure that the bar graph reflects the value of level number 1 of the volume card. it sends a command to the volume card to set the level of the card to the previously saved level in PRESET. when the volume is muted. To update a bar graph on a device. VOL_LEVEL Since this code resides in mainline it will be executed continually. The same goes for ramping down. (NOTE: AMX volume devices remember the previous level when it is muted so that it can un-mute to that same level.4] { WAIT 20 ‘VOL_PRESET’ { PRESET = VOL_LEVEL } } RELEASE[TP. Here is the syntax: SEND_LEVEL device. The master continually keeps the variable updated with the value of that level. and the volume is un-muted. value This keyword is used to update a level in a device. VOL_LEVEL increases and the bar graph fills. 1. Using bar graphs Now you will add the code to continuously display the current level of the volume card on the Touch Panel’s bar graph. First.

and anytime a volume level is changed (probably by the volume control buttons on the Touch Panel). DEFINE_CONNECT_LEVEL is not a keyword that is used inside mainline. . you only have to track one of them for the bar graph. but is actually a definition section like DEFINE_DEVICE or DEFINE_START.bar graph also decreases. VOLUME.. it is not necessary to use the SEND_LEVEL keyword in your program since the connection constantly takes care of updating the bar graph.. When using DEFINE_CONNECT_LEVEL.level number 2. the best location to place it is immediately following the DEFINE_DEVICE section.) The section inside the parentheses represents a single connection. Any number of levels may be supported per connection. 1. That is what the keyword DEFINE_CONNECT_LEVEL accomplishes.level number 1. all others will change to match. VOLUME. However.etc.. All levels listed in the connection will follow each other. If any one level changes. Since both volume levels are ramping together. Underneath the DEFINE_CONNECT_LEVEL header is where all level connections are listed. the level simply tracks the movement of your finger. 1. When you use it. to do this you must set up a connection between the bar graph and the volume level. 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. 2) This connects level number 1 on the Touch Panel (your bar graph) and levels 1 and 2 on the volume device together. the bar graph will automatically follow. both volume levels will follow. Here is how DEFINE_CONNECT_LEVEL is used: DEFINE_CONNECT_LEVEL (device 1.device 2. Here is how you would use DEFINE_CONNECT_LEVEL in your program to connect the Touch Panel's bar graph to the volume card's levels: DEFINE_CONNECT_LEVEL (TP. Connecting levels Touch Panel bar graphs have a unique feature if they are set to the active bar graph type: you can touch and slide the bar graph itself and the level will raise or lower to that point. and there is no limit to the number of connections. These connections are a two-way street: anytime the bar graph is changed.

Your control panel will have nine buttons: Volume Up (button 1). you could create an array and use an index value to pick the preset you want to use. and it must be a number from 1 to 255. Understanding these concepts and the keywords that go with them will allow you to easily handle data. you want to store several preset levels for the volume control card. if you need a variable to hold several values at once. For this program. This variable could only hold one value at a time. Volume Down (button 2). use an array. Preset 3. Strings and Buffers Chapter 10 – Arrays and Strings Introduction In the previous units you developed a program that demonstrates the most common features of the AMX programming languages.. You could create several individual variables and use IF statements or SELECT.. This example assigns the . a maximum of 255 locations can be specified for Axcess systems. depending on whether the Store button is on or not. The index value is the number that tells Axcess which location in the array to retrieve. buffers. Here is your array declaration: DEFINE_VARIABLE PRESETS[6] This declares a new variable. In this chapter. Defining arrays In the program developed in Unit 2. The Store button simply toggles a state on and off. The variable must be named using a valid identifier first. and two-dimensional arrays.Unit 4: Arrays. simply refer to the storage location inside the array you wish to retrieve. Its definition has two parts: a unique identifier and its storage capacity. However. (See Chapter 1 for the rules concerning identifiers). Preset 1. Preset 4. you used a variable called DECK. you will need to create a level and assign it to a variable. you will develop a small example program. Accessing and storing array values To access a particular value in an array. For your new program. Arrays must be defined as variables within the DEFINE_VARIABLE section of your program. The Volume Up and Volume Down buttons ramp a volume card up and down. You will use the variable VOLUME_LEVEL for this. The variable PRESETS is an array that can hold six distinct values. The Preset 1– 6 buttons either store or recall a preset. as defined by the number 6 inside the brackets. An array is a single variable that has more than one storage location. the number of storage locations in the array must be indicated. and will provide another means of communicating with the outside world. such as follows: THE_LEVEL=PRESETS[3] The number inside the brackets is called the index value. 65535 locations for NetLinx systems.ACTIVE statements to select the preset you want to use. Store (button 3). Preset 5. Preset 2. PRESETS. strings. more advanced concepts will be introduced: arrays. Second. and Preset 6 (buttons 9 through 14). Or even better. In this unit.

. Retrieving a value from an array does not in any way change the array. Single quotes can only enclose values ranging from decimal 32 (the space character) to decimal 126 (the tilde character ‘~’). You can place values into a storage location by setting the particular location equal to the needed value. Strings Many times you may need to reference entire groups of values at once. the statements inside the conditional statement are executed if one of the Preset buttons is pressed. A string is a set of values grouped together with single and/or double quotes. (Remember. 8 must be subtracted from PUSH_CHANNEL to find the index value. it places the ‘F’ (ASCII value 70) in location 1 of PRESETS. You can do this by using strings and string expressions. In the example program. except when a new program is loaded into the master.8]) " } The first PUSH[TP. The next statement is an If statement which checks to see if PUSH_CHANNEL is greater than or equal to nine. These string literals are constant values that are set at compile time. or to send a command to the volume card telling it to go to a previously stored level. In other words. and less than or equal to 14. NOT inverts the state of whatever follows it.3] is the Store button. If you want the second location to hold a value of 6 you would type the following: PRESETS[2]=6 The number 6 is placed into the second location. The first letter is automatically placed into the first storage location. pressing a Preset button either stores or recalls a preset. anytime PRESETS[2] is referenced. String ‘FOUR’ is placed in the array PRESETS. the second letter is placed into the second storage location.) A feedback statement for the STORE button immediately follows the PUSH statement. and so on. In order to place the variable VOLUME_LEVEL into the array PRESETS at the correct location. Inside the conditional statement is another IF statement which uses the state of the variable STORE to determine whether to assign the volume location in the PRESETS array.3] = STORE IF((PUSH_CHANNEL >= 9) AND (PUSH_CHANNEL <= 14)) { IF(STORE) PRESETS[PUSH_CHANNEL .8] = VOLUME_LEVEL ELSE SEND_COMMAND VOLUME_CARD. Once loaded into the master these strings cannot be changed. Here is an example of assigning a string to an array: PRESETS='FOUR' When the master processes this assignment. PRESETS was previously defined as having six locations.3] { STORE = NOT STORE } [TP. and so on. its value is 6. Examine the section of code that accomplishes this: PUSH[TP. For example."'P0L'.value in the third location of PRESETS to the variable THE_LEVEL.ITOA(PRESETS[PUSH_CHANNEL . ‘O’ (ASCII value 79) in location 2. Note that an index value is not given when strings are assigned to arrays. which simply toggles the STORE variable using the NOT operator. Strings enclosed in single quotes are called string literals. From now on.

The difference between a string literal and the string expression is that the string expression is “built” at run time instead of compile time.X" (* Y = 6 *) .'TEST TWO' SEND_STRING CARD.S1 This small section of code will send two strings to the card named CARD: first ‘TEST TWO’.X" Assuming that PLAY is a constant with the value of 1. You could do this by assigning values to each individual location in the PRESETS array. The string length of an array is an internal value set for arrays by string assignment operations. whatever value is in the variable X when the expression is evaluated is what is placed into the result. and arrays.0. or each array as a group of values. If you had assigned a string expression to S1 and then sent it to the card.'NO'. the entire contents of the string expression would be sent.The string expression AMX control system masters interpret single and double quotes in two different ways.0. You can get this length value of an array by using the LENGTH_STRING function. This number is different than the storage capacity declared in the DEFINE_VARIABLE section.5. as well as variables.‘O’. Consider the following lines: DEFINE_VARIABLE S1[10] DEFINE_PROGRAM S1='TEST ONE' SEND_STRING CARD.'123'" (* Y = 5 *) "PLAY.5. and X is a variable with the value of 10.‘N’. A string expression combines several types of data into a single string. it evaluates each member of the expression from left to right.”. Whereas single quotes enclose string literals. an entire array can be accessed as one unit.’ Notice that there are no quotes around the variable S1 in the second SEND_STRING. it is considered a string. However. Arrays as strings There are two ways of referencing data in arrays within Axcess programs: each location as an individual value. string literals. however. A better solution.5.90. If you refer to an array without specifying an index value. and what the above line of code would return to the variable Y in each case: PRESETS PRESETS PRESETS PRESETS = = = = 'FOUR' (* Y = 4 *) 'ONE' (* Y = 3 *) "12.0. This is because the variable S1 is an array.5. and when an array is referenced as a single unit like this.30. As the master processes a string expression. A string expression can contain any ASCII value (0 to 255). the string expression is evaluated as a string with the following values: “1. Here is an example: Y = LENGTH_STRING(PRESETS) Here are examples of some assignments.191.10. like this: DEFINE_START PRESETS = “0. Suppose that during power-up of the Axcess system you want to set all of the presets to default values.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. Since the expression is evaluated at run time. Here is an example: PRESETS="PLAY.128. double quotes represent a different operation: they enclose string expressions. and the result is a complete string. is to use a string expression to set all six at once. the contents of the entire array are referenced as a string. then ‘TEST ONE.'NO'. So far you have seen how to access the individual locations.

.3. If PRESETS contains “1. the length will not change. the number of characters from the array PRESETS it will add will be equal to PRESETS string length value.5. to explicitly set the string length value of an array variable.1.PRESETS. to set the length value of PRESETS to 4. however.The length of a string array cannot exceed the number of storage locations allocated to it in the DEFINE_VARIABLE section.6” but its string length value is 3.2. so the first 4 locations of PRESETS will be used in all cases where you refer to the entire array. 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. The length of PRESETS would also be set to 6.'O'" The string length value of an array is very important to many string operations in AMX Programming. If the string ‘GOODBYE’ is placed in the PRESETS variable. if the letters ‘W’.2. Consider this string expression that contains an array in the expression: "5. you would first need to set the length value of the PRESETS array with this line inserted before the copy statement: SET_LENGTH_STRING (PRESETS. the resulting string from the above string expression will look like this: "5. If this were the entire program. Here is an example: PRESETS[1] = PRESETS[2] = PRESETS[4] = SAVE_PRESETS 5 6 'A' = PRESETS What do you think the array SAVE_PRESETS will contain after this code is executed? It will totally depend on the length value of the PRESETS variable. you would use the following statement: SET_LENGTH_STRING(PRESETS. if you assign values to individual elements in an array. and then assign that array to another. the length value of PRESETS is 4. For instance.3. the string length value of the array PRESETS is 4.'G'.’ dropping the final ‘E’ because PRESETS was defined to hold a maximum of six locations.'GO'" As the master constructs a string from this string expression.4) After this. so nothing would be copied into SAVE_PRESETS. PRESETS[1] PRESETS[2] PRESETS[3] PRESETS[4] = = = = 'W' 'O' 'R' 'D' There is a way. In order to assure that SAVE_PRESETS were to hold a copy of PRESETS. Knowing this will prevent subtle errors from creeping into your code. However. If the length was previously 3. For instance. This value determines how much of the string is used when the entire array is referenced as a string. it will still be 3. String lengths play an important role in the handling of strings. the array will only contain the string ‘GOODBY.4. For instance. nothing will actually be copied. ‘O’ . The SET_LENGTH_STRING keyword accomplishes this. and ‘D’ are assigned individually to elements of PRESETS as shown below.‘R’. PRESETS would have a default length of 0.4) After execution. assigning values to individual elements of an array does not affect the length value of the array.

you use the SEND_STRING keyword. followed by however many characters from PRESETS as defined by its length value. 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. and then two numbers expressed here in hexadecimal. from left to right. the number of characters from the array that are sent is determined by the length value for the array. the third example above shows $52.” All three methods—letters.<string. The second example first builds the string expression using a string literal. decimal ASCII codes. you can set that value with the SET_LENGTH_STRING function.'THIS IS A STRING LITERAL' SEND_STRING RS232. a string is broken up into single letters when placed into a string array. you would write the following line: SEND_STRING RS232. to the card named RS232. variable. (Remember.$0D.” respectively. hexadecimal numbers begin with a dollar sign ($). “this number."'EXPRESSION '.PRESETS String literals and string expression can also be sent using SEND_STRING. In AMX Programming. Following that is a comma. For example. is a hexadecimal number.PRESETS. and hexadecimal ASCII codes—can be used interchangeably. When an array variable is specified.’ There are actually three ways you can reference this array location (in this example using If statements): IF(TEMP[3] = 'R') { (* statement(s) *) } or IF(TEMP[3] = 82) { (* statement(s) *) } or IF(TEMP[3] = $52) { (* statement(s) *) } The ASCII character ‘R’ has a value of 82 decimal.Sending strings and arrays To send a string to the outside world. Each storage space returns the letter it is holding when referenced. meaning. or string expression you wish to send.$0A" The first example sends the entire set of characters enclosed in the single quotes. (The hexadecimal numbers in the example represent the codes for “carriage return” and “line feed.) ASCII codes As you have learned. . 52. Here is the syntax: SEND_STRING device. then the string. if you need to send the PRESETS array to a card named RS232. assume that PRESETS[3] holds the letter ‘R. variable (which can be either a normal variable or an array). Here are some examples: SEND_STRING RS232. Feel free to use whichever method is easiest for the task at hand.) For instance. Therefore. which is equivalent to 52 in hexadecimal.

If an integer array is assigned to a normal array. in assigning a normal array to an integer array. except that each location can hold values from zero to 65.535.) So what could you do if you need to create an array in which each location can contain values greater than 255? The answer is to use an integer array. the range of values in each location is zero to 255. the actual number that is assigned is 244. if the number 500 is assigned to a location in an array. If your array is only going to hold only alphanumeric values. (See the earlier discussion on truncating values. the number is truncated above 255.535. and when a value greater than 255 is assigned to an array location.) This also happens if an integer array is sent to a device using the keywords SEND_STRING or SEND_COMMAND. Recall that the range of values in a single variable is zero to 255. An integer array is just like a normal array. . each location can hold values from zero to 65. all values are truncated above 255. There is no problem.Integer arrays So far. however. If you wanted your PRESETS array to be an integer array. To declare an integer array. (The way to find this is to keep subtracting 256 from the number until the number is less than 256. simply place the keyword INTEGER in front of the array definition in the DEFINE_VARIABLE section. For instance. in all of the arrays you have seen. do not make it an integer array. here is how you would declare it: DEFINE_VARIABLE INTEGER PRESETS[6] This declares an integer array with six locations. There are certain limitations of integer arrays.

This is because the dollar sign indicates a numerical value expressed in hexadecimal. Thus there are many keywords to help you manipulate arrays and strings.” creates a string that represents the decimal value of a number. ITOA ITOA. except that the integer is transformed into a hexadecimal ASCII string. The three keywords ITOA. . The length value of STR is set to 3 in each case. ITOHEX. or explicitly defined—into its string representation. The result is an ASCII string which contains a representation of the hexadecimal value. If you substitute the ITOA keywords in the previous example with ITOHEX keywords. and is only used when telling the system that a number is hexadecimal. Conversion keywords There are several string conversion keywords available: UPPER_STRING LOWER_STRING ITOA ITOHEX ATOI The first two keywords convert a string into all uppercase or all lowercase. These keywords can be grouped into two classes: conversion keywords and array manipulation keywords. in a variable. and vice versa. The last three serve to convert numbers—either as a constant. even though its storage capacity is 5.Chapter 11 – Working with Arrays Grouping Data The ability to group data into cohesive units (arrays) is one of the more powerful features of the AMX programming languages. and ATOI automatically set the length value of the resulting string. Here are some examples: DEFINE_CONSTANT CONST = 456 DEFINE_VARIABLE STR[5] VAR DEFINE_PROGRAM VAR = 789 STR = ITOA(123) (* STR = ‘123’ *) STR = ITOA(CONST) (* STR = ‘456’ *) STR = ITOA(VAR) (* STR = ‘789’ *) The comment after each statement shows the value of the array STR after each assignment. ITOHEX This keyword is short for “integer to hexadecimal. this would be the result: STR = ITOHEX(123) (* STR = ‘76’ *) STR = ITOHEX(CONST) (* STR = ‘1C8’ *) STR = ITOHEX(VAR) (* STR = ‘315’ *) Notice that result does not contain a dollar sign. which is short for “integer to ASCII.” ITOHEX works in the exact manner as ITOA.

Here is an example: STR = MID_STRING (PRESETS. the length value of STR will be set to 3. Notice that only the first set of numbers from STR2is returned. Three parameters. . the position at which to start. Here are some examples: DEFINE_CONSTANT STR1 = ‘456’ STR2 = ‘YES789GO19’ DEFINE_PROGRAM NUM = ATOI('123') (* NUM = 123 *) NUM = ATOI(STR1) (* NUM = 456 *) NUM = ATOI(STR2) (* NUM = 789 *) If the string contains all non-numeric characters (such as ‘HELLO’).” If PRESETS contains ‘HELLO. are needed for its operation: the string to reference. Here is an example: STR = LEFT_STRING (PRESETS. into the array variable STR. you must specify two parameters: the string or array you are referencing and the number of characters you need. This keyword also will set the length value of the array receiving the result.’ this line will assign ‘ELL’ to the array STR.’ replacing LEFT_STRING in the previous example with RIGHT_STRING will assign the string ‘LLO’ to STR. or array as a parameter. However.3) After execution of this line. Assuming PRESETS still contains ‘HELLO.3) This line tells the master: “Place three characters from the array PRESETS.2. and returns a single integer as the result. However. rather than two. RIGHT_STRING begins reading at the end of the string array for the specified amount of characters. starting at location 2 and moving to the right. and the number of characters to return.’ then STR will contain ‘HEL. the array STR will contain the first 3 characters of the array PRESETS. ATOI returns the integer 0. ATOI returns the first complete set it comes upon.’ Also. Array manipulation keywords There are a number of keywords at your disposal that allow you to manipulate arrays and to retrieve certain portions of an array: LEFT_STRING MID_STRING RIGHT_STRING FIND_STRING REMOVE_STRING LEFT_STRING For this keyword.ATOI The ATOI keyword stands for “ASCII to integer” and does just that. RIGHT_STRING This keyword requires the same parameters as LEFT_STRING. if there are any numeric characters embedded within the string. It takes a string literal. MID_STRING This keyword returns the specified amount of characters starting at a specified location in the source string. string expression. If PRESETS has a length of 5 and contains the string ‘HELLO. This keyword also will set the length value of the array receiving the result. LEFT_STRING returns a string containing the number of characters specified starting at the beginning of the string. as is the case with STR2 above.

looking for the string ‘LO. All the other characters move up to fill in the space. DEST will contain ‘THIS’ and SOURCE will contain ‘ IS A TEST’. However. As soon as it finds a duplication of the sequence. it extracts every character up to and including the sequence.10.1) (* OK this works*) STR = REMOVE_STRING(“2. In FIND_STRING. However. each of the first two parameters can be a string literal. the FIND_STRING keyword is used.‘HELLO’. Here is an example: DEFINE_VARIABLE SOURCE[20] DEST[20] DEFINE_PROGRAM SOURCE = ‘THIS IS A TEST’ DEST = REMOVE_STRING (SOURCE.13”.'LO'. the first location of the array SOURCE contains a space. 1) tells the master where in the array PRESETS to start the search.’ If the system finds the search string.“12”.1) After the last line is executed. In this case. it will search the array PRESETS from the beginning. . Once loaded into the master. but you want to find out if it contains the string ‘LO. This is because REMOVE_STRING removed all characters from the beginning of SOURCE up to and including the string ‘IS. when the master finds the sequence it is looking for. This keyword will search through a string for a specified sequence of characters. there will be many times when you have no idea where to look. or array.‘IS’. and only variables can be changed at run time. The third parameter (in this example. and DEST is set to 10.Finding Strings The keywords explained previously are helpful when you know where certain parts of strings are located within a string array.’ The length values of both arrays are set according to the results of the operation.1) (* NO this doesn’t work *) Remember that REMOVE_STRING changes the first parameter after it removes whatever characters it needs. Notice that after the removal. In these cases. Removing Strings The REMOVE_STRING keyword works much like the FIND_STRING keyword. only an array variable. as in this case it will. constant values cannot be changed. However. the length value of SOURCE is set to 4. X = FIND_STRING (PRESETS. suppose you don’t know the exact contents of the PRESETS array.‘HELLO’.’ It did not remove the space following the string ‘IS’ in SOURCE. it returns the beginning position of that duplication. 4. it returns the starting position of the search string in the PRESETS array: in this case. Also notice that the first occurrence of ‘IS’ is embedded in the word ‘THIS.’ Assume that PRESETS has a length of 5 and contains ‘HELLO’ and the following line is executed. Also remember to supply the starting position of the search as the third parameter for both FIND_STRING and REMOVE_STRING.1) When the master executes this statement. in the case of REMOVE_STRING. having anything except an array as the first parameter makes no sense because the master cannot remove part of a string literal or string expression. This is because string literals are constant values and string expressions may contain constant values. Look at these examples: STR = REMOVE_STRING(PRESETS. For example. string expression.

Here are some examples: DEFINE_PROGRAM Identifier_1 = 'Fred' Identifier_2 = 'FRED' if(IDENTIFIER_1 = IDENTIFIER_2) { (* This will not be true because 'Fred' and 'FRED' are not the same. The keywords that do this are UPPER_STRING and LOWER_STRING. As you recall. . however. the compiler makes no differentiation based on the case of the letters making up the identifier name. For example. However.UPPERCASE vs. the statements below the If would not be executed. Each has its own decimal ASCII value. the compiler is not case sensitive when it comes to keywords and identifiers. This could become a problem when. the value for “a” is 97. when it comes to values inside single quotes (string literals). This also makes absolutely no difference to the compiler. The compiler is case sensitive. Also notice that in this example the keyword IF is not capitalized. which means that uppercase and lowercase values are not evaluated the same.’ providing that the If statement reads IF(ABC2 = ‘YES’). your program compares an incoming string ABC against another: IF (ABC = 'YES') { (* statement(s) *) } If the incoming string is ‘YES’ there is no problem. as well as when comparing two string values. *) } Notice that the string literals ‘FRED’ and ‘Fred’ are not the same. the lower case letter “a” is not the same as the upper case letter “A”. However. Setting uppercase and lowercase Within the system. and the value for “A” is 65. The statements are executed as expected. it is important to remember that such comparisons are case sensitive. the following statement could have been added before the preceding program: ABC2 = UPPER_STRING(ABC) The If statement can now compare ABC2 against ‘YES. As expected. LOWER_STRING converts a string into lowercase in the same manner that UPPER_STRING operates. what if ABC equals ‘Yes’? Since ‘YES’ and ‘Yes’ do not have the same decimal ASCII value. for example. lowercase When using FIND_STRING and REMOVE_STRING. The solution is to change all incoming strings to either uppercase or lowercase. in the case of identifiers IDENTIFIER_1 and IDENTIFIER_2. The string ‘Yes’ is accepted since it has been converted into uppercase.

send it to a device. assign it to other arrays. and it has the following syntax: CREATE_BUFFER device. it increments the length value for the array and then places the byte into the array at the current end of the array. You have the ability to construct any combination of numbers and characters with the string expression and send it to an external device. as well as use the array manipulation keywords discussed in the previous chapter. use the CREATE_BUFFER keyword. To be able to receive strings from a device.Chapter 12 – Using Buffers Communicating to the outside world One of the most powerful features of the AMX control systems is its ability to send and receive any combination of values using RS-232. So the ‘Y’ is put into location 4. A buffer is an array variable that is associated with a particular device for the purpose of storing information received from the device. When the master places the byte into the array. it is still an array and can be treated as one. Receiving strings Receiving strings requires several more steps than sending strings. the length value was 3. MIDI. This keyword can only appear in the DEFINE_START section of your program. Here. When data comes in from a device. you must first create a buffer for that device. you can receive strings from external devices and interpret them to obtain useful information. array The CREATE_BUFFER keyword directs the master to place any data received from the specified device into the specified array. Even though the array is acting as a buffer. and a variety of other formats. assign other arrays to it. RS-422. and the length value is incremented to 4. it goes into the spot determined by the length value of the array. You can still access the individual locations. . In addition. Creating buffers To create a buffer. RS-485.

and so on. you will create an array called BUFR with a capacity of ten characters. The result must be a simple variable (not an array). the master places the incoming information into the buffer created for that device. The second character is now the first. but does not need to be a buffer. Here is the syntax of this keyword: string = GET_BUFFER_CHAR(array) The parameter passed to GET_BUFFER_CHAR must be an array. DEFINE_VARIABLE BUFR[10] CHAR DEFINE_START CREATE_BUFFER RS232. as described earlier. This is usually a twostep process. This keyword has a two-part operation: • First.) These actions are executed after the master has passed through mainline. • Second. but not all arrays are buffers. Then you will make it a buffer associated with a device named RS232.) The statement will operate identically in either case. Now. and updates the buffer’s length value. (Remember: All buffers are arrays. (Remember.Storing characters When a device sends string information to the master. shifting the contents of the buffer left in order to insert the new character at the end of the buffer. the master drops the first character. the third is now the second. because one and only one character will ever be returned. Retrieving characters This is where the keyword GET_BUFFER_CHAR comes into play. If the buffer is full when a character needs to be inserted into it. it removes that character from the buffer. In these examples. causing all the other characters to shift up one place. A buffer is said to be “full” when its length value is equal to its storage capacity.BUFR Now all string data sent to the Master from the device RS232 will go into the array BUFR. Here is an example: IF(LENGTH_STRING(BUFR)) { CHAR = GET_BUFFER_CHAR(BUFR) } . suppose you want to get the data out of the buffer as soon as it enters. it retrieves the first character in the buffer for your own utilization. a buffer is an array. This creates the same effect as if you retrieved the first storage location of a normal string array.

Remember. such as assigning a null string to the buffer. which will be executed if there are one or more characters in BUFR. Characters should be continuously retrieved and removed from the buffer so that incoming strings have spaces to completely enter. or using SET_LENGTH_STRING. and it will execute the GET_BUFFER_CHAR statement as long as it is in its path of execution. tells the master to get the first character in BUFR place it into the variable CHAR. The second part. The condition of the If is the result of the LENGTH_STRING keyword. Using CLEAR_BUFFER is preferable to other methods. Be sure to place a GET_BUFFER_CHAR statement in a position to do this. plus it is clearer to the reader as to what the programmer is trying to accomplish. Here is how it is used: CLEAR_BUFFER BUFR This keyword effectively sets the length of the buffer to zero. Clearing a buffer AMX programming provides a single keyword that clears a buffer: CLEAR_BUFFER. . the master system is constantly running through the main program. so that subsequent GET_BUFFER_CHAR statements will not return anything. The CLEAR_BUFFER keyword actually compiles into smaller code and executes faster than the other methods.These two lines of code are actually one statement: an IF statement. if there are not any characters in the buffer (length value of BUFR is zero). then the master will skip the second part of the statement.

although all are not always used. Boolean expression A conditional statement used to tell the master whether or not to execute a particular function or functions in the program. and other characters. Constant An identifier whose value remains unchanged throughout the entire program. measured in bits per second (bps). Baud rate Speed of data transmission. Buffer An array variable that is associated with a particular device for the purpose of storing information sent by the device. AXlink The AXCESS communications bus. Compile time When the program is compiled. “CASS” is not the same as “cass. for example. This is also known as a relational expression. Channel The basic input/output unit. Boolean operator A keyword or symbol that creates a relation between two items. Bar graph A visual representation of a level. Array A single variable that has more than one storage location. Compound statement A group of several statements enclosed by a set of braces. Decimal Base 10 numbering system. Caller The Call statement that called a subroutine. Channels correspond to actual control functions such as relays and infrared signals.Glossary Analog An input or output that can have many values. Default statement . Comment A description or remark within a program that is not considered part of the actual program. Compilation error An error that occurs at compile time. numbers.” Cell One particular location in a two-dimensional array. ASCII A coding scheme that assigns numeric values to letters. Each AXCESS device has 255 channels. it is ignored by the compiler. Case sensitive Uppercase and lowercase values are not evaluated the same. Bitwise operator A keyword or symbol that performs a bit-by-bit operation between two items.

DEFINE_START. Integer . Global variable Any variable in the DEFINE_VARIABLE section of the program. and DEFINE_PROGRAM. Device A component connected to an AMX system to control another piece of equipment. Direct assignment Generating an output change by assigning a value to a device-channel. this software enables these devices to operate. Executable code A translated version of the source code that the system master can understand. Infinite loop A loop which will never terminate. Feedback The lighting of a button during and after it is pressed. DEFINE_VARIABLE. Firmware Residing within the EPROMs in many AXCESS devices. or variable. 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. Downloading The sending of data from a computer to a device (such as an AMX Master). EPROM Acronym for erasable programmable read-only memory. Input change A signal sent by the input function of a channel that causes the AMX master to scan the program for a reference to that signal. Hexadecimal Base 16 numbering system. Flag A variable that is used to store an “on” or “off” state. The scope of these variables extends throughout the entire program.A statement (or compound statement) that is executed if none of the conditions being tested is true. Identifier A combination of letters. DEFINE_LATCHING. These sections include DEFINE_DEVICE. Index value The number that tells the system master which location in an array to retrieve. numbers.channel]. Instance number A number enclosed in brackets after the SYSTEM_CALL keyword to denote which copy of the compiled library file to call. Definition section One of the various divisions of an AMX program. Free format A characteristic of the AMX programming languages that allows the source code to be independent of tabs and carriage returns. Device-channel A reference to a specific channel in an AMX system in the format [device. DEFINE_CONSTANT. or underscores that represents a device. constant. DEFINE_MUTUALLY_EXCLUSIVE. Device number A unique number from 1 to 255 designated to each device connected to an AXCESS master or from 1 to 32000 designated to each device connected to a NetLinx master.

Operator A character or group of characters that performs a specific mathematical or relational function. One-to-one Each button has one and only one function. Logic error An error in the actual design of the program. These files are used only for System_Calls. Loop A block of code that is continuously executed until a condition is satisfied. Momentary A defined behavior of status that causes its output channel to be activated as long as the corresponding button is pressed. inclusive. Latching A defined behavior of status that causes its output channel to stay on or off until activated once more. Nesting Placing conditional branches inside other conditional branches. Momentary mutually exclusive A characteristic of status that allows only one channel of a pre-defined set to be on at a time. and whose scope is limited to that subroutine. Name mangling The process where the name of the DEFINE_CALL and any WAITs and WAIT_UNTILs in a library file are changed so that multiple separate copies can be compiled into a program. The output channel is activated as long as the corresponding button is pressed. Output change A message to the output function of a channel. Local variable A variable declared in a subroutine. Mutually exclusive toggling A characteristic of status that allows only one channel of a pre-defined set to be on at a time. Level A value that is related to an analog input or output on an AMX device. 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. with no special conditions or considerations. Integer array An array where each location can hold a value ranging from zero to 65. which represents a string literal with no content and a length value of zero. The output channel stays on until it is re-activated or another channel of the set is activated.535. This is also known as the DEFINE_PROGRAM section. Locking When flags are used to disable events. Note that an integer array will take up twice as much memory than a normal (character) array of the same storage capacity. Library file A special file containing program code. Preset . Null string An empty set of single quotes.535.A 16 bit binary number in the range of whole numbers from 0 to 65. Keyword A word or series of words that signifies the operation for the system master to execute. Mutually exclusive latching A characteristic of status that allows only one channel of a pre-defined set to be on at a time. Mainline The section of the program that actually is executed continuously by the system master.

and Rewind. When a preset is recalled. the level returns to the preset value.” Ramp To change a level from one value to another smoothly over a period of time. A variable has global scope if the entire program has access to it. Run time When the program is executed. Program file File containing the program source code. State The “on” or “off” status of a channel. Run-time error An error that occurs during program execution. Select group A group of buttons that selects a single deck or device out of a group. For example: Play. Statement A keyword and all of its parameters or conditions. it has the DOS extension “AXS. Select variable A variable whose value determines which device in a group is currently selected. String A set of values grouped together with single and/or double quotes. Source code The program that you type and edit. a variable has local scope if only a section of the program has access to it. Two-dimensional array . but before it returns to the caller. Reserved word An identifier reserved for use by the control system program. String expression Enclosed by double quotes. String length An internal value set for arrays by string assignment operations. String literal A set of characters (decimal values ranging from 32 to 127) enclosed in single quotes. Re-assignment When the master assigns a new value to a parameter variable after a subroutine is executed. Transport function A common function of devices such as VCRs and cassette decks. System variable A value kept in the system memory that can be referenced by certain keywords. Scope The part of the program where the variable can be accessed. Row A one-dimensional array of values in a two-dimensional array.A level saved for later retrieval. Pause. Serial The transfer of data one byte at a time. Fast Forward. Stop. Subroutine A section of code that stands alone and can be “called” from anywhere else in the program. Status Records the state of the physical part of a channel. this expression combines several types of data into a single string. Relational expression See Boolean expression.

this is the question mark (?). Uploading The opposite of downloading. After each pass through mainline. Wait_Until list A list containing unexpired Wait_Until statements. the computer receives data from a device. the master scans this list to see if any have expired. the master scans this list to see if any have expired. . in AXCESS programs. Wildcard character Allows any character to be in its place. Variable A place to store data that will change as the program is executed. After each pass through mainline. Wait list A list containing unexpired Wait statements.A storage place holding multiple one-dimensional arrays. This is only valid when comparing dates and times. Warning A statement by the compiler urging caution with a potentially hazardous statement in the source code.