Programmer 1 & 2 PDF
Programmer 1 & 2 PDF
Copyright
AMX Corporation, 2005. All rights reserved. No part of this publication may be reproduced, transcribed, stored in a retrieval system or translated into any language in any form by any means without the written permission of AMX.
Credits
Written by AMX University.
For additional questions or suggestions, feel free to call us. AMX University 3000 Research Drive Richardson, TX 75082 Phone 469.624.8000 Fax 469.624.7192
Table of Contents
Table of Contents
Introduction .............................................................................................................................1 Programmer I Course Objectives .........................................................................................1 Programmer II Course Objectives ........................................................................................2 Basics Of Control Review .......................................................................................................3 AMX Product Review .............................................................................................................5 Setting up a Project in NetLinx Studio .................................................................................7
Review of User Interface ................................................................................................................. 7 Preferences....................................................................................................................................... 8
Table of Contents
Device-Channel Concept ............................................................................................................... 57 Input Characteristics ...................................................................................................................... 58 Output Characteristics.................................................................................................................... 59 Feedback Statements...................................................................................................................... 60 Mutually Exclusive Groups / Sets.................................................................................................. 62
Variables ................................................................................................................................77
Data Types ..................................................................................................................................... 78 Behavior Types .............................................................................................................................. 78 Scope.............................................................................................................................................. 81
Waits ......................................................................................................................................87
Naming Waits ................................................................................................................................ 87 Types of Waits ............................................................................................................................... 87 Nesting Waits................................................................................................................................. 89 Pausing and Restarting Waits ........................................................................................................ 89 Canceling Waits ............................................................................................................................. 90
Conditionals ...........................................................................................................................93
IF Statement ................................................................................................................................... 93 IF...ELSE Statement ...................................................................................................................... 94 The SELECT...ACTIVE Statement ............................................................................................... 96 SWITCHCASE .......................................................................................................................... 98
Subroutines ..........................................................................................................................113
Subroutines Defined..................................................................................................................... 113 DEFINE_CALL........................................................................................................................... 114 DEFINE_FUNCTION ................................................................................................................. 115
Modules ................................................................................................................................119
ii
Table of Contents
Levels ....................................................................................................................................123
Introduction to Levels.................................................................................................................. 123 Creating Levels ............................................................................................................................ 126 Using Levels ................................................................................................................................ 127 Using Bargraphs .......................................................................................................................... 128 DEFINE_CONNECT_LEVEL.................................................................................................... 128 LEVEL_EVENTs ........................................................................................................................ 129
Loops ....................................................................................................................................157
While Loops................................................................................................................................. 157 FOR Loops................................................................................................................................... 158
iii
Table of Contents
Assigning Values to Multi-dimensional Arrays and Structures .................................................. 177 Data Sets ...................................................................................................................................... 177
Timelines ..............................................................................................................................197
Timeline Functions ...................................................................................................................... 197 Timeline Keywords...................................................................................................................... 199 TIMELINE_EVENTs .................................................................................................................. 204
Review Sheet - Basics of Control .......................................................................................213 Review Sheet - Product .......................................................................................................215 Review Sheet - Intro to Networking ..................................................................................217 Review Sheet - Control Networks ......................................................................................219 Appendix - Keywords .........................................................................................................221 Appendix - Embedded Event Data Objects ......................................................................223 Appendix - IR Functions ....................................................................................................225 Appendix: ASCII Code Chart ...........................................................................................227 Appendix - NetLinx Security .............................................................................................229 Appendix - NetLinx Ethernet Information ......................................................................255 Appendix - Troubleshooting ..............................................................................................259
iv
Introduction
Introduction
Welcome to AMX Programmer I and II. These courses, for programmers and technical support personnel, teach programming skills for AMX Control Systems. A programmer completing these courses will be able to program NetLinx Control Systems.
Skill level will be different from Programmer I and Programmer II.
This manual is designed to be both a tool to be used in the classroom and for reference on the job. White space is available on every page for taking notes. Good luck!
Input & output statements Direct feedback statements Object Oriented Programming
LEVEL_EVENT
BUTTON_EVENT CHANNEL_EVENT
Conditional Statements Loop Statements Multi-Dimensional Arrays Data Structures & Sets String Handling Statements Buffers
DATA_EVENT
DEFINE_COMBINE
COMBINE_DEVICES UNCOMBINE_DEVICES
Timelines
TIMELINE_EVENT
Modules
Match each property to the appropriate serial control type: (some properties have more than one answer) RS-232 RS-422 RS-485
____uses a balanced signal to reduce interference ____maximum run length of 50 feet ____only multi-drop ____single-ended or multi-drop ____connects only one transmitter and receiver ____maximum run length of 4000 feet
What are some of the different types of touch panels that AMX offers?
Match the software solution with its appropriate description: a) MeetingManager b) Picture Frame c) G4 Web Control d) G4 Computer Control
____ Allows you to transform your Modero Touch Panel into a dynamic digital photo album ____ Allows any Modero Touch Panel to remotely view and control any network attached computer ____ Allows you to schedule, animate, and monitor any room controlled by NetLinx ____ Allows a Modero Touch Panel to be remotely controlled by any computer on the control network
What are the differences between a MAX MMS, AVM, and AOM?
Workspace Window
Output Display Window Status Bar FIG. 1 NetLinx Studio 2.2 Work Area
Preferences
Select Settings > Preferences to open the Preferences dialog, where you can set various application-level preferences. This dialog contains the following tabs: General tab - Contains options to set general program defaults Axcess Compiler Options tab - Contains options to set default prefefernces for the Axcess Compiler NetLinx Compiler Options tab - Contains options to set default prefefernces for the NetLinx Compiler Editor tab - Contains options to set default preferences for the Source Code Editor windows Diagnostics tab - Contains options to set default diagnostics preferences Terminal Options tab - Contains options to set default Terminal window preferences File Transfer tab - Contains options to set default preferences for file transfer operations Workspace tab - Contains options to set various display and file preferences relating to the Workspace Window Commands tab - Contains options to add/remove commands from the toolbars Toolbars tab - Contains options to add/delete/rename and reset the toolbars Tools tab - Contains optins to add a shortcut to another application in the Tools menu Keyboard tab - Contains options to set custom keyboard accelerators (shortcut keys/ key combinations) often-used commands Menu tab - Contains options to customize the menus and reset the menus to their original default state. Options tab - Contains options to set a few basic toolbar options We will go over a few of these tabs on the next few pages:
Use the options on the General tab of the Preferences dialog to set general program defaults: Window Color Display Options - Allows you to define the Forground and Background Color in each window. Software History Application - This File Location field allows you to specify whether or not to close Sofware History when NetLinx Studio exits. Recent File List Size - This field allows you to change the size of the recent file list, displayed at the bottom of the File menu (range = 1-9),
Use the options in the NetLinx Compiler tab of the Preferences dialog to set default preferences for the NetLinx compiler. The items in this tab include: Directories Click to open the directories menu, where you select the directories to point the compiler to, by file type. Once a directory type is selected, the directory list is populated with the directories of that type that have been mapped. There are a maximum of 100 directories that can be entered for each type.
Select Include Files to select or create the directory that the compiler will look for Include files in. Select Library Files to select or create the directory that the compiler will look for System Call files in.
Compile With Debug Info Select this option to include variable symbol information in the compiled file. This allows the debugger to identify and validate variable symbols in the code. You must compile with debug info in order to debug NetLinx files. Build With Source Check to include the executable code and the source code to the Master Controller or data device when the file is sent (memory permitting). This allows the Receive option to retrieve the source code from the Master Controller. If Build with Source is disabled, only the executable code is sent, which cannot be retrieved from the Master Controller.
When building with source, only the files needed for the compilation process are compressed. Though the APW may contain many files, if the source file only uses one AXI file, then only 2 files will be compressed.
10
Build With Password Protection Select this option to apply a password to the Source file. Select the Change button to edit the password (via the Change Password dialog). A password must be at least 6 characters in length (maximum of 20 characters).
Use the options on the Editor Options tab of the Preferences dialog to set default preferences for the Source Code Editor windows. The items in this tab include: Syntax Highlighting - These options allow you to customize syntax highlighting within the Source Code Editor windows.
Document Type - Select the type of document that you want to set highlighting options for (Text Files or Source Code Files). Selections - This is a list of all the items that can be customized in the Source Code Editor Windows. The items that appear in this list depend on the Document Type selection. Background Color - This is the background color setting for the selected Item. Apply to All - Use this option to apply the selected background color to all items in the Selections list. Text Color - This is the text color setting for the selected Item. Click the down arrow to select a different color from a palette. Bold/Italic - Use these checkboxes to specify the text style setting for the selected Item.
11
Display options These checkboxes offer more display-oriented options for the Source Code Editor window:
Show Line Numbers - This option displays line numbers along the left-hand edge of the Source Code Editor window (default = enabled). Enable Code Folding - This option allows you to "fold-up" each section of code in the Source Code Editor (default = enabled). Enable AutoComplete/AutoSuggest - With this option enabled, the application examines the first few characters in a variable name, device name or a reserved identifier, and automatically finishes typing it for you (default = enabled). Auto-indent - This option automatically indents your text as you type (default = disabled). Enable Indentation Guides - This option causes the program to draw vertical lines indicating the tab stops in the Source Code Editor window (default = enabled).
Tabs and Indentation Preferences - This set of options allows you to specify the following indentation preferences:
Set tab stops every X characters - Use this option to specify the size (in number of characters) of the tab stops in the Source Code Editor window (default = 4). Enable Auto-Indentation - This option causes the program to automatically indent lines that occur after an indented line. Clear Text Buffer History - Clears all the clipboard text items from the list.
Font - The Selection button opens the Font dialog, where you can select the font, font style (regular, italic, bold) and font size to be displayed in the Source Code Editor window. Clipboard Text Buffer - These options allow you to define the number of clip-board buffer entries and the maximum width to display.
Max Items - You can have a maximum of 30 clip-board buffer items (default = 20). Max Display Width - You can set the maximum display width to up to 80 characters (default = 50).
12
Use the options on the Workspace tab of the Preferences dialog to set various display and file preferences relating to the Workspace Window. The items on this tab include: Display Options:
Restore Workspace On Startup - This option (on by default) automatically restores the workspace file upon startup of the application. With this option enabled, all files that were opened and the dockable windows that were displayed when you closed the application will be restored when you restart the program. Display System Configuration Setting in the Identifier - This option (off by default) displays the System Configuration settings as part of the System identifier (as displayed in the Workspace tab of the Workspace Window).
Saving:
Enable Auto Save - Toggles the timed auto-saving of text files and the duration of time between auto saves.
Auto Save Every <x> Minutes - This field is only enabled when the Enable Auto Save option is selected. The range is 1-120 minutes, the default setting is 5.
Automatically Save Before Compile - Toggles auto-saving of code files before a compile. Automatically Stamp File with Creation and Last Modified Date -This option automatically stamps all Workspace files with Creation and Last Modified dates when the file is closed (default = enabled).
13
Editor Window tabs - These options allow you to toggle the Source Code Editor Window tabs ( ), and set their style and location.
Enable Window Tabs - This option toggles the display of the window tabs that appear by default along the lower edge of the Source Code Editor windows area of the GUI. These tabs provide easy access for each open Source Code Editor window. If this option is not selected, the following tab-oriented options are disabled. Enable File Icons In Tabs - This option toggles the file icons displayed in the Source Code Editor window tabs. Enable Window Close Button - This option toggles the Window Close button ( ).
When Closing the Workspace - This section contains options for closing files associated with a Workspace that is being closed. The options are:
Close Associated Files Without Prompting Always Prompt Before Closing Associated Files Do Not Prompt or Close Associated Files
When Removing a File From the Workspace - This section contains various options for closing files when they are removed from the current Workspace. The options are:]
Close File Without Prompting Always Prompt Before Closing Files Do Not Prompt or Close File
14
Device Addressing in NetLinx Device:Port:System DIP Switch Programmer Software and Settings Checklist
Types:
Master Axcess Devices NetLinx CardFrames ICSNet NetLinx Devices ICSNet Landmark Devices Inconcert Devices PCLink Devices ICSNet Panels Dynamic Devices Virtual Devices
Comments:
Use Axcess standards Start at frame number 25 - (frame# * 12) + 1 NXI, NI Series, NXM-COM2, NXM-IRS4, etc. PLH-VS8, PLH-AS16, PLB-AS16 PCLink Devices are PC Programs DMS, Modero, & TPI4 Actual range used by NetLinx master Actual range used by NetLinx master
Device numbers 1-255 are reserved for Axcess devices. NetLinx devices can be numbered between 256-32,000.
15
16
There are two ways to address the NXI. First if you are certain which dynamic address has been assigned to the NXI you can enter that address in the Device/System Change of Address Options section of the dialog box. Or, if you are not sure of the dynamic address the NXI can be addressed using the ID Mode section. To determine that address that has been dynamically assigned you can look at the Online tab in the Workspace Window. (To show the Workspace Window, select Workspace from the View menu on the menu bar.)
System ID
In this example the NXI has been assigned device address 32002 on System 1. This information should be entered in the Device to Change area of the Change Address section of the Device Addressing tab (See FIG. 1.) Check the boxes to indicate if you want to change the device address or the system ID or both. Then enter the device address and system number you want to assign to that device. For example if we want to change this NXI to device 5001 on System 1, we would check the Change Device box and enter 5001 in the adjacent field.
This works well if there is only one NXI in the system, but what if there are several? In this case it may be difficult to determine which NXI is connected to which controlled devices. To make that easier AMX developed the ID Mode for device addressing. ID Mode sets the ICSNet devices to a special mode where an ICSP indicator on each device quickly flashes to indicate that it is now in ID mode. To address a device using the ID Mode, in the section labeled ID Mode enter the system ID of the system the NXI is connected to, then enter the desired Device number and System ID that you wish to assign to the NXI then press Start Identify Mode. A green indicator note under the Cancel Identify Mode button will light up, the ICSP LED on the rear of each NXI will be quickly flashing and the system is waiting for the device to be identified (See FIG. 3). At this time press the white ID button on the left rear of the NXI.
17
FIG. 3 Device Addressing Dialog after the Start Identify button is pressed.
That will bring up a Successful Identification Made message (FIG. 4) indicating that the NXI address has been set. Continue this process for the remaining NXIs in the system until all have been given a fixed device address.
FIG. 4 Device Addressing Dialog after Successful Identification has been Made
18
19
Set the CardFrame Number to Assign Device Addresses to a CardFrame (NXF) 1. 2. 3. Disconnect power from the CardFrame. Determine desired address range for devices in the CardFrame. AMX recommends CardFrame device addresses begin at 301. Turn on the appropriate switches on the CardFrame DIP Switch to set the CardFrame number. To use our recommended device address set the CardFrame number to 25. (Switch one on, switch four on, switch five on, and all others off.) Re-power the CardFrame. Insert control cards in the desired slots. Cards will be assigned an address as CardFrame number *12 + slot number.
4. 5.
A little bit of math is required to determine the starting address. The DIP switch assigns a CardFrame number which is then multiplied by 12 and that result is added to the card slot number to get the address for that card. (DIP switch address x 12) + Card Slot Number (1-12) = Device Address For example if we have a card in slot 3 and the CardFrame number is 32 (switch 6 is on, all the others are off) the device address for the card is: (32 x 12) + 3 = 387 The address assigned to the card in the CardFrame overrides the address stored in memory of the Control Card. If the Control Card in the CardFrame is removed and placed in a NetModule Shell it does not retain the address from the CardFrame, but reverts to the last address it received when it was in a NetModule, or to a dynamic address as set at the factory if a fixed address was not yet assigned.
20
DIP Switch
There are two kinds of configurations for an AMX Control System, hardware and software. For the hardware configuration a DIP switch is used. DIP stands for Dual Inline Package and is a group of switches mounted to the module device that plugs into a PC board. The following are all configured with a DIP switch: NetLinx Master Card (hidden behind the front panel) NetLinx CardFrame NI4000 NXF-MINI DIP Switch2 is a 32-bit Windows program that graphically shows the DIP switch settings. The ON (down) and OFF (up) positions on the DIP switches are dynamically set when you enter device numbers and choose communication port options. You can also use the DIP switches to check a device number and/or communication setting. Set the program's DIP switches by clicking inside the ON or OFF switch area so the DIP switches match the settings on the device or communication port or by entering a number in the CardFrame Number.
21
PRD mode prevents the NetLinx program stored in the Master Card, from running when you power up the Master Card. PRD mode should only be used when you suspect the resident NetLinx program is causing inadvertent communication and/or control problems. If necessary, place the Master Card in PRD mode and use the NetLinx Studio program to resolve the communication and/ or control problems with the resident NetLinx program. Then, download the new NetLinx program and try again. Setting the Program Port DIP Switch 1. 2. 3. 4. Disconnect the power supply from the 2-pin PWR (green) connector on the Master Card. Remove the front faceplate and mounting screws (four) from the Master Card's front panel. Then, locate the Program Port DIP Switch (to the left of the Program port). Set DIP switch positions according to the information listed in the Baud Rate Settings and PRD Mode Settings table Card Frame above. Replace the front panel and faceplate back onto the Master Card and reconnect the 12 VDC power supply to the 2-pin PWR connector.
Program Port DIP Switch - baud rate settings The Program Port DIP Switch is located at the front of the Master Cards. For Modules, you must remove the front panel to access the DIP Switch. Use this DIP Switch to set the baud rate for the Program Port, according to the settings shown in the following table. Make sure the baud rate you set matches the baud rate on your PC's COM port before programming the Master Card. By default, the baud rate is set to 38,400 (bps). Note the orientation of the DIP Switch and the ON position label. Baud Rate Settings
Baud Rate 9600 bps 38,400 bps (default) 57,600 bps 115,200 bps Position 5 OFF OFF ON ON Position 6 ON ON OFF ON Position 7 OFF ON OFF ON Position 8 ON ON OFF ON
DIP Switch positions 3 and 4 are reserved for future features and should always be set to the Off (down) position.
22
System ID Numbering
Since more than 65,000 NetLinx masters can be connected together a method to identify those masters is needed. Each master is assigned a system number, much in the same way as the device number is assigned, in fact it is done from the device addressing tab of the NetLinx Diagnostics dialog. The Master in a NetLinx system is defined as device number 0. (Remember this, it will be important later.) By default the NetLinx Master Cards are shipped from AMX set to System ID number 1. To change the System ID of a NetLinx master instead of changing the Device ID, we simply change the System ID. Open the Device Addressing dialog from the Diagnostics menu.
In the Change Address section enter 0 for the device ID and the System ID of the master you want to change. (The system ID is shown in the top of the Online tab of the Project Navigator.) Check the Change System box and enter the new System ID in the adjacent field.
The easiest way is to disconnect the power from the master, but it can also be done from the Networking tab of the Diagnostics dialog and entering 0 for both the System ID and Device ID. Placing zeros in both fields will reboot the master that is currently connected to NetLinx Studio
23
Device:Port:System
In the NetLinx system a device can have multiple ports, therefore each port must be addressed. Additionally, since up to 65,535 NetLinx systems can be connected together, each device receives the system ID of the connected master. This addressing scheme is referred to as the Device:Port:System triplet.
All devices in a NetLinx system are given D:P:S addresses. Since the idea of ports is new to the NetLinx system, all Axcess and Landmark devices have only one port. For example, you have an Axcess touch panel connected to a NetLinx system whose system ID is 1, it would be referred to as address 128:1:1 .It is this addressing scheme that will allow a single NetLinx Master to control more than 400,000 RS232 or IR controlled devices.
D:P:S = 10001:1:0
When assigning an address to a device you can use a "0" for the system number. A system number of "0" refers to the current system. When working in master to master mode you will need to specify the actual number.
24
Set the Communication Settings and Connect to the Master Verify Devices Online Set NetLinx Time and Date Configure Network Settings Set the System ID and Reboot the Master Connect via the Network
Configuring a NetLinx Master When setting up a NetLinx system the Master card must be configured properly before anything can be done. Set the Communications Settings Set Networking Information Verify devices online Set System Time and Date Configure Network Settings Set the Device Addresses and System ID
25
2. 3.
Click Communication Settings... to access the Communication Settings dialog. Select NetLinx Master as the Platform Selection.
4. 5.
Select TCP/IP as the Transport Connection Option. Click Settings to open the TCP/IP Settings dialog.
26
6.
The Port should always be set to 1319 (default setting). Do notNetLinx change the Port assignment. Studio
7. 8. 9.
Click OK to return to the Communication Settings dialog. Click OK to return to the Master Communication Settings dialog. Click OK to close the Master Communications dialog.
Connecting to a NetLinx Master via Serial Port To connect to a NetLinx master, use the options in the Master Communication Settings and Communication Settings dialogs to specify the TCP/IP address, serial port or modem settings, depending on the transport connection type specified. These instructions in these topics assume that the physical link between the PC running NetLinx Studio and the NetLinx master is established. 1. 2. 3. 4. 5. Select Settings > Master Communication Settings to open the Master Communication Settings dialog. Click Communication Settings... to access the Communication Settings dialog. Select NetLinx Master as the Platform Selection. Select Serial as the Transport Connection Option. Click Settings to open the Serial Port Settings dialog.
27
6.
Select a COM port and specify the communication settings for serial port communications. The default settings are:
Comm Port Baud Rate Data Bits Parity Stop Bits Flow Control COM1 38400 8 None 1 None
7. 8. 9.
Click OK to return to the Communication Settings dialog. Click OK to return to the Master Communication Settings dialog. Click OK to close the Master Communications dialog.
Connecting to a NetLinx Master via Modem To connect to a NetLinx master, use the options in the Master Communication Settings and Communication Settings dialogs to specify the TCP/IP address, serial port or modem settings, depending on the transport connection type specified. These instructions in these topics assume that the physical link between the PC running NetLinx Studio and the NetLinx master is established. 1. 2. 3. 4. 5. Select Settings > Master Communication Settings to open the Master Communication Settings dialog. Click Communication Settings... to access the Communication Settings dialog. Select NetLinx Master as the Platform Selection. Select Modem as the Transport Connection Option. Click Settings to open the Modem Port Settings dialog.
28
6.
Select a COM port and specify the communication settings for modem communications. The default settings are:
Comm Port Baud Rate Data Bits Parity Stop Bits Flow Control Phone Number COM1 38400 8 None 1 None Enter the telephone number of the master.
7. 8. 9.
Click OK to return to the Communication Settings dialog. Click OK to return to the Master Communication Settings dialog. Click OK to close the Master Communications dialog.
29
4.
To change the target Master's time setting, select a field within the time display (hours, minutes, seconds, or AM/PM) and click the up and down arrows to adjust the selected field. Alternatively, you can highlight the field in the Time display that you want to adjust and type the desired number in its place. If no field is selected within the time display, the up/down arrows affect the hours setting.
5.
To set the specified Time/Date settings for the target system click Set Time/Date.
Changing the IP Address on a NetLinx Device Using DHCP Use the IP Address options in the Network Addresses dialog to change the IP Address for a specified NetLinx Device (using DHCP): 1. 2. 3. 4. 5. 6. Select Diagnostics > Network Addresses (or click the toolbar button) to access the Network Addresses dialog. At the top of the dialog, enter the specified device's System and Device numbers in the text boxes. The range is 0-65535. Click the Get IP Information button to populate the IP Address fields with the current Host Name and Gateway assignments. Click the Use DHCP radio button, and enter a new Host Name in the text box, if necessary. Click the Set IP Information button to set the new Host Name assignment. Click the Reboot Master button to reboot the master and accept the new changes. Allow 2030 seconds for the master to reboot.
When you change the IP Address of a master (if connected via IP), you must also change the communication settings to match the new IP Address in the Master Communications Settings dialog.
30
Setting the DNS Address for a NetLinx Master 1. 2. Select Diagnostics > Network Addresses (or click the toolbar button) to access the Network Addresses dialog. Enter the specified device's System and Device values in the text boxes at the top of the dialog (ranges = 0-65535).
3.
Click Get DNS Information to populate the DNS Address fields with the current Domain Suffix, DNS IP Address #1, DNS IP Address #2 and DNS IP Address #3 assignments (as applicable). Edit the DNS Address assignments and/or add new DNS address information as needed. Click Set DNS Information to set the new DNS address assignments.
4. 5.
Setting the IP Address for a NetLinx Master 1. 2. Select Diagnostics > Network Addresses (or click the toolbar button) to access the Network Addresses dialog. At the top of the dialog, enter the specified device's System and Device numbers in the text boxes (range = 0-65535).
If you change the IP Address of a Master (if connected via IP), you must also change the communication settings to match the new IP Address (in the Master Communication Setting dialog). NetLinx Masters are always set to Device = 0.
3. 4. 5. 6.
Click Get IP Information to populate the IP Address fields with the current Host Name, IP Address, Subnet Mask and Gateway assignments. Click the Specify IP Address radio button, and enter the new IP Address, Subnet Mask and Gateway assignments in the text boxes, as necessary. Click Set IP Information to set the new IP Address assignment. Click Reboot Master to reboot the master and accept the new changes. Allow 20-30 seconds for the master to reboot.
Changing the IP Address on a NetLinx Master (Use DHCP) Use the options in the Network Addresses dialog to change the IP Address for a specified NetLinx device (using DHCP). 1. 2. Select Diagnostics > Network Addresses (or click the toolbar button) to access the Network Addresses dialog. At the top of the dialog, enter the specified device's System and Device numbers in the text boxes. The range is 0-65535.
31
3. 4. 5. 6.
Click the Get IP Information button to populate the IP Address fields with the current Host Name and Gateway assignments. Click the Use DHCP radio button, and enter the new Host Name in the text box, if necessary. Click the Set IP Information button to set the new Host Name assignment. A message will be displayed indicating that the Master has accepted the new settings. Click the Reboot Master button to reboot the Master and accept the new changes. Allow 2030 seconds for the Master to reboot.
32
Connect to Master through front program port Set System Time & Date (Affects program references to TIME)
Go to Tools/Set Master Controllers Date/Time to open the dialog in NetLinx Studio Click "Set Time/Date" to set the NetLinx master to the time / date shown
Time shown without intervention is from the PC control panel clock Click "Get Time/Date" to see what the NetLinx master is already set to Type new time / date as required
Click Start Identify Mode Press button on device to change (DMS Keypad, NXI, Net Module Shell)
Use Dip Switches to set NetLinx cardframe address (see Dip Switch 2 for settings help)
Setup Networking
From Client's Network Administrator, determine whether DHCP or Static IP addressing will be used Got to Diagnostics/ Network Addresses Select DHCP or Specify
If Specify, enter IP, Subnet, and Gateway information obtained from Network Administrator.
33
System Preparation:
Using NetLinx Studio, Workspace Wizard In the Workspace window, import project support files
Program source code (.axs) IR files for each IR controlled device (.irl, .irv) Serial Protocol reference files (if available--.doc, .txt, etc.) Touch Panel / Keypad files (.tpd, .kpd, .ovl, etc.) System Drawings (.dwg, .vsd, etc.) Owner's Manuals (.pdf, .doc, etc.)
Set Device Mapping for each IR, Keypad, Touch Panel, and source code file Compile source code, if available (there should be no compile errors at this point) Transfer project files to the NetLinx master or control device as appropriate For NetLinx masters, reboot before testing
34
Principles of Programming
Principles of Programming
Lesson Topics:
The above program statement executes the same even if it looks like this:
BUTTON_EVENT[PANEL,1] PUSH: {IF(X = 1) {Y = 2 Z = 3}}
The syntax is identical, but the spacing is different. The first method is recommended because it is easier to read, and adheres to AMX programming conventions.
35
Principles of Programming
Language Basics Identifiers, Keywords and Operators are used to form a statement. Keywords are reserved words that perform a specific function or operation in the AMX Program An operator is a character that performs a specific mathematical, relational, or logical function
For example, the operator used to set a variable equal to a value is '=' The statement used to set variable X to the value 5 is X = 5
Identifiers are used to denote a device, constant, or variable. There are certain guidelines for identifiers:
Identifiers must begin with a letter followed by any combination of letters, numbers, or underscores. No spaces allowed. The identifier must have fewer than 27 characters Identifiers are not case-sensitive Each identifier must be unique. Once you define VHS3, do not choose the same name for a different identifier.
Valid identifiers: T_PANEL, CD3, VCR3_SELECT Invalid identifiers: 3VHS, CD PLAYER, *RGB4
For example, the keyword to turn a channel on is ON, and the statement to turn on a particular channel is ON [RELAY_CARD,RELAY] Statements can also involve mathematical or logical operations when operators are used.
Statement Keyword ON[RELAY_CARD,5] X = 5 Operator Identifier
Compound Statements are made up of several statements that are grouped together by a set of braces giving you the ability to have multiple statements within one argument.
Compound statements are used where several statements are to be executed as a single event. The statements are executed in the sequence they are programmed
.
The number of open and closed braces must be the same in your program. After compiling, NetLinx will list an error if the numbers are different. It is recommended that you insert braces in pairs to avoid a mismatch.
36
Principles of Programming
For an Event, when button 1 on PANEL is pressed, relay 5 on RELAY_CARD is turned on. Also, the variable X is assigned the value of 5. The open brace indicates the beginning of the compound statement, and the close brace ends it.
BUTTON_EVENT[TP,1] { PUSH: { ON [RELAY_CARD,5] X = 5 } }
If you only need the relay to be turned on, the statement could have been written like this:
PUSH ON [RELAY_CARD,5]
Since there is only one statement after the line PUSH[PANEL,1], braces are not necessary, but should be used to make the program easier to read and makes for a good habit. The following table lists the special symbols that are used when writing code. Special Symbols
Operator {} [] Name Braces Brackets Function Combine several statements into a compound statement. In NetLinx, Braces are also used to group "sets" of data or information. Enclose the device-channel set: [device, channel]. Enclose the location of a storage space in an array: Array_Name[5] Enclose the instance number for use with a SYSTEM_CALL: SYSTEM_CALL [2] VCR1(parameters) () Parentheses Enclose the expression after an IF statement: IF (X=1) Enclose a mutually exclusive set in the Define section: ([RELAY,1], [RELAY,2]) Enclose DEFINE_CALL parameter list: DEFINE_CALL TEST (parameters) Group a mathematical operation: NEW_VALUE = (X*Y+4) (**) or /* */ // Comments Comments Enclose helpful descriptions or remarks that are not considered part of the program and have no effect on the operation of the program. In NetLinx, the double slash is used for a single line comment.
37
Principles of Programming
Operators
An operator is a character (or group of characters) that performs a specific operational function. Each operator type is described below. Arithmetic Operators Arithmetic operators create a numeric value from one or more operations such as addition, multiplication, and division. Arithmetic Operators
Operator + * / % Function Addition Subtraction Multiplication Division Modulo (remainder after division)
Relational Operators A relational operator is a conditional statement and tells the program whether to execute a particular function or functions in the program. Relational Operators
Operator < > = == <= >= <> Function Less Than Greater Than Equal To Equal To Less Than or Equal To Greater Than or Equal To Not Equal To
Logical Operators Logical operators compare two conditions or, in the case of NOT, invert one condition. A true or false result is produced. Logical Operators
Operator && || ^^ ! Function Logical Or Logical Xor Logical Not Keyword OR XOR NOT Logical And AND
38
Principles of Programming
Bitwise Operators Bitwise operators are keywords or symbols that perform a bit-by-bit operation between two items. Bitwise Operators
Operator & | ^ ~ << >> Function Bitwise Or Bitwise Xor Bitwise Not Shift Left Shift Right Keyword BOR BXOR BNOT LSHIFT RSHIFT Bitwise And BAND
Shift Left shifts the bits of a value to the left n binary positions or effectively multiplies the value by 2n, where n is the number of places to shift. Shift Left is designated by a double less-than sign ( << ) or the LSHIFT keyword. Shift Right shifts the bits of a value to the right n binary positions or effectively divides the value by 2n, where n is the number of places to shift. Shift Right is designated by a double greater-than sign ( >> )or the RSHIFT keyword. An example of both is shown below:
X = 1 Y = 8 X = X << 2 Z = Y >> 3 (* X is now equal to 4 *) (* Z is now equal to 1 *)
39
Principles of Programming
Assignment Operators NetLinx also includes value increment and decrement operators. These operators with variables as statements work just like an Assignment operator or the equal sign does. The Increment-by-One operator or double plus sign (++) increments the value of its variable by one. The Decrement-byOne operator or double minus sign (--) decrements the value of its variable by one. The assignment operators may appear only once in a single NetLinx statement. Assignment Operators
Operator = ++ -Function Assignment Increment by 1 Decrement by 1
The following rules apply to the use of Direct assignment operators: The "=" operator may be used to assign
Expressions to intrinsic type variables (see Data Types) Arrays to other array of matching size and type Structures to other structures of the same type
The "++" and "--" operators are statements and cannot appear within expressions. For example:
FOR (I=1; I<10; I++) I = j++; // Legal // Illegal
Refer to the Structures subsection of the NetLinx Programming Language Guide for more information on structures.
40
Principles of Programming
Operator Precedence The table below shows the inherent precedence assigned to the operators. As noted in the chart, the NOT (!) operator has the highest precedence in NetLinx systems but the lowest precedence in Axcess systems. Axcess programs that are converted to NetLinx may exhibit logic problems if they use statements that combine NOT (!) and other operators. NetLinx Operator Precedence
Level 1 (highest) 2 3 4 5 6 7 (lowest) * + Operators ! ~ / % Associability Left To Right Left To Right Left To Right Left To Right Left To Right Left To Right Left To Right
Putting it Together
Using Templates Section 1 - you have your Definitions. For example, DEFINE_DEVICE is like the team roster, and the device addresses are like the players jersey numbers. DEFINE_VARIABLE is like the players positions
41
Principles of Programming
Section 2 & 3, DEFINE_START & DATA_EVENT; online are like the start of the game because it sets defaults and configuration just like a starting lineup tells the umpires what is going on.
Section 3, DEFINE_EVENT is like when the pitcher pitches and the batter swings; hit, strike, ball, walk, etc. and the defense is waiting for a hit; fly, grounder, etc. Something happens based on that pitch just like with an Event, the program waits for a triggering mechanism for it to act.
Section 4, DEFINE_PROGRAM which is Mainline is where you have Feedback and SYSTEM_CALLs; just like looking at the score board.
42
Principles of Programming
Mainline in NetLinx
Mainline is the section of the program that is executed continuously by the NetLinx Central Controller. DEFINE_PROGRAM contains the code known as Mainline that is executed continuously as long as the Controller has power.
A typical NetLinx program is composed of a number of different sections. Each section defines some aspect of a program such as device definitions, variable declarations, channel characteristics, or event processing.
In a NetLinx system, either DEFINE_PROGRAM or DEFINE_EVENT is required. Other sections are required only to support code in one of these two sections, although the Compiler might require more.
NetLinx processes network activity through a separate thread of execution. Bus activity is serviced concurrently with event processing and Mainline execution.
The DEFINE_EVENT section provides an efficient mechanism for processing events since Mainline does not have to be traversed to process a single I/O request. A handler can be defined for processing device-specific events as well as providing feedback for the device initiating the event notification. If a handler is present, Mainline will not be called to process the event; the handler is called instead. Once the handler completes its execution, the system is ready to process the next input message. When there are no more messages pending, Mainline is run. In effect, Mainline becomes an idle time process.
Mainline will be run every 1/2 second if no other event requires it first.
43
Principles of Programming
FIG. 1 illustrates Message and Mainline processing as it appears in the NetLinx system. Note that bus servicing is taken care of by a separate process thread (Connection Manager & Message Dispatcher) and therefore is not a task that must follow Mainline.
Messages
Communications Bus
Message Dispatcher
Message Queue
Connection Manager
DEFINE_EVENTS
Event Handlers
Next Message
DEFINE_PROGRAM
Mainline
End of Program
Next Message
Code Examples
Bitwise Operator - BAND Example: DEFINE_CALL 'NEC CHECKSUM' (CMD[20]) LOCAL_VAR INDEX LENGTH { CHECKSUM = 0 INDEX = 1 LENGTH = LENGTH_STRING(CMD) WHILE (INDEX <= LENGTH) { CHECKSUM = CHECKSUM + CMD[INDEX] INDEX = INDEX + 1 } CHECKSUM = CHECKSUM BAND $FF }
44
An example would be a multi-disc CD Changer. The CD Changer is the Object. Some Properties would be: Power Flag - keeps track of whether the power is on or off Disc number - keeps track of what disc is selected Function - keeps track of what transport function is active (Play, Stop, Pause, etc) Track - keeps track of what music track is currently selected
Some Methods would be: Play Stop Pause Skip Forward Skip Reverse Fast Forward Rewind
45
Buttons on an AMX touch panel can be considered an Object also. Some of the Properties of a button are: Associated device number Channel number Feedback type (channel, momentary, etc.) Variable text channel number Level number Pop Up page
46
Event Handlers
All interactions between external devices and the master processor are handled within mainline code. The processor runs mainline code, services the wait and pulse queues, and checks the bus for any changes in device status. These interactions or changes in status are Events. There are handlers to support five types of events: BUTTON_EVENTs include pushes, releases, and holds, which are associated with a push or release on a particular device-channel. CHANNEL_EVENTs occur when an output change (On/Off) is detected on a devicechannel. DATA_EVENTs include commands, strings, status, and error messages. LEVEL_EVENTs are received as a result of a level change on a particular device. TIMELINE_EVENTs trigger events based on a sequence of times.
The processing of an event associated with a given member of a device, channel, devicechannel, level, or device-level array must be completed before processing can begin on another event associated with the same array.
DEFINE_EVENT
NetLinx has a special program section called DEFINE_EVENT to handle the incoming events. The event processing that could only occur within mainline code can be handled in the DEFINE_EVENT section.
NetLinx maintains a table of the defined event handlers, when a new event comes into the NetLinx processing queue, the event is compared against the table of events. If the event is found, only the code in the event definition is evaluated and executed, mainline is bypassed. If an event handler is not defined, mainline is run, and the event is evaluated against the mainline code. This provides a more efficient mechanism for processing events, since mainline is not required to process a single I/O request. If no events are pending, mainline is run. Mainline becomes an idle time process.
Start
NO
Run Mainline
YES
Stop
More than one handler can be defined for the same event. In this case, the handlers are executed in the order in which they are defined in the program.
47
With the addition of the DEFINE_EVENT section for processing events, mainline becomes greatly diminished in NetLinx, if not totally eliminated. Programs can still be written using the traditional technique of processing events and providing feedback in mainline code. However, programs written using the event table structure will run faster and be much easier to maintain.
48
BUTTON_EVENTs
A BUTTON_EVENT occurs when an Input Channel turns on and off. When you think about events which may occur in relation to a button in a control system the events will fall into one of three categories: What happens when the button is pushed What happens when the button is released What happens if the button is held
What information describes a BUTTON_EVENT? Channel number of the button The D:P:S device number of the device generating the BUTTON_EVENT The individual Device Number, Port and System ID used for the D:P:S The amount of time the button has been held The [<device>, <channel>] declaration can contain a DEV device set, or a DEVCHAN devicechannel set in addition to an individual device and channel declarations. A HOLD event handler specifies the actions that should be performed when a button is pressed and held for a minimum length of time indicated by the TIME parameter (TIME is specified in 0.1 second increments). The REPEAT keyword specifies that the event notification should be repeated in TIME increments as long as the button is held. The BUTTON object is available to the BUTTON_EVENT handler as a local variable.
49
The following is an example of how a block of existing Axcess code can be rewritten using the NetLinx BUTTON_EVENT handler. The code below will send an A to an RS-232 port defined as KC1 upon a button push and will repeat the A string every 0.5 seconds until the button is released.
NetLinx BUTTON_EVENT:
DEFINE_EVENT BUTTON_EVENT[TP1,10] { PUSH: { TO[TP1,10] SEND_STRING KC1, A } RELEASE: { } HOLD[5,REPEAT]: { SEND_STRING KC1, A } }
In addition to evaluating the push within the event handler structure, you can see the simplified logic for creating the repeating A string using the HOLD event handler.
50
CHANNEL_EVENTs
Channel_Events are similar to Button_Events. Channel_Events are generated by an ON, OFF, PULSE, TO, or MIN_TO. CHANNEL_EVENT are very simple and only have two conditions: What happens when the channel turns on What happens when the channel turns off
Like BUTTON_EVENTs, the [<device>, <channel>] declaration can contain a DEV device set, or a DEVCHAN device-channel set in addition to individual device and channel declarations.
What information describes a CHANNEL_EVENT? Channel number of the device The D:P:S Device number of the relay card that contains the relay The individual Device number, Port and System ID of the D:P:S device number
In the following example, a CHANNEL_EVENT is defined to turn off a video projector every time the projector lift is raised. In NetLinx, you define a CHANNEL_EVENT for the Projector Lift Up relay and tell the system to turn off the projector every time this relay is turned on. Since turning on the relay or pulsing the relay does not produce a push, a BUTTON_EVENT is not generated.
51
52
DATA_EVENTs
This keyword defines a DATA_EVENT handler. This type of handler processes COMMAND, STRING, ONLINE, OFFLINE and ONERROR events. Please see DATA_EVENTs on page 145 for more information on this Event.
LEVEL_EVENTs
This keyword defines a LEVEL_EVENT handler. This type of handler is triggered by a level change on a particular device. Please go to LEVEL_EVENTs on page 129 for more information on this Event.
TIMELINE_EVENTs
A TIMELINE_EVENT is generated when the timer of the timeline matches a value in the timeline array. Please go to TIMELINE_EVENTs on page 204 for more information on this Event.
Event Parameters
It has already been stated that DEFINE_EVENT handlers are stored in an event table providing quick access to code that must be executed when an event is received. The event table keeps a list of all events in a sorted order to more quickly determine which code needs to be accessed for a giving incoming event. The event table is built before DEFINE_START runs and it not changed anytime after that. As a result, there are certain rules that must be applied to the parameters used in DEFINE_EVENTs.
Since the event table is built before DEFINE_START, all event parameters must contain the correct information prior to DEFINE_START. This requires that all EVENT parameters must be defined at compile time. In addition, many parameter "shortcuts" to help fulfill this requirement.
Using BUTTON_EVENT as an example, the simplest version of event parameters is a device and channel reference. In the following example: Example 1:
DEFINE_DEVICE dvTp = 128:1:0 DEFINE_EVENT BUTTON_EVENT[dvTp,1] { PUSH: Send_String 0,'Button 1 of dvTp was pushed' }
53
The device, dvTp, was defined in the DEFINE_DEVICE section, which has the effect of making it an initialized variable of type DEV, and the channel number was a hard-coded value of 1. Since both of these value were defined at compile time, the event is entered into the event table correctly. Let's take another example: Example 2:
DEFINE_DEVICE dvTp = 128:1:0 DEFINE_VARIABLE Integer nMyChannel DEFINE_START nMyChannel = 1 DEFINE_EVENT BUTTON_EVENT[dvTp,nMyChannel] { PUSH: Send_String 0,"'Button ',ITOA(nMyChannel),' of dvTp was pushed'" }
In this example, the event will not perform as the previous one did. When the code is compiled, the event parameters are dvTp, which is already assigned, and nMyChannel, which has a value of 0. nMyChannel does not get assigned a value of 1 until DEFINE_START, at which time the event has already been added to the event table. If you were to run this code, you would discover that it did in fact run when button 1 was pushed, leading us to one of the "shortcuts":
<bold>
A value of 0 for a Channel or Level Number in a BUTTON_EVENT, CHANNEL_EVENT or LEVEL_EVENT will be interpreted as an event handler for all events of that type from the given device number(s).
</bold>
So, the reason the above example runs when button 1 was pushed is that the above example runs when any button on dvTp is pushed. This "shortcut" was added so you could define an event handler for all buttons, channel or levels of a device without having to define a DEVCHAN of DEVLEV containing every value you may want to handle.
To make the example 2 behave like the example 1, we simply need to make sure the value of nMyChannel contains a value of 1 at compile time. This is simply done by initializing nMyChannel a value of 1 in the DEFINE_VARIABLE section. The new example reads: Example 3:
DEFINE_DEVICE dvTp = 128:1:0 DEFINE_VARIABLE Integer nMyChannel = 1 DEFINE_EVENT BUTTON_EVENT[dvTp,nMyChannel] { PUSH: Send_String 0,"'Button ',ITOA(nMyChannel),' of dvTp was pushed'" }
54
You may be tempted to use a more traditional variable as the channel number, mainly PUSH_CHANNEL or RELEASE_CHANNEL. It is important to realize that the identifiers are nothing more than global (system) variable. At compile time, the values are defined and contain a value of 0. So the following code: Example 4:
DEFINE_EVENT BUTTON_EVENT[dvTp,PUSH_CHANNEL] { PUSH: Send_String 0,"'Button ',ITOA(BUTTON.INPUT.CHANNEL),' of dvTp was pushed'" RELEASE: Send_String 0,"'Button ',ITOA(BUTTON.INPUT.CHANNEL),' of dvTp was released'" }
will have the effect you expect but probably for a different reason than you expect. Although the event will run for both the push and release of all buttons for dvTp, you may also be tempted to think that you need to make sure the event runs for RELEASE_CHANNEL by adding the following: Example 5:
DEFINE_EVENT BUTTON_EVENT[dvTp,PUSH_CHANNEL] BUTTON_EVENT[dvTp,RELEASE_CHANNEL] { PUSH: Send_String 0,"'Button ',ITOA(BUTTON.INPUT.CHANNEL),' of dvTp was pushed'" RELEASE: Send_String 0,"'Button ',ITOA(BUTTON.INPUT.CHANNEL),' of dvTp was released'" }
However, since both PUSH_CHANNEL and RELEASE_CHANNEL have a value of 0 at compile time, you are in effect stacking two events that are interpreted as running for any button pushed on the panel and as a result, the event is run twice every time a button is pushed or released. This may not seem like a big problem until you try to toggle a variable in the event: since the event runs twice for every button push, the variable toggles on then toggles off again.
There are some additional parameter "shortcuts" available. In all cases, the following rules apply: When a DEV can be used, a DEV array can also be used. When a DEVCHAN can be used, a DEVCHAN array can be used. When a DEVLEV can be used, a DEVLEV array can be used. When a Char, Integer or Long can be used, a Char, Integer or Long array can also be used. You can apply more then 1 of the above rules at a time in a given event handler.
GET_LAST() can be used to determine which index of an array (any type) caused the
event to fire.
55
The above rules can let you write some interesting event handler. Let's say you wanted to handle 4 buttons from 6 panels all with one BUTTON_EVENT. You could write: Example 6:
DEFINE_DEVICE dvPanel1 = 128:1:0 dvPanel2 = 129:1:0 dvPanel3 = 130:1:0 dvPanel4 = 131:1:0 dvPanel5 = 132:1:0 dvPanel6 = 133:1:0 DEFINE_VARIABLE DEV dvMyPanels[] = { dvPanel1, dvPanel2, dvPanel3, dvPanel4, dvPanel5, dvPanel6 } INTEGER nMyButtons[] = { 4, 3, 2, 1 } INTEGER nPanelIndex INTEGER nButtonIndex DEFINE_EVENT BUTTON_EVENT[dvMyPanels,nMyButtons] { PUSH: { nPanelIndex = GET_LAST(dvMyPanels) nButtonIndex = GET_LAST(nMyButtons) Send_String 0,"'Button Index=',ITOA(nButtonIndex),' was pushed on Panel Index=',ITOA(nPanelIndex)" } }
This event will be run for all combinations of dvMyPanel and nMyButtons, 24 buttons in all. The GET_LAST() function is very useful when running event using array as parameters. GET_LAST() returns an index value, starting at 1, for the element that triggered the event. In the case of nButtonIndex, it will contain a value of 1 when button 4 was pressed, a value of 2 when button 3 was pressed, ... This can be very useful in the case of transmitters and wired panels where the channel number may not reflect a numerical sequence you would like, such as with Numeric Keypads.
56
Channel Characteristics
Channel Characteristics
Lesson Topics
Device-Channel Concept Input Characteristics Output Characteristics Feedback Statements Mutually Exclusive Groups/ Sets
Controlling Something Over There The basic idea behind a remote control system is to do something over here to make something happen over there. In the DEFINE_PROGRAM section of the source code you define what happens when an input is received.
How do you get the inputs into the system? How do you generate an output?
Device-Channel Concept
Everything that an AMX Control System controls is controlled through a device in the system. Each device communicates to the Central Controller. Most devices, such as a Touch Panel or a relay card, have channels which either generate an input, accept an output, or both. These inputs and outputs are referred to in the program as a "device-channel" pair, which is written like this:
[8,1] //DEVICE 8, CHANNEL 1
The device-channel is the most fundamental concept of an AMX Control System, as it is the most common way that an AMX program communicates to the outside world.
57
Channel Characteristics
Input Characteristics
When a button is pressed on a control panel the input function of the button sends an input change to the master. The master then directs the reference to the event handler.
Input keywords are generally followed by the [device, channel] set that created the input. Example: BUTTON_EVENT[TP,1] or BUTTON_EVENT[128:1:0]
Input Keywords
PUSH: Input change from off to on when a button is pushed.
BUTTON_EVENT [DEVICE,CHANNEL]
HOLD: A HOLD event handler specifies the actions that should be performed when a button is pressed and held for a minimum length of time indicated by the TIME parameter (TIME is specified in 0.1 second increments).
HOLD [VALUE,REAPEAT]:.
All AMX panel and transmitter functionality comes down to programming PUSH and RELEASE statements.
Inputs PUSH/ RELEASE are the leading and trailing edges of a Channel PULSE
PUSH HOLD RELEASE
Leading Edge
Trailing Edge
58
Channel Characteristics
Output Characteristics
An output is activated only by a keyword. The output channel change from the system master causes an action on a device. The output function affects channels on a device. The channel can be turned on or off.
ON[TP,1]
For an Output function to be sent to a device (like a television), the appropriate input function must be associated to the device. Therefore, once an input function (such as button "1" on a touch panel) is selected, an associated output function (the VCR turns on) will occur.
BUTTON_EVENT [TP,1] { PUSH: { ON [VCR, 9] } }
Some output keywords create a sequence of ON then OFF after some period of time.
PULSE[RELAY,1]
Output Keywords
ON: The On keyword turns on a channel or variable. If the channel or variable is already on, its status will remain the same. If the variable contains zero, it is off; therefore, any number other than zero denotes the system as on.
ON [VCR,2] (* This turns on channel 2 of device VCR *)
OFF: Turn a channel or variable off. Variables simply get set to 0. TO: Toggle a latching channel or variable, or will momentarily turn on a non-latching one until button is released. TO turns ON an Output channel while an Input channel is On and turns off the Output channel when the Input channel turns Off.
TO[device,channel]
MIN_TO: Toggle a latching channel or variable, or will momentarily turn on a nonlatching channel until the associated button is released. In the case of a momentary channel, the channel will be on for a minimum time specified by SET_PULSE_TIME system variable or the current pulse time setting. PULSE: Momentarily turns on a channel for a set period of time. The pulse on time is determined by SET_PULSE_TIME system variable and the default pulse time is 1/2 second.
PULSE[device,channel]
59
Channel Characteristics
ON
OFF
Theres a PULSE thats a regulated ON/ OFF and a TO thats a variable ON/ OFF and a MIN_TO which is a fixed pulse (based on current pulse time at a minimum and a variable pulse length afterwards.
PUSH PUSH RELEASE
PULSE ON OFF
PUSH
RELEASE
Feedback Statements
This section describes how to assign feedback to a button. Feedback refers to the lighting of a button during and after it is pressed. The system does not do this automatically; you must tell it how to light the button via the program.
There are two types of feedback: Direct - reference to "real time" feedback.
[TP,1] = [RELAY,1]
Indirect - is "pseudo" feedback which means the program turned on feedback because it thinks something directly caused it.
Where possible, it is best to use direct feedback, since it is tied directly to a channel on a device.
60
Channel Characteristics
Feedback involves only one statement per button. The first part of the statement references the device-channel of the button that is going to be lit. It is followed by an equal sign (=) and the conditional feedback. For example:
DEFINE_PROGRAM [TP,1] = [RELAY,SCREEN_UP]
When RELAY channel 1 (the constant value of SCREEN_UP) is on, the light of TP button 1 will also be on. When the channel is off, the light will be off. Any reference to a device-channel that does not have the keyword PUSH or RELEASE preceding it is referring to the output side of the channel. This is a very important concept, because it is the basis of how feedback works.
One way of creating an output change is to assign a value directly to the device-channel. If the value that you are assigning is another device-channel reference it tells Axcess to take the output status of channel SCREEN_UP on device RELAY, and send it as an output change to channel 1 of device TP. Since the device-channel [RELAY,SCREEN_UP] is defined as being in a mutually exclusive group, its status will be ON if it was the last channel activated in that set, and the feedback assignment will light button 1 on the Touch Panel.
This feedback section will act no differently if each statement is placed under its corresponding PUSH statement.
Feedback statements are most often placed in the DEFINE_PROGRAM section of the program. However, it is recommended that you organize them in your program so that they can be easily located. While grouping all of the feedback statements at the end of the program is acceptable, in larger programs it can be confusing to skip from the top where the BUTTON_EVENT statement is located to the bottom where the feedback statements are located. Smaller programs may be easier to manage if all the BUTTON_EVENTs are together and all the feedback statements are together.
61
Channel Characteristics
Ranges of channels can be assigned using two periods. The example below defines Relays 1, 2, 3, 4 and 5 as being Mutually Exclusive.
DEFINE_MUTUALLY_EXCLUSIVE ([LIGHTS,1]..[LIGHTS,5])
Even if Relay 1 is pulsed, so it turns off after 1/2 second, the Feedback will still show that it is on, since it was the last active element in the Mutually Exclusive Group.
62
Software History Types of Errors Tracking Down Errors Resources For Debugging
Sofware History
Open Software History from the Tools menu.
This is now a Windows-based application inside NetLinx Studio that lists the firmware history and all of the functions of EVERY AMX product. Software History lists: Available Channels and their functionality Available Levels All SEND_COMMAND instructions, format, and functionality All SEND_STRING commands, format, and functionality Use this information to learn the functions available or protocol required for each AMX product.
63
Debugging
Types of Errors
No programs are ever written without errors on the first try, and one of the most time-consuming parts of programming is debugging. There are three general types of programming errors: Compiler errors: Errors that occur at compile time. The compiler alerts you to these errors immediately and identifies each error and the line where it is located.
Messages sent from the compiler to alert you to a Syntax Error or a Definition Error
Syntax Errors occur when Keywords are misused or Statements have the wrong format Definition Errors occur when Identifiers are used within the program but have not been defined.
These errors must be corrected before the AMX program can be compiled. Compiler identifies each error and the line where it is located. Many errors occur due to typos.
Run-time errors: Errors that occur after the program has been compiled and loaded into the Central Controller. These errors are caused by program statements that attempt illegal operations. Logic errors: Logic errors are errors in program design and thus are the programmer's responsibility; Axcess cannot tell if the program it is executing is accomplishing what the user intends.
64
Attempted CALL to undefined subroutine Comment never ends, EOF encountered Conditional compile nesting too deep
Duplicate symbol Evaluation stack overflow Evaluation stack underflow Identifier expected
Identifier is not an array type Include file not found Invalid Include file name
65
Library file not found Maximum string length exceeded Must be char array reference Must be integer reference
The library file containing the specified SYSTEM_CALL could not be found. String literals are limited in length to 132 characters, including spaces. An array type variable was expected in CREATE_BUFFER, CREATE_MULTI_BUFFER, or CLEAR_BUFFER. The identifier in question must be an integer. This error occurs when the third parameter of CREATE_LEVEL is an array or array element. This error means that the compiler cannot find the line number to even check what type of error has occurred, so it gives no details on the cause. If you get this non-descriptive error when compiling and the code contains modules, check to make sure the module parameters are the right type. If you're trying to pass in a one-dimension array where the module requires a two-dimension array, or a CHAR instead of an INTEGER, etc., this error will occur.
Out of memory
The compiler has run out of memory. Free up memory either by removing any pop-up programs or drivers, by using extended memory, or by breaking your program into one or more Include files. A value or variable passed to a CALL as a parameter is of the wrong type as defined by the DEFINE_CALL statement. Move the PROGRAM_NAME= statement to the first line of the program. A PUSH or RELEASE statement was found within a block of code headed by a PUSH or RELEASE statement. These keywords are not allowed in a section of code which will be executed due to a WAIT keyword.
Parameter mismatch in CALL PROGRAM_NAME must be on line 1 PUSH/RELEASE not allowed within PUSH/ RELEASE PUSH/RELEASE not allowed within WAIT PUSH_CHANNEL not allowed within WAIT RELEASE_CHANNEL not allowed within WAIT PUSH_DEVICE not allowed within WAIT RELEASE_DEVICE not allowed within WAIT String constant expected
A string is required for the particular operation. This error occurs if a string literal enclosed in single quotes does not follow the PROGRAM_NAME keyword. A string literal is started but never ends. Add a closing single quotation mark (' ) to the end of the string. A string is required for the particular operation. This error would occur if a string literal enclosed in single quotes does not follow the #WARN keyword. A subroutine cannot call itself. It can, however, call a different subroutine. A syntax error is found in an expression. In most cases, this error means that a character is out of place or something is misspelled. This error occurs when a library file is compiled and the name of the subroutine in the library file does not match the PROGRAM_NAME string on the first line of the file. This error occurs when an attempt is made to use an array variable with DEFINE_LATCHING , DEFINE_TOGGLING, or DEFINE_MUTUALLY_EXCLUSIVE .
Subroutine may not call itself Syntax error SYSTEM_CALL name not same as PROGRAM_NAME in <file> This variable type not allowed
66
To not allowed within DEFINE_START To not allowed within MAINLINE To not allowed within RELEASE To not allowed within WAIT Too few parameters in CALL Too many Include files Too many parameters in CALL Type mismatch in function CALL
These errors occur if the TO keyword is found in an erroneous location. The TO keyword can only be associated directly with a PUSH statement.
There are not enough parameters being passed to the subroutine. A program may only contain up to 20 Include files. There are too many parameters being passed to the subroutine. A function was called with a parameter of the wrong type. For instance, attempting to use ITOA with an array as a parameter will result in an error. An attempt was made to reference an identifier that has not been defined previously in the program. An #END_IF keyword was found, but no #IF_DEFINED or #IF_NOT_DEFINED was previously compiled. An invalid character was found during compilation. This error occurs if a SYSTEM_CALL statement is written incorrectly as SYSTEM_CALL 'NAME' [INSTANCE NUMBER]. Variables may not be assigned a value when they are defined in the DEFINE_VARIABLE section. A statement references a WAIT by a name that does not exist. For example, CANCEL_WAIT 'CASS' will produce this error if there is no WAIT named CASS.
Undefined identifier Unmatched #END_IF Unrecognized character in input file Use SYSTEM_CALL [INSTANCE] 'NAME'
67
Compiler Warnings Sometimes the compiler generates a warning message instead of an error message; these warning messages always start with "w". A warning about a particular statement means that the statement is not technically an error, but you should be careful doing it. Warnings, unlike errors, do not stop the program from compiling.
Some types of warnings can be disabled in the Compiler Options tab of the Preference dialog. Common compiler warnings are described below: Compiler Warnings
(w) Cannot assign unlike types This warning occurs when a variable or value of one type is assigned to a variable of a different type. Here are some examples: Assigning a string literal, string expression, or array to a non-array variable Assigning a non-array variable to an entire array Assigning an integer array to a non-integer array Assigning a two-dimensional array to a one-dimensional array, or vice versa Assigning the result of a function that returns an array type to a non-array variable or to a two-dimensional array variable (for example, X = ITOA(12), where X is a non-array variable or two-dimensional array variable) Assigning the result of a function that returns a non-array type to a one- or two-dimensional array variable (for example, X = ATOI('AMX'), where X is a one- or two-dimensional array variable) This message is a warning and not an error, because X = ITOA(12) works correctly when X is a simple variable, since the result is a single value between and 65,535. The generation of this warning can be turned on or off in the Compiler Options tab of the Preference dialog. (w) Define_Call is not used This warning occurs at the end of program compilation for each DEFINE_CALL subroutine that was declared but never used. The generation of this warning can be turned on or off in the Compiler Options tab of the Preference dialog This warning appears when the keyword INTEGER is applied to a non-array type of variable. Doing this is not an error, because non-array variables are already integers, but it is redundant. The generation of this warning can be turned on or off in the Compiler Options tab of the Preference dialog. This warning occurs if the compiler finds a LONG_WHILE or MEDIUM_WHILE inside a block of code following a WHILE keyword. This warning exists because the WHILE command has a 1/2 second timeout period, and the LONG_WHILE and MEDIUM_WHILE keywords do not. This could create a hard-to-find logic error. The solution is to change the WHILE to a LONG_WHILE to fix this problem. The generation of this warning can be turned on or off in the Compiler Options tab of the Preference dialog. This warning appears if there is a large amount of nesting in the program. This can happen with a long chain of IF...ELSE IF statements. The solution is to use the SELECT...ACTIVE set of statements. The generation of this warning can be turned on or off in the Compiler Options tab of the Preference dialog. This warning occurs at the end of compilation for each variable that was declared but never used. The generation of this warning can be turned on or off in the Compiler Options tab of the Preference dialog.
68
FIG. 1 NetLinx Compiler tab showing the Compile With Debug Info enabled.
After this is enabled go to the Diagnostic Menu and select Enable NetLinx Internal Diagnostic Messages (FIG. 2). The resulting notification messages are displayed in the Notifications tab of the Output Display window. The Notifications tab contains 13 columns. Each column represents a notification type (which are enabled/disabled in the NetLinx Notification Properties dialog). If a notification type is enabled, the word ON is displayed in the appropriate column. Initially, the only entry in the notifications list is All Devices, and the only notification enabled is Input.
69
For more information on Using NetLinx Device Notification go to the NetLinx Diagnostics section of the NetLinx Studio instruction manual on www.amx.com.
Logic Errors
Logic Errors or Functional Errors are mistakes in the operations of the system. Logic Errors can only be identified through testing the system.
YOU never told the system to do something. YOU told the system to do the wrong thing.
To view Push results, select Diagnostics > Enable Push Message Status Bar Display.
NetLinx Studio displays the most recently received Push, or Push status (Push Enabled/Disabled) in the Status Bar. Left-mouse click on the push message displayed to view a history of push messages. Then, right-mouse click within the list box to view the available options. Using NetLinx Device Emulation Emulating a device in NetLinx Studio means that the program generates messages that appear to the master to have come from a specified <D:P:S> combination (real or fictitious).
70
The options in the Emulate a Device dialog allow you to specify the <D:P:S> combination for a device you want to emulate.
Use device emulation to simulate basic control of a specified NetLinx Master, including Channels (PUSH/RELEASE), Levels and String/Commands. Use this option to test specific areas in your Source Code against a specific device.
To use NetLinx Device Emulation: 1. 2. 3. Select Diagnostics > Emulate a Device (or click the toolbar button) to access the Emulate a Device dialog. Enter the Device, Port and System <D:P:S> combination of the device you wish to emulate (real or fictitious). The Device, Port and System value ranges are 0-65535. To emulate a channel (push/release), enter a valid Channel number to emulate Channel messages (i.e., Push/Release, CHON, and CHOFF ) for the specified <D:P:S> in the Channel text box. The Channel number range is 0-65535. Select the Push button to emulate a push/release on the channel specified. You may click and hold down the Push button to see how the master controller responds to the push message. Select the On or Off buttons to emulate Channel ON (CHON) and Channel OFF (CHOFF) messages for the specified <D:P:S>. 4. To emulate a level, enter the desired Level (number), Value and data Type (BYTE, CHAR, WIDECHAR, INTEGER, SINTEGER, ULONG, LONG, FLOAT, or DOUBLE), and click Send to emulate the specified level and value. The Level number range is 0-65535. The list below contains the valid level data types and their ranges:
Min Value CHAR INTEGER SINTEGER LONG SLONG FLOAT 0 0 -32768 0 -2147483648 -3.402823466e+38 Max Value 255 65535 32767 429497295 2147483647 3.402823466e+38
5.
To emulate sending a String or Command, type a String or Command in the Message(s) To Send text box. Use the Return key within the text box to enter a new line for the next message.
Hold down the Shift key to select a specific range of lines to send to the controller instead of all the lines within the edit control.
71
a. Click the Message Type radio buttons (String or Command) to specify the type of message you are sending. b. Click Send To Master to send the messages in the Message(s) to Send text box to the master. If none of the messages are selected (highlighted), all messages are sent. If you have selected a line or a range of lines, only the selected messages will be sent 6. Check the Messaging Options checkboxes to Enable Asynchronous Notifications and/or Enable Internal Diagnostic Messages.
It is recommended that you enable NetLinx Notifications to view the results in the Notifications tab of the Output Display window. For example, in order to view a string sent to a device (via the Emulate Device dialog), you must first enable the Strings to Device notification (in the NetLinx Device Notifications Options dialog). Additionally, to view any strings returned from the device, you must enable the Strings From Device notification.
72
Using NetLinx Device Control Controlling a device in NetLinx Studio means that it will appear to a specified System device that messages are being sent from the NetLinx master controller. The options in the Control a Device dialog allow you to specify the <D:P:S> combination for the target device you want to control.
Use device control to simulate basic control of a specified NetLinx device, including Channels (PUSH/RELEASE), Levels and String/Commands. Use this option to test specific areas in your Source Code against a specific device. To use NetLinx Device Control: 1. 2. Select Diagnostics > Control a Device (or click the toolbar button) to access the Control a Device dialog. Enter the Device, Port and System <D:P:S> combination of the device you wish to control. The <D:P:S> value ranges are 0 - 65,535. 3. To emulate a channel (push/release), enter a valid Channel number to emulate Channel messages (i.e., Push/Release, CHON, and CHOFF) for the specified <D:P:S> in the Channel text box. The Channel number range is 0-65535. Select the Push button to emulate a push/release on the channel specified. You may click and hold down the Push button to see how the master controller responds to the push message. Select the On or Off buttons to emulate Channel ON (CHON) and Channel OFF (CHOFF) messages for the specified <D:P:S>. 4. To emulate a level, enter the desired Level (number), Value and data Type (BYTE, CHAR, WIDECHAR, INTEGER, SINTEGER, ULONG, LONG, FLOAT, or DOUBLE), and click Send to emulate the specified level and value. The Level number range is 0-65535. The list below contains the valid level data types and their ranges:
Min Value CHAR INTEGER SINTEGER LONG SLONG FLOAT 0 0 -32768 0 -2147483648 -3.402823466e+38 Max Value 255 65535 32767 429497295 2147483647 3.402823466e+38
73
5.
To emulate sending a String or Command, type a String or Command in the Message(s) To Send text box. Use the Return key within the text box to enter a new line for the next message. When entering a send command (in the context of this dialog) do not include the "send c" or "send_command" in the statement - only type what would normally occur within the quotes, but don't include the quotes either. For example to send the "CALIBRATE" send command, simply type CALIBRATE (no quotes) rather than SEND_COMMAND <dev> "CALIBRATE".
Hold down the Shift key to select a specific range of lines to send to the controller instead of all the lines within the edit control.
a. Click the Message Type radio buttons (String or Command) to specify the type of message you are sending. b. Click Send To Master to send the messages in the Message(s) to Send text box to the master. If none of the messages are selected (highlighted), all messages are sent. If you have selected a line or a range of lines, only the selected messages will be sent. 6. Check the Messaging Options checkboxes to Enable Asynchronous Notifications and/or Enable Internal Diagnostic Messages.
It is recommended that you enable NetLinx Notifications to view the results in the Notifications tab of the Output Display window. For example, in order to view a string sent to a device (via the Emulate Device dialog), you must first enable the Strings to Device notification (in the NetLinx Device Notifications Options dialog). Additionally, to view any strings returned from the device, you must enable the Strings From Device notification.
Terminal Window
NetLinx Studio provides a terminal interface to NetLinx and Axcess devices that support an interactive terminal mode. The Terminal toolbar is enabled when the Terminal window is opened, with connect/disconnect commands and the (ASCII, Hex, and Decimal) display commands.
Using the Terminal Window Select Tools > Terminal (or click the toolbar button) to open the Terminal window. The Terminal window puts the Master Controller into dumb terminal mode. Anything that is typed on the screen exits through the Master communications port, and anything coming in from the communications port is displayed in the Terminal Emulator window. Use the Terminal window to communicate directly with the Master Controller and to debug RS-232-controlled devices. You cannot use the Terminal window while a communication port is in use for a file transfer or debug operation. Type "ECHO ON" in the Terminal window display messages. If the Terminal window becomes unresponsive, close and re-open the window.
74
To leave the Terminal window active for a long session, click the Terminal Locks the Port option in the General tab of the Preferences dialog. Use the Format tab of the Preferences dialog to change the appearance of the elements of the Terminal window. To use the Terminal window with NetLinx systems, you must be connected to the Master via the PROGRAM port. Otherwise, you can use Windows TelNet for terminal control of NetLinx systems. The Terminal Window does not support: Cut operations. Editing operations within the window, other than to input characters at the cursor. (The text in the terminal window actually reflects what has been received from the device. Text that is typed in the window will not appear unless echoing is currently enabled on the device).
TelNet
You can also communicate with the NetLinx Master via Telnet using a TCP/IP connection. Both TelNet and the NetLinx Terminal offer the same commands. As with Axcess systems, the commands reside on the central controller not within th terminal program. The command set is different than the command set available to Axcess systems. In addition to device and system diagnostics, the NetLinx terminal commands also allow for the diagnostics and configuration of NetLinx systems on a network.
You can add TelNet to your Tools menu by: 1. 2. 3. 4. 5. 6. Selecting Settings > Preferences to open the Preferences dialog. In the Tools tab, click the New button to create an empty text field in the Menu Contents list. Enter TelNet for the application. In the Command text box type "TelNet". Click Close to close the Preferences dialog. The new shortcut should appear at the bottom of the Tools menu.
75
1. 2. 3. 4. 5. 6.
Open and compile a Source Code file (that contains at least one variable), if you have not already done so. The file must be successfully compiled before you can enter debug mode. Choose Build > Debug to open the Watch window. If this option is disabled, make sure your Master Communications Port settings are set to connect to your Master Controller. Right-click inside the Watch window to open the Watch Window context menu. Click Add to insert a new variable in the Watch window. A box appears in the window, with a cursor blinking in the Name column. Type the syntax of the variable exactly as it is defined in the code and press the Enter key. The value of the specified variable appears next to the variable (in the Value column). You can select different view formats for the Value by right-clicking on the line containing the variable/value, and clicking on Display in the Watch window context menu. This opens the Display sub-menu.
76
Variables
Variables
Lesson Topics:
A variable represents a place to store data that will change as the program is executed. Think of a variable as a container, nearly anything can be placed in it. For example, an integer variable can represent any number from 0 to 65,535. An integer variable cannot hold a negative number. If one variable is subtracted from another, the result will always be positive. If you subtract a larger number from a smaller number, the result wraps around at 65,535. For example, 10-20 = 65,525. VariableName = <expression>
NetLinx allows variables to be defined with more data types and data ranges. NetLinx can also define variables which hold larger numbers, negative numbers, and decimal numbers.
If you use too many Variables it can make your program very confusing, so use them wisely.
When the system is turned off, variables retain their values as long as there are working back up batteries. Resetting or initializing can be done manually in the DEFINE_VARIABLE section of the program.
77
Variables
Data Types
Type
CHAR INTEGER WIDECHAR SINTEGER LONG SLONG FLOAT DOUBLE
Description
Single byte values and character strings Default variable value to store values up to 65,535. Wide character strings dealing with Unicode fonts that use 16-bit character codes and also most Far-eastern fonts Signed integer values both greater than and less than zero Stores large integer values esp. greater than 65,535 Signed large integer values less than -32,767 and greater than 32,767
Range
0 to 255 (8-bit) 'a', 145, $FE, 'The quick gray fox' 0 to 65,535 (16-bit) 0 to 65,535 (16-bit) "'OFF',500" -32,767 to 32,767 (16-bit) 0 to 4,294,967,295 (32-bit) -2,147,483,647 to 2,147,483,647 (32-bit)
Stores signed floating point numbers to 7 places 1.17E-38 to 3.40E38 with7 digits of preciof precision sion (32-bit) Stores signed large floating point numbers to 16 2.22E-308 to 1.79E308with 16 digits of places of precision precision (64-bit)
Behavior Types
The role of the DEFINE_VARIABLE section is enhanced for NetLinx. The structure of a variable definition is:
[NON_VOLATILE|VOLATILE][CONSTANT][<type>]<variable name> [= <value>]
The NON_VOLATILE and VOLATILE keywords specify what happens to a variable when the program is downloaded or after a system reset. NON_VOLATILE variables (the default) lose their values when the program is downloaded, but retain their values when the system resets. VOLATILE variables lose their values when the system is loaded and after system resets. If you initialize a VOLATILE variable in the DEFINE_VARIABLE section, the value of the variable is set every time the code is loaded or after a system reset. The variable initializes like it would in the DEFINE_START section. If you initialize a NON_VOLATILE variable within the DEFINE_VARIABLE section, the variable only initializes when the system is loaded, and it retains any changed values after system resets.
Variables can now be defined as constant variables. Since the DEFINE_CONSTANT section does not allow you to explicitly declare a constant's data type, using the CONSTANT keyword allows you to explicitly declare the data type of a constant, and to define constant values for structures and arrays of structures.
CONSTANT STR_TV CHAN_5 = {'KXAS', 5} CONSTANT SINTEGER ABS_ZERO = -273
78
Variables
Persistence
Persistent variables are NetLinx program variables that maintain their value between updates to the NetLinx program. The user can define a variable to be persistent using the PERSISTENT storage modifier as show below:
PERSISTENT CHAR cMyString[100]
All persistent variables are automatically non-volatile. It is not legal to define a variable as VOLATILE and PERSISTENT. Non-volatile variables: A variable declared with the NON_VOLATILE keyword is stored in non-volatile memory. It will retain its value in the event of a system powerdown, but is reset to zero if the program is reloaded. Unless specified otherwise, all variables are stored in non-volatile memory. Volatile variables: A variable declared with the VOLATILE keyword is stored in volatile memory and reset to zero after either power-down or reload. Volatile memory is generally faster and more plentiful than non-volatile memory. For this reason, you should use the VOLATILE keyword when declaring large data arrays where persistence of the data is not a requirement. Persistent variables: If a variable is declared with the PERSISTENT keyword, it is initialized to zero the first time the program is loaded but will retain its value after either power-down or reload. If the data type is omitted from the variable definition, the following defaults are assumed: Single variables are INTEGER type Arrays are CHAR type When a NetLinx program has a persistent variable declared, subsequent downloads of new NetLinx programs containing the same persistent variable will retain the variable settings. By default, nonpersistent variables are set to zero after a NetLinx program download. Persistence overrides this behavior by setting the variable in the newly downloaded program to be the same as it was before the download.
Typically, persistent variables are used for saving preset information. Suppose you have a system that contains several PosiTrack camera positioning systems, and that the user interface to the system allows the user to set the position of any of the cameras and record that position for recalling later. The position presets are stored in a non-volatile array variable so they are maintained during a power cycle. Without persistent variables, an update to the NetLinx program would zero out all of the presets the user had stored. With persistent variables, the new NetLinx program can be downloaded and all of the presets remain intact.
When a new NetLinx program is downloaded to the Master, the Master iterates through all nonvolatile variables from the new program looking for persistent ones. When it finds a persistent variable in the new program, it searches the old programs persistent variable space for the same variable. When it finds the same variable, the value of the new variable is set to the same value as the old variable. The Master identifies the same variable by verifying the following:
79
Variables
Variable name Variable source location Variable type Therefore, in order for persistence to function properly the name, type, and file location declared must be the same as the previously downloaded NetLinx program. If you changed any of the three, the new persistent variable will not be set with the old variable's value.
Constancy
Any variable may also be assigned the attribute CONSTANT. This declares a variable to be immutable (cannot change at run-time). The variable must be initialized as part of its declaration if this keyword is used.
80
Variables
Scope
Scope is a term used in reference to program variables that describe where in the program they can be accessed. There are two types: Local scope: a variable can only be accessed in the subroutine or method that it is declared. (NetLinx only) Global scope: a variable can be accessed anywhere in the program. Scope differentiates the two basic classes of NetLinx variables: Local variable: a variable declared within a subroutine, event, or function whose scope is limited to that subroutine or function. Global variable: a variable declared in the DEFINE_VARIABLE section; its scope extends throughout the module in which it is declared.
Local Variables
Local variables are restricted in scope to the statement block in which they are declared. A statement block is one or more NetLinx statements enclosed in a pair of braces, like the blocks following subroutines, functions, conditionals, loops, waits, and so on. Local variables must be declared immediately after the opening brace of a block but before the first executable statement. To provide compatibility with the Axcess language, local variables may be declared right before the opening brace for DEFINE_CALL declarations only. For example, both formats shown below are legal in the NetLinx language:
DEFINE_CALL 'My Subroutine' (INTEGER INT1) LOCAL_VAR INTEGER INT2 { (* body of subroutine *) } DEFINE_CALL 'My Subroutine' (INTEGER INT1) { LOCAL_VAR INTEGER INT2 (* body of subroutine *) }
81
Variables
The scope of a local variable is restricted to the statement block in which it is declared. A local variable is either static or non-static, depending on whether it is declared as LOCAL_VAR or STACK_VAR:
A static variable maintains its value throughout the execution of the program, regardless of whether it is within scope of the current program instruction.
The keyword LOCAL_VAR specifies a variable that is static. A static variable's value is initialized the first time the statement block in which it is declared is executed and retained after execution of the statement block has finished. The STACK_VAR keyword specifies a variable that is non-static. A non-static variable's value is re-initialized every time the statement block in which it is declared is executed. If neither the LOCAL_VAR nor the STACK_VAR keyword is specified, LOCAL_VAR is assumed.
BUTTON_EVENT [TP,1] { PUSH: { LOCAL_VAR INTEGER INT2 STACK_VAR CHAR ARRAY1[10] // statements } // static (permanent) // non-static (temporary)
} LOCAL_VAR and STACK_VAR can be used interchangeably in any statement block except for waits. Only LOCAL_VAR variables may be declared inside a wait block.
DATA_EVENT { STRING: { LOCAL_VAR CHAR TempBuf[80] // statements } } When using the debug tool, you must use LOCAL_VAR to be "seen" in the debug display. (STACK_VARs are not displayed in debug.)
82
Variables
A name assigned to a local variable must be unique within the statement block in which it is declared and any statement block enclosing that block. Therefore, non-nested statement blocks can define the same local variable name without conflict. For example:
Define_function integer MyFunc(INTEGER nFlag) { LOCAL_VAR INTEGER n IF (nFlag > 0) { LOCAL_VAR INTEGER n . . } . . } Define_function integer MyFunc(INTEGER nFlag) { LOCAL_VAR INTEGER n IF (nFlag > 0) { . . } else { LOCAL_VAR INTEGER n// legal declaration } } // illegal declaration
Since non-static local variables are allocated on the program stack (a block of memory reserved for allocation of temporary variables), the keywords VOLATILE, PERSISTENT, and CONSTANT do not apply.
83
Variables
Global variables
Global variables are defined in the DEFINE_VARIABLE section of any program module. For example:
DEFINE_VARIABLE CONSTANT INTEGER MAXLEN = 64 CHAR STR[MAXLEN] = 'No errors were found.' INTEGER ARRAY[ ] = {100, 200, 300}
A global variable is accessible throughout the module or program in which it is defined. Global variables retain their value for as long as the program runs. They may retain their value after powering down or reloading the system depending on the variable's persistence attributes (VOLATILE and PERSISTENT).
Modules are re-usable NetLinx sub-programs that can be inserted into the main program. The main program is also a module. Refer to the NetLinx Modules section for information on program modules.
If a local variable shares the same name as a global variable, the local variable always takes precedence. The general form of a global variable definition is:
[NON_VOLATILE | VOLATILE | PERSISTENT] [CONSTANT] [<type>] name [= <value>]
84
Variables
Code Examples:
These examples illustrate non-volatile applications for presets at startup, and tracking whether or not new code has been loaded. Non-Volatile Variables that remember their value through a system power cycle but lose it on a new code download. Possible applications: Current A/V Source Selected Current TV/DSS channel selected Device States (Screen Up or Down, etc.) Example 1: DEFINE_VARIABLE NON_VOLATILE INTEGER nCUR_PRESET DEFINE_START SEND_COMMAND dvTUNER,'SET MODE IR' SEND_COMMAND dvTUNER,'CARON' SEND_COMMAND dvTUNER,"'CH',TV[nCUR_PRESET].CH"
Example 2: DEFINE_VARIABLE NON_VOLATILE INTEGER LOADED DEFINE_START IF( !LOADED ) { ON [LOADED] POLL_WAIT_TIME POLL_TIME ON [OK_2_POLL] (* ON[RACK_PWR,RACK_RELAY] *) = 5 = 5 (* SET POLL WAIT TIME *) (* ENABLE POLLING OF DEVICES *) (* REMOVED REV3 *) RELOAD OF CODE *) PROJ_ON_WAIT CROWN_PSET } = 300 = 1 (* WAIT TIME UNTIL NEXT COMMAND *) (* SET ON ONCE CODE IS LOADED *) (* IF CODE HAS NOT BEEN LOADED *)
85
Variables
86
Waits
Waits
Lesson Topics:
Naming Waits Types of Waits Nesting Waits Pausing/ Restarting Waits Canceling Waits
Wait instructions allow delayed execution of one or more program statements. When a wait statement is executed, it is added to a list of currently active wait requests and the program continues running.
All variables inside the wait are evaluated at the time the wait is executed, not when it is added to the stack.
Naming Waits
Supplying a unique name (in string literal form) to the wait statement allows the wait to be identified for purposes of canceling, pausing, or restarting the wait request. The name must not conflict with previously defined constants, variables, buffers, subroutines, or functions. Unlike other NetLinx identifiers, wait names may contain spaces.
If a wait instruction that uses a name currently in the wait list is encountered, the new wait instruction is thrown away so as not to conflict with the one currently in progress. If this feature is not desired, the current wait must be canceled before processing the new request. For information, refer to the Canceling Waits sub-section below.
Types of Waits
Types of Wait statements include: Timed Waits have an associated parameter that indicates an amount of time that must elapse before the associated wait instruction(s) are to be executed. Conditional Waits require that a specified condition be met before the instructions are executed. Timed Conditional Waits have a timeout parameter; if the condition is not met before the specified time elapses, the wait request is canceled.
87
Waits
Types of Waits
Timed waits The syntax for Timed Waits is:
88
Waits
Nesting Waits
The wait time for a nested wait is the sum of its own wait time, plus that of the enclosing waits. In the example below, SECOND WAIT occurs 0.5 seconds after FIRST WAIT is executed, or 1.5 seconds after FIRST WAIT is added to the wait list.
WAIT 10 'FIRST WAIT' { (* FIRST WAIT statements *) WAIT 5 'SECOND WAIT' { (* SECOND WAIT statements *) } }
To execute the inner wait of a nested conditional wait, the conditions must be met in the order specified (condition 1, then condition 2) but not necessarily at the same time.
WAIT_UNTIL <condition 1> 'FIRST WAIT' { (* FIRST WAIT statements *) WAIT_UNTIL <condition 2> 'SECOND WAIT' { (* SECOND WAIT statements *) } }
PAUSE_WAIT '<name>'
RESTART_WAIT RESTART_WAIT resumes the countdown for a wait suspended with PAUSE_WAIT. The wait to be restarted is identified by the parameter name.
RESTART_WAIT '<name>'
PAUSE_ALL_WAIT & RESTART_ALL_WAIT PAUSE_ALL_WAIT and RESTART_ALL_WAIT commands are used to pause or restart all scheduled waits, regardless of whether or not they are named. They have no parameters.
PAUSE_ALL_WAIT RESTART_ALL_WAIT
89
Waits
Canceling Waits
Canceling Waits
CANCEL_WAIT / CANCEL_WAIT_UNTIL CANCEL_WAIT and CANCEL_WAIT_UNTIL remove the wait specified by name from the appropriate wait list. The syntax is:
CANCEL_ALL_WAIT CANCEL_ALL_WAIT_UNTIL
90
Waits
Code Examples:
A very simple example of WAIT.
BUTTON_EVENT [TP,34] { PUSH: { IF(![VCR,PWR_FLAG]) { PULSE [VCR,PWR] WAIT 50 { PULSE [VCR,1] } } ELSE { PULSE [VCR,1] } } } This example illustrates Nested Waits-each wait uses a small independent value rather than summing all the previous values together. Example: - Nested WAIT
IF (RESET_FLAG1 AND RESET_FLAG2) { CALL 'AM8 SET GAIN'(AM8_ADDRESS,1,24) (* SET GAIN OF CHAN 1 TO 1/4 FULL *) WAIT 2 { CALL 'AM8 SET GAIN'(AM8_ADDRESS,2,24) (* SET GAIN OF CHAN 2 TO 1/4 FULL *) WAIT 2 { CALL 'AM8 SET GAIN'(AM8_ADDRESS,3,24) (* SET GAIN OF CHAN 3 TO 1/4 FULL *) WAIT 2 { CALL 'AM8 SET GAIN'(AM8_ADDRESS,4,24) (* SET GAIN OF CHAN 4 TO 1/4 FULL *) WAIT 2 { CALL 'AM8 SET GAIN'(AM8_ADDRESS,5,24)(* SET GAIN OF CHAN 5 TO 1/4 FULL *) } } } } }
//PLAY VCR //IF VCR POWER IS OFF //TURN ON VCR POWER //WAIT 5 SECONDS FOR VCR TO COME ON //PLAY THE VCR
91
Waits
92
Conditionals
Conditionals
Lesson Topics
Conditional Expressions
A conditional expression is used to tell the AMX program whether or not to execute a particular statement or group of statements. The program uses conditional expressions to judge certain conditions before continuing.
A conditional expression can have one of two results: true or false. Any non-zero value is true, while a zero value is false. When the AMX Program evaluates a conditional expression, it assigns a 1 for a true result, and a for a false result.
IF Statement
The most common conditional expression in an AMX program is the IF keyword. Every IF statement must be followed by a conditional expression enclosed in parentheses. This provides the beginning of a conditional execution of statements, as shown in this example:
If the conditional expression is true, the program executes Statement 1 and continues with whatever statements follow. If the conditional expression is false, Statement 1 is ignored. If Statement 1 is a compound statement, it must be enclosed in braces.
93
Conditionals
IF...ELSE Statement
If the conditional expression is false, the program executes a function independent of the True conditional expression.
For Example:
IF (conditonal expression) { (*Statement 1*) } ELSE { (*Statement 2*) }
If the conditional statement is true, then Statement 1 is executed and Statement 2, underneath the ELSE statement, is ignored. If the conditional statement is false, then Statement 2 is executed. Statement 1 is automatically ignored if the expression is false.
94
Conditionals
IF(CONDITIONAL1) { (* STATEMENT(S) IF CONDITIONAL1 IS TRUE *) } ELSE { IF(CONDITIONAL2) { (* STATEMENT(S) IF CONDITIONAL2 IS TRUE *) } ELSE { IF(CONDITIONAL3) { (* STATEMENT(S) IF CONDITIONAL3 IS TRUE *) } ELSE { IF(CONDITIONAL4) { (* STATEMENT(S) IF CONDITIONAL4 IS TRUE *) } ELSE { IF(CONDITIONALn) { (* STATEMENT(S) IF CONDITIONALn IS TRUE *) } ELSE { (* STATEMENT(S) IF NONE OF THE CONDITIONALS ARE TRUE *) } } } } }
95
Conditionals
A last ELSE statement can be placed at the end as a default statement. Then, if the program does not find a true IF statement, it executes the final ELSE statement. This last ELSE statement is not necessary.
If too many IF...ELSE IF statements are chained together, a run-time error could occur.
} Each one of the conditional expressions is evaluated in order, until one is found to be true. The statements associated with the true expression are then executed, and the path flows to the statements following the closing brace. Using SELECT...ACTIVE is preferable to using multiple IF...ELSE IF statements since it uses less memory, and runs faster.
When using the IF...ELSE set of statements, the code following the ELSE is the default statement. If the condition of the IF is false, then the default statement following the ELSE is executed. If none of the conditions in a SELECT...ACTIVE statement are true, no code of any ACTIVE statement will be executed, since SELECT...ACTIVE has no default statement.
96
Conditionals
The following example shows how to create your own default statement for a SELECT...ACTIVE.
SELECT { ACTIVE(CONDITION 1): { (*STATEMENT 1*) } ACTIVE(CONDITION 2): { (*STATEMENT 2*) } ACTIVE(CONDITION 3): { (*STATEMENT 3*) } ACTIVE(1): { (*DEFAULT STATEMENT*) } }
Here, the last ACTIVE will always be true, and will execute only if all of the conditions of the previous ACTIVES are false. This makes the last ACTIVE's statement the default statement.
97
Conditionals
SWITCHCASE
The SWITCHCASE statement provides a programming structure for selective execution of code blocks based on the evaluation of a single condition. The value of the SWITCH expression is tested against each CASE value (numeric constant or string literal). If a match is found, the statements associated with the CASE are executed. All other CASE statements are ignored. If no match is found, the DEFAULT case statements (if any) are executed. The SWITCH expression is evaluated only once.
SWITCH (<expression>) { CASE <numeric constant or string literal>: { (* statements for case 1 *) } CASE <numeric constant or string literal>: { (* statements for case 2 *) } CASE <numeric constant or string literal>: { (* statements for case n *) } DEFAULT: { (* statements for the default case *) } }
98
Conditionals
Regarding SWITCH...CASE statements: Only the statements associated with the first case that matches the value of the expression are executed. If no CASE matches the SWITCH expression, then the statements under the default case (if available) are executed. All cases must be unique. Braces should be used to bracket the statements in a case. They are required only if variables are to be declared within the case. The BREAK statement applies to the SWITCH. It takes execution to the end of the SWITCH. Unlike the C language, cases do not fall through to the next case if a break is not used. BREAKs are recommended between cases. The syntax is:
SWITCH (var) { CASE 1: { (*statements go here*) BREAK } CASE 3: { (*statements go here*) BREAK } CASE 5: { (*statements go here*) BREAK } DEFAULT: { (*statements go here*) BREAK } }
99
Conditionals
The conditional operators used in the AMX Control System are AND, OR, XOR, and NOT.
If the end result of the conditional expression is true, the program continues with Statement 1. If the end result is false, the program ignores Statement 1.
FIG. 1 Pictorial explanation of the Boolean expression table for the operator AND.
Boolean Expressions / Operators and Conditional Expressions / Operators are one in the same.
The following text formula can also be followed to find that result:
If <STATEMENT 1> is <its condition (true or false)> <Boolean operator> <STATEMENT 2> is <its condition>, then the result of the expression is <result of statement conditions>.
The result is found by basing the conditions of the statements against specific rules set by the Boolean operator:
AND Both statements must be true for the result to be true. OR At least one of the conditions must be true for the result to be true. XOR Only one statement can be true for the result to be true. NOT If the statement is true, the result is false. On the contrary, if the condition is false, the result is true. This expression uses only one statement.
For example, assume that it has been previously defined that NUM1 = 5 and NUM2 = 3. Insert the variables from the example into the text formula:
If NUM1 = 5 is true and NUM2 = 4 is false, then the result of the expression is false.
100
Conditionals
The statement would have been true if NUM2 had been equal to 3, because in an AND expression both statements must be true as shown in FIG. 2.
FIG. 2 An example of how a Boolean expression table is used to compare multiple conditions.
The Boolean expression tables in FIG. 3 are a quick reference guide for the result of a conditional expression.
101
Conditionals
Code Examples:
If(a = 1) { DO DOMETHING AND SKIP THE RESTOTHERWISE } Else If(a = 2) { DO SOMETHING ELSE } Else { DO THIS IF THE OTHER CONDITIONS ARE NOT TRUE } Select { Active(a = 1): { Just like the IF above } Active(a = 2): { Just like the IF ELSE above } Active(1): { Just like the Else Above } } //Check this if the first condition is false, and if this is true // If this is true
102
System Calls
System Calls
Lesson Topics:
Resource Documents Instancing of SYSTEM_CALLS Button Parameters Time Outs FIRST Parameter
SYSTEM_CALLs are used to simplify programming by using known proven blocks of code. They provide access to pre-developed programming solutions and tools without rewriting. AMX has written a number of SYSTEM_CALLs to handle many of the most common programming requirements in AMX Control Systems. These SYSTEM_CALLs are divided into several categories including VCRs, switchers, video projectors, and others. SYSTEM_CALLs follow a standard naming convention, and the SYSTEM_CALLs in each group take the same parameters.
*ALL VCR calls follow this convention: <SYS CALL> (DECK,PANEL,PLAYB,STOPB,PAUSEB,FFWDB,REWB,SFWDB,SREVB,RECB,FIRST)
The purpose of SYSTEM_CALLs is to maintain a consistent look and feel for the control panels, regardless of how the deck behaves from its own remote control. For example, when some VCRs are in the pause mode, pressing Pause again will cause the deck to play, whereas on other VCRs, pressing Pause again does nothing. However, when using a VCR SYSTEM_CALL, pressing Pause on the control panel while the deck is in pause mode will always cause the deck to play. This is because the different VCR SYSTEM_CALLs were written to take into account the behaviors of different VCRs. Therefore, no matter what type or model of equipment is being used, the behavior of the buttons on the control panel will not change.
VCR2 - does not have discrete searches sends PLAY (or REC) to exit pause VCR2_REW_TO_STOP = 1800 (3 min) VCR2_SREV_TO_STOP = 12000 (20 min) VCR2_PAUSE_TO_STOP = 6000 (10 min) VCR2_PULSE_DELAY = 3 (0.3 sec) VCR2_DEFEAT_FEEDBACK = OFF
103
System Calls
Resource Documents
AMX has pre-written SYSTEM_CALLS to handle common programming requirements stored in a shared directory. These files are installed during the installation of the Control Disc. The text files to view the descriptions of these SYSTEM_CALLS are: Newcalls.DOC Camcalls.TXT All SYSTEM_CALLS are also available in the Inconcert section of amx.com. See Axcess or NetLinx Keyword Help for usage details.
These files have the DOS extension .LIB (library file) Must contain a DEFINE_CALL subroutine with same PROGRAM_NAME on the first line
Newcalls.txt Camcalls.txt
104
System Calls
Instancing of SYSTEM_CALLS
A SYSTEM_CALL can be referenced more than one time in a program. For example, in a system with multiple projectors of the same model a programmer might use the same SYSTEM_CALL to control each projector. To avoid conflicts between Variables as WAITs in the SYSTEM_CALLs, the multiple references must be uniquely identified.
In this example, make a new library file that has WAIT statements in its subroutine. Here is a listing:
DEFINE_CALL 'SEND' (CARD,STR1[1],STR2[1]) { SEND_STRING CARD, STR1 WAIT 2 'SS WAIT' SEND_STRING CARD, STR2 }
This subroutine takes three parameters. The purpose of the subroutine is to send the two strings to the device specified in the parameter variable CARD, with a delay of 2 seconds between sends.
The following line will send the string 'AMX', followed 2 seconds later by the string 'Axcess' to SWT, defined as card 3:
SYSTEM_CALL 'SEND' (SWT1,'AMX','Axcess')
This code compiles and works fine. The following code and related paragraphs describe the effect of adding another SYSTEM_CALL to the program:
SYSTEM_CALL 'SEND' (SWT1,'AMX','Axcess') SYSTEM_CALL 'SEND' (SWT2,'GOOD','TIMES')
The string 'Axcess' is never sent to card SWT1. This is because the STR2 parameter variable in the subroutine is overwritten by the second SYSTEM_CALL before the WAIT comes due. This is the problem with using WAITS in SYSTEM_CALL subroutines. The solution is to use an instance number to force the compiler to compile two separate copies of the subroutine. Here is an example of the same SYSTEM_CALLs using instance numbers:
SYSTEM_CALL [1] 'SEND' (SWT1,'AMX','Axcess') SYSTEM_CALL [2] 'SEND' (SWT2,'GOOD','TIMES')
The number in the brackets is the instance number. The instance number tells the compiler to compile multiple copies of the routine, and have the different SYSTEM_CALLs each call a separate copy. The compiler does this by using the instance number to modify the actual name of the DEFINE_CALL before compiling it. When compiling a library file called with an instance number, the program converts the number to ASCII and appends it to the DEFINE_CALL name, as shown in FIG. 1 on the next page.
105
System Calls
Main Program
SYSTEM_CALL [1] 'SEND' (SWT1, 'AMX', 'AXCESS')
Library File
DEFINE_CALL 'SEND1'
FIG. 1 How the DEFINE_CALL name in the library file is modified using the instance number
The process of converting the instance number to ASCII and appending it to the DEFINE_CALL name is called name mangling. When an instance number is used in a SYSTEM_CALL, the program mangles the names of the DEFINE_CALL and any WAITs, WAIT_UNTILS, and variables inside the subroutine. When the SYSTEM_CALL subroutine SEND is called with an instance number of 1, a call to SEND1 is generated. Then it compiles the library file, adding a 1 to the end of the DEFINE_CALL name and the WAIT name. For example, if a SYSTEM_CALL were made with the instance number equal to 1, the DEFINE_CALL would be named 'SEND1', and the WAIT would be named 'SS WAIT1'.
All SYSTEM_CALLS using the same instance number call the same copy of the library file. For example:
SYSTEM_CALL [1] 'SEND' (SWT1,'HOW','FEE') SYSTEM_CALL [2] 'SEND' (SWT2,'DO','FI') SYSTEM_CALL [2] 'SEND' (SWT2,'YOU','FO') \ SYSTEM_CALL [3] 'SEND' (SWT3,'DO','FUM') //calls copy 1 //calls copy 2 //calls copy 2 //calls copy 3
For example, if there is a DEFINE_CALL SEND1 in your program, and you attempt the following line of code:
SYSTEM_CALL [1] 'SEND' (SWT1,'LETS','GO')
After name mangling, this generates a call to SEND1, which will actually call the subroutine SEND1 in the program file, not the library file. In fact, since the call to SEND1 is resolved (that is, a subroutine SEND1 was found) the library file is never compiled. However, if the instance number was 2, the SEND1 subroutine would not be called, and the SEND library file would be compiled with the names mangled using the character 2.
106
System Calls
Button Parameters
For all of the button parameters (parameters ending with a B, such as PLAYB) simply pass the button number of the panel that should activate that function. If a particular button does not exist, pass a 0 in its place. For example, a VCR may be controlled by only five buttons. If the FFWD button is pressed, the call will see if there is a SFWD button. If there is, then the deck will send the FFWD command. If there is not a SFWD button, the call will see if it is in PLAY or not to determine if it should send the FFWD or the SFWD command. All decks with transport controls will work similarly. The SLD calls work like this too; pass a 0 for POFFB if a single power button exists, and a 0 in FOUTB if only one alternating focus button exists.
Time Outs
Several transport system calls have built-in timeouts (VCR1_PAUSE_TO_STOP, etc.) that stop the deck in various conditions. If you do not want the deck to timeout and stop, then override the default and set the timeout value to 0. The maximum value for any timeout is 65535 or about 109 minutes.
Example of a timeout: Cassette decks controlled by system call CAS1 to go to a stop condition after pausing for 10 minutes, and this is not desired in a particular application. In the actual system call is the following statement: CAS1_PAUSE_TO_STOP=6000
(*Note* 10 minutes = 6000 for AMX programming purposes, as 1/10 second = 1). The following needs to be defined in the DEFINE_CONSTANT area of the program which is being written: CAS1_PAUSE_TO_STOP=0
FIRST Parameter
The FIRST parameter is used as an offset for transport calls. For example, if PLAY is located in position 4 instead of position 1, then pass 4 in the FIRST position. If no offset is needed, pass 0. Even if PLAY is in a different position, the order of the functions must be maintained (STOP=5, PAUSE=6, FFWD=7, etc.) for the calls to work. If the feedback channels need to be moved, then pass the desired first channel in the high byte of FIRST. If PLAY_FB is not needed at 241 but at 109, then pass 109*$100 in the FIRST position. The multiplication by $100 shifts the offset into the high byte. Example: Say you are using an IR controlled receiver that has controls for both a CD player and a cassette deck. The CD controls are in the standard positions, but the cassette controls begin at position 43. The following two lines of AMX code could be used in this situation:
SYSTEM_CALL 'CDP2' (RECEIVER,TP,11,12,13,14,15,16,17,0) //CD SYSTEM_CALL 'CAS3' (RECEIVER,TP,21,22,23,24,25,0,231*$100+43) //CAS
107
System Calls
The CD call works normally; the 0 in the FIRST position does not change any defaults (actually, sending 241*$100+1 in the FIRST position achieves the same thing). The CAS call changes the offsets so PLAY is in the correct position (in this case 43) and moves the feedback to start at channel 231. This will let the status of both devices to be kept on the same card! This system call feature will work on every other control card/device AMX makes.
For screen calls, the FIRST parameter controls the screen run time. If you need the screen to run for 10 seconds, set the FIRST parameter to 10. (NOTE: this parameter is interpreted as seconds, not 1/ 10's of a second). You can specify different UP and DOWN times by setting the low byte of FIRST to the down time and the high byte of FIRST to the up time. For example, say you have a screen which needs the relay held for 10 seconds to travel down fully and 15 seconds for the screen to travel up fully. You would specify the FIRST parameter to the screen call as: 15*$100+10.
If the FIRST parameter is 0, the default time is 1/2 second, a standard PULSE time.
SYSTEM_CALL Subroutines
A SYSTEM_CALL subroutine is a special type of DEFINE_CALL subroutine that is defined in a separate program file called a LIB file with a PROGRAM_NAME entry matching the subroutine name.
PROGRAM_NAME = 'COSX' DEFINE_CALL 'COSX' (FLOAT X) { //body of subroutine }
To invoke a system call, use the SYSTEM_CALL keyword followed by the name in single quotes and any calling parameters, as shown below:
SYSTEM_CALL 'COSX' (45)
System calls are resolved automatically at compile time without requiring an INCLUDE instruction to include the system call source file.
For special cases where multiple copies of a system call are needed, an instance number can be specified in the call. The compiler will compile a separate copy of the subroutine for each system call instance number. For example, the following commands force the compiler to include two separate copies of COSX:
SYSTEM_CALL[1] 'COSX' (45) SYSTEM_CALL[2] 'COSX' (60)
This technique could be useful in cases where a system call contains a wait instruction that would cause a conflict when multiple calls to the same subroutine were made during a single wait period.
108
System Calls
Function Subroutines
A function is similar to a DEFINE_CALL, but is intended for use either standalone or in-line as an expression. Instead of requiring a string literal for its name, it requires a name that follows the rules for naming constants and variables. This eliminates the need for using the CALL keyword to invoke the subroutine. DEFINE_FUNCTION subroutines also differ from DEFINE_CALL by allowing values to be returned using the RETURN statement (see below).
The return type may only be one of the 8 intrinsic types (see Data Types). Strings, arrays, structures, classes, and other user-defined types may not be returned.
In syntax with a ([ ]), the ( ) are NOT OPTIONAL but [ ] are optional.
109
System Calls
The DEFINE_FUNCTION subroutine can be called as a single programming statement. For example, the following syntax:
ReadBuffer(Buffer,BufSize)
The rules pertaining to calling parameters are the same for DEFINE_FUNCTION as they are for DEFINE_CALL subroutines. The parameter list must appear in parentheses to the right of the function name. If the function has no calling parameters a set of parentheses must still be included. For example:
MyFunc() // calling a function with no parameters
The return type may be omitted, as an alternate way of defining a subroutine. In this case the function cannot be used as part of an expression or in an assignment statement.
DEFINE_FUNCTION also allows the use of the RETURN keyword that serves two purposes:
If a return statement is encountered anywhere in the function, execution of the function is terminated immediately and the value (if any) specified as the <return value> is returned to the caller.
A function that returns a value through the RETURN keyword must be declared with a return type. Conversely, a function that is declared without a return type cannot return a value.
The return type may only be one of the 8 intrinsic types (see Data Types). Structures and other user-defined types may not be returned.
110
System Calls
In the example below, GetBufferSize returns an unsigned 16-bit integer, BufSize. The return type is indicated before the DEFINE_FUNCTION keyword.
DEFINE_FUNCTION INTEGER GetBufferSize() { LOCAL_VAR INTEGER BufSize = 0; RETURN BufSize; }
To call this function and to retrieve the RETURN value, use the following syntax:
BufSize = GetBufferSize()
Even if a function returns a value, it is not necessary to assign the return value to a variable. Both forms of the following call are valid. In the second case, the return value is simply thrown away.
Count = ReadBuffer(Buffer,BufSize) ReadBuffer(Buffer,BufSize) // return value is ignored
Calling Parameters
Parameters may be passed to any NetLinx function or subroutine. Calling parameters are simply variables or constants that originate from the caller and are received by the function or subroutine being invoked.
The NetLinx compiler passes all variables by reference. This means that the variable the subroutine operates on is the same variable the caller passed. Any change made to a variable passed as a calling parameter updates the value of the variable from the perspective of the caller. You can take advantage of this pass by reference feature to return an updated value through a calling parameter rather than as the return value.
Constants, on the other hand, are passed by value. When this happens, a copy of the parameter is delivered to the subroutine. Any change made to the variable representing the constant is lost once the function or subroutine finishes.
Function and subroutine declarations must include the type and name of each parameter expected. If the type is omitted, the default type is assumed - arrays are CHAR type and non-array parameters are INTEGER.
To specify an array as a function or subroutine parameter, one set of brackets for each array dimension must follow the variable name, as shown in the following example:
DEFINE_CALL 'Process Array' (CHAR Array[ ][ ]) { //body of subroutine }
111
System Calls
The parameter Array is declared to be a 2-dimensional array by including two sets of brackets after the name. For compatibility with existing programs, the array dimensions may be specified inside the brackets. These dimensions are not required and are ignored by the compiler. The NetLinx interpreter will do bounds checking on the array and generate a run-time error if the array bounds are exceeded.
When calling a subroutine that takes an array as one of its parameters, pass only the name of the array as the calling parameter, as shown below:
CHAR Buffer[10][20] CALL 'Process Array' (Array)
If dimensions are specified in the call statement, the compiler will interpret that as specifying a subset of the array. For example, suppose Array were defined as a 3-dimensional array. The third table of that dimensional array could be passed to 'Process Array' as follows:
CHAR Buffer[5][5][10] CALL 'Process Array' (Array [3])
112
Subroutines
Subroutines
Lesson Topics:
Subroutines Defined
A subroutine is a section of code that stands alone, and can be called from anywhere else in the program. The subroutine name follows the DEFINE_CALL or DEFINE_FUNCTION keyword, enclosed in single quotes. There are certain restrictions for subroutine names: They cannot be previously defined constants or variables. They cannot be names that have already been assigned to BUFFERs or WAITs. They are case-sensitive; Test and TEST are not the same. Subroutines must be defined before they can be used. For this reason, DEFINE_CALLs and DEFINE_FUNCTIONs are usually found right before the DEFINE_START section of the program. For example:
DEFINE_VARIABLE LIGHT_PRESET { PULSE[CARD,PRESET] LIGHT_PRESET = PRESET } DEFINE_START CALL 'PRESET LIGHTS' (LIGHTS,LIGHT_FULL) DEFINE_EVENT BUTTON_EVENT[TP,7] { PUSH: CALL 'PRESET LIGHTS' (LIGHTS,LIGHT_OFF) } DEFINE_PROGRAM [TP,7] = (LIGHT_PRESET = LIGHT_OFF) // LIGHTS OFF // CURRENT LIGHTING PRESET DEFINE_CALL 'PRESET LIGHTS' (CARD,PRESET)
Spaces in the subroutine name are allowed, since it is a string literal. The subroutine's code must be enclosed in braces. Regardless of how long the subroutine is, it must be in this format.
113
Subroutines
DEFINE_CALL
DEFINE_CALL is intended to run segments of code that are repeated throughout the program, but don't require a return value. For example, this DEFINE_CALL creates a macro to lower a screen, turn on the projector, and set the lights to Preset 1. The subroutine executes three commands and no values are returned to the program.
DEFINE_CALL 'PRESENTATION MACRO' { SYSTEM_CALL [1] 'SCREEN1' (0, 0, 1, 0, SCREEN, 1, 2, 3, 0) SEND_STRING VPROJ, "'PON',$0D,$0A" SEND_STRING RADIA, "'1B',$0D" }
The DEFINE_CALL is the standard method provided by NetLinx for defining subroutines.
DEFINE_CALL '<subroutine name>' [(Param1,Param2,...)] { (* statements *) }
where (Param1, Param2, ...) refers to a comma-separated list of <datatype><variable> pairs. For example, "INTEGER Size" would be one pair.
DEFINE_CALL names must not conflict with previously defined constants, variables, buffers, or wait names. Unlike identifiers, DEFINE_CALL names are case sensitive.
A subroutine may accept parameters. To do this, each parameter and its type must be listed within the set of parentheses to the right of the subroutine name, as shown below:
DEFINE_CALL 'Read Input' [(CHAR Buffer)] { }
To invoke a user-defined subroutine, use the CALL keyword plus the name of subroutine and any required calling parameters.
CALL 'Read Input' (Buf1)
In NetLinx, DEFINE_CALL supports the RETURN statement (as shown in the following example), although return values are not supported.
DEFINE_CALL 'Read Input' (CHAR Buffer) { if (nChars = 0) { RETURN } (* read input *) } // exit subroutine
114
Subroutines
DEFINE_FUNCTION
DEFINE_FUNCTION provides a way to return a value to a statement. It has the same functionality as a DEFINE_CALL. The DEFINE_FUNCTION is used in-line in a statement, where a DEFINE_CALL must be used as a standalone statement. The basic structure is:
DEFINE_FUNCTION [<return type>]<name>[(<param1>,<param2>, <parameN>)] { (* } statements *)
In syntax with a ([ ]), the ( ) are NOT OPTIONAL but [ ] are optional.
The following DEFINE_FUNCTION creates a subroutine to cube a number and returns a LONG integer value:
DEFINE_FUNCTION LONG CUBEIT (LONG VALUE) { STACK_VAR RESULT RESULT = VALUE * VALUE * VALUE RETURN RESULT } DEFINE_EVENT BUTTON_EVENT [TP,1] { PUSH: { CUBED_VAL = CUBEIT (3) } }
115
Subroutines
Code Examples:
DEFINE_CALL Example DEFINE_CALL 'SHUTDOWN' { PULSE[SCREEN,UP] PULSE[PROJ,OFF] SYSTEM_CALL 'FUNCTION' (VCR,2,0) SYSTEM_CALL 'FUNCTION' (DVD,2,0) SYSTEM_CALL 'FUNCTION' (CD,2,0) WAIT 600 'EXIT TIME' { PULSE[LIGHTS,ALL_OFF] } } In the main program, it looks like this: IF(TIME='02:00:00') CALL 'SHUTDOWN' BUTTON_EVENT[TP,125] CALL 'SHUTDOWN' This example shows application of subroutines, including parameters. Subroutines
DEFINE_CALL 'SET_GAIN'(CHAN,LEV) { IF (LEV < 65) { LEV = 65-LEV SEND_STRING MIXER,"'#40 GAIN ',ITOA(CHAN),' O -',ITOA(LEV),' A',$0D,$0A" } ELSE { LEV = LEV - 65 SEND_STRING MIXER,"'#40 GAIN ',ITOA(CHAN),' O ',ITOA(LEV),' A',$0D,$0A" } }
116
Subroutines
This example is a good application of several elements for a real world system. DEFINE_CALL 'DEVICE_SELECTION'(SELECTED_INPUT[1],strPROJ_IN[5]) { IF ((! nPROJ_PWR) AND (! nJUST_TURNED_OFF)) //PWR ON PROJ IF OFF { SEND_STRING dvPROJ,"$02,'PON',$03" nPROJ_PWR = 1 nJUST_TURNED_ON = 1 WAIT 600 { nJUST_TURNED_ON = 0 } IF ([dvPROJ,DEBUG]) SEND_STRING 0,"$02,'PON',$03" } SEND_STRING dvPROCESSOR,SELECTED_INPUT IF ([dvPROCESSOR,DEBUG]) SEND_STRING 0,SELECTED_INPUT //SELECT INPUT ON SUNFIRE IF (nSCRN_STATE <> 2) { PULSE [dvSCREEN,2] nSCRN_STATE = 2 } IF (! nJUST_TURNED_ON) { SEND_STRING dvPROJ,"$02,'IIS:',strPROJ_IN,$03" IF ([dvPROJ,DEBUG]) SEND_STRING 0,"$02,'IIS:',strPROJ_IN,$03" } ELSE } WAIT 600 { SEND_STRING dvPROJ,"$02,'IIS:',strPROJ_IN,$03" IF ([dvPROJ,DEBUG]) SEND_STRING 0,"$02,'IIS:',strPROJ_IN,$03" } } } //WAIT A MINUTE FOR PROJ TO WARM UP //DO IF PROJ HAS BEEN ON AWHILE //LOWER SCREEN //DO IF SCREEN NOT ALREADY DOWN //SELECT INPUT ON SUNFIRE //POWER FLAG //USED TO TRACK WARM UP STATE //1 MINUTE
117
Subroutines
DEFINE_FUNCTION
DEFINE_FUNCTION returns a value unlike DEFINE_CALL. Also illustrated is the shorcut X++. DEFINE_VARIABLE Volatile X (* DEFINE SUBROUTINE SECTION *) DEFINE_FUNCTION CHAR CalcTotalReps() { nTotalReps = 0 FOR (X=1;X <= uBoardInfo.nNumOfAgencies; X++) { nTotalReps = nTotalReps + uAgencyInfo[X].nNumberOfReps } uBoardInfo.nNumOfMembers = nTotalReps } //Save total reps into structure //X++ is shortcut for X=X+1
118
Modules
Modules
Lesson Topics
Modules are a method for reusing code in a NetLinx system. Modules provide some of the same functionality as System Calls and Include Files, but modules are unique in a number of ways.
Like Include files, modules can define their own variables, subroutines, events and mainline. But modules are self-contained and the variables and subroutines defined within the module cannot be accessed by the main program.
Modules can interact with the program in a number of different ways. Modules have parameters that can be used to pass information into and out of the module. Modules can also pass channels, events, strings and commands between the module and the main program.
Most times the functionality of the module is transparent to the program. In the DMS-IMS module, the device number of the keypad and a virtual device for a virtual keypad are passed to the module. In the program, all events and commands are programmed for the virtual keypad. The module handles all of the interaction with the actual keypad device.
Modules can be used to provide a standard interface to a variety of similar devices. Within the program, the devices are programmed using the same channels and SEND_COMMANDs. The different modules handle the channels and SEND_COMMANDs, and control the devices according to their own protocols.
The ability to reuse code is a desirable goal in software development; however, code reuse takes careful planning and organization. NetLinx provides tools such as functions and modules to promote reusability. Modules are NetLinx sub-programs designed to be "plugged into" a main program.
119
Modules
Defining a Module
The MODULE_NAME entry on the first line of the file defines the module. The syntax is:
MODULE_NAME = '<module name>' [(<parameter list>)]
The MODULE_NAME entry identifies the file as containing a NetLinx module, as opposed to a standard NetLinx source code file. The module name is any valid string literal not to exceed 64 characters. A file can contain only one module and the file name must be the same as the module name with the addition of the ".AXS" extension.
Module parameters behave exactly like subroutine parameters; the parameter list is optional. The value for each parameter is set either by the main program or another module. If the value of a parameter is changed, both the main program and the module see the change.
All parameters to a module must be one of the intrinsic types: CHAR, INTEGER, SINTEGER, LONG, SLONG, FLOAT, DOUBLE, DEV, DEVCHAN or DEVLEV. Also, any array of any of the above types can be used.
Modules can contain declarations to other modules, provided that no circular references are involved (if module A declares module B that contains a reference to another module with a reference to A, that is a circular reference.) However, because different instances of the same module must not be separated by instances of a different module, it is highly recommended that you do not declare modules from within other modules - if you have multiple declarations of the parent module they will then be separated by the declarations of the child module.
Like System Calls, each module is going to have a list of its own parameters. The modules parameters must be either defined as devices or as variables. You cannot hard code values into the parameters or pass constants.
Modules are defined between the DEFINE_START section and the DEFINE_EVENT section. Do not place DEFINE_START statements after the DEFINE_MODULE statements.
120
Modules
Modules can be distributed as .AXS files or as compiled token files. In either case, compiling your program will incorporate the module into your program. Modules should be documented to tell what parameters need to be defined, what values need to be passed and how any devices or virtual devices need to be programmed in the main program.
FIG. 1 demonstrates how a NetLinx module is incorporated into a main program. In this example, the main program has no event table or mainline code.
121
Modules
122
Levels
Levels
Lesson Topics:
Introduction to Levels
Devices such as volume control cards, voltage generator cards, and pan/tilt control cards use levels to interface with the outside world. Levels are values related to an analog input or output on an AMX device. Several AMX panels (FIG. 1) have bargraph displays capable of displaying a level.
Levels are used: To represent the current gain on a volume device To represent the output or input level of a voltage device To represent the current position or location of a Camera system (Pan/Tilt/Zoom/Focus) An input/output (I/O) channel is usually digital in nature; that is, it is always either in an ON or OFF state. However, several devices, such as the volume control card and the pan/tilt control card, have analog input and/or output capabilities. An analog input or output may have many different states. Devices using analog I/O internally store the values relating to the state of each of these analog inputs and outputs; these values are called levels. On a volume card, levels relate to the volume levels of the card. Levels can be used to tell a pan/tilt control card where to position a camera, or tell a voltage generator card the amount of voltage to generate.
123
Levels
For conceptual purposes, imagine that a volume control card has two volume knobs: one for the left speaker and one for the right, as shown in FIG. 2 on the next page. Each knob has a value range from to 255. These knobs represent the two levels present in the volume control card. When a level is discussed in the text, it is usually referring to the value of one of these imaginary knobs.
Level Values 80 135
Level 1
255
Level 2
255
FIG. 2 The imaginary knobs. The knob is the level, which can have a range of values.
Level Keywords
Level keywords that you can use in an AMX program for volume control or lighting control are described below: Level Keywords
CREATE_LEVEL Reads a level from an AMX device that supports levels. Syntax:
Level Keywords
124
Levels
DEFINE_CONNECT_LEVE L
All level connections are listed underneath the DEFINE_CONNECT_LEVEL header. Syntax:
125
Levels
Creating Levels
Most AMX devices have up to eight levels which can contain values from to 255.
A few devices have level ranges larger than to 255, but the programming principles and examples in this section still apply.
Level values can be stored in a variable for later use. To read a level from an AMX device that supports levels, use the keyword CREATE_LEVEL. Here is the syntax:
CREATE_LEVEL requires 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. Your program will continually update the variable to contain the value of the level with which it is associated during its execution. Since this association only needs to occur once, this keyword is only allowed to appear in the DEFINE_START section of your program.
Using LEVEL_EVENTS bypasses the CREATE_LEVEL process.
126
Levels
Using Levels
Reading Levels
When a level is associated with a variable using CREATE_LEVEL, the Master continually keeps the variable updated with the value of that level. As the user ramps the volume level up, the value in VOL_LEVEL increases. When the volume is ramped up to the maximum, VOL_LEVEL will contain 255, and when the volume is muted, the variable will contain . AXlink devices have up to 8 levels per device, and their values typically range from 0 to 255 (8 bit resolution) Some Input levels range from 0 to 1024 (10 bit resolution) NetLinx devices can have more levels and greater data ranges A Preset is a level saved for later retrieval. When presets are recalled, the level returns to the preset value. Presets are generally recalled using a SEND_COMMAND. Making a Preset An example would be giving a Volume Preset button a dual role.
DEFINE_EVENT BUTTON_EVENT[TP,20] { PUSH: { OFF[VOLUME,VOL_MUTE] WAIT 20 STORE VOL PRESET VOL_PRESET = VOL_LEVEL } RELEASE: { CANCEL_WAIT STORE VOL PRESET SEND_COMMAND VOLUME,P0L,ITOA(VOL_PRESET) } } } // VOLUME PRESET // VOLUME PRESET
Result of this program: If the button is pressed for less than two seconds, it sends a command to the volume card. The SEND_COMMAND sets the level of the card to the previously saved level in VOL_PRESET. If the button is held two seconds, the current level is stored in the VOL_PRESET variable.
127
Levels
Using Bargraphs
The SEND_LEVEL keyword is used to update a level in a device. To continuously display the current level of the volume card on the Touch Panel's bargraph, use the SEND_LEVEL keyword. Here is the syntax:
SEND_LEVEL device, level number, value
Assume your bargraph display on the Touch Panel has level number 1. To keep the display updated continually, add the following line to a LEVEL_EVENT in a NetLinx program:
SEND_LEVEL TP, 1, VOL_LEVEL
This code makes sure that the bargraph always reflects the value of level number 1 of the volume card. As the volume ramps up, VOL_LEVEL increases and the bargraph fills. As the volume ramps down, VOL_LEVEL decreases and the level indicated on the bargraph also decreases. Since both volume levels are ramping together, you only have to track one of them for the bargraph.
DEFINE_CONNECT_LEVEL
A unique feature of Touch Panels is to assign an active property to a bargraph so you can touch and slide it to raise or lower the level. The level tracks the movement of your finger. However, to do this you must set up a connection between the bargraph and the volume level. This is the function of the DEFINE_CONNECT_LEVEL keyword.
DEFINE_CONNECT_LEVEL is not a keyword used inside mainline, but a definition section, like DEFINE_DEVICE or DEFINE_START. The best location to place it is immediately following the DEFINE_VARIABLE section. Underneath the DEFINE_CONNECT_LEVEL header is where all level connections are listed. Here is how DEFINE_CONNECT_LEVEL is used: Example:
DEFINE_CONNECT_LEVEL
(virtual device, vitual level,device 1,level number 1,device 2,level number 2,...etc.)
COMBINE_LEVEL and UNCOMBINE_LEVEL work similarly and will be covered in more detail in AMX Programmer II.
128
Levels
The section inside the parentheses represents a single connection. All levels listed in the connection will follow each other. If any one level changes, all others in the connection will change to match. Any number of levels may be supported per connection, and there is no limit to the number of connections.
Here is how you would use DEFINE_CONNECT_LEVEL in a program to connect the Touch Panel bargraph to the Axcess volume card levels:
DEFINE_CONNECT_LEVEL (TP, 1, VOLUME, 1, VOLUME, 2)
This connects level number 1 on the Touch Panel (the bargraph) and levels 1 and 2 on the volume card. The reason that two levels on the volume card are included is because Axcess volume control cards have two levels: the left audio channel and the right audio channel. These connections are a two-way street: anytime the bargraph is changed, both volume levels will follow, and anytime a volume level is changed (for example, by the volume control buttons on the Touch Panel), the bargraph will automatically follow. When using DEFINE_CONNECT_LEVEL, it is not necessary to use the SEND_LEVEL keyword in your program, since the connection takes care of updating the bargraph.
LEVEL_EVENTs
This keyword defines a LEVEL_EVENT handler. This type of handler is triggered by a level change on a particular device. It can only be used in the DEFINE_EVENT section of the program. The level object is available to the LEVEL_EVENT handler as a local variable. This eliminates having to constantly evaluate a level against a previous value. The format for the LEVEL_EVENT is as follows:
LEVEL_EVENT[<device>,<level>] { //LEVEL_EVENT handler }
What information might be associated with the level of volume device changing? The value of the volume level The device, port, and system of the volume device that had its level changed Which level on the device changed
Please see the Appendix - Embedded Event Data Objects on page 223 for more information on LEVEL_EVENTS.
129
Levels
NetLinx LEVEL_EVENT:
LEVEL_EVENT [ AC, 1 ] { IF (LEVEL.VALUE>= COOL_POINT) { ON[RELAY,FAN] } ELSE IF (LEVEL.VALUE <= HEAT_POINT) { OFF[RELAY,FAN] } }
LEVEL.VALUE is an embedded object value in the LEVEL_EVENT statement. A complete listing of these objects is available for each event handler in the NetLinx Programming Language Instruction Manual. The LEVEL.VALUE object eliminates the need to create a level for the TEMP device.
130
Levels
Code Examples:
DEFINE_DEVICE VOL TP vVOL = = = 16:1:0 128:1:0 33001:1:0 //AXC-VOL CARD IN AXCENT 3 PRO //AXT-MCA //VIRTUAL VOLUME DEVICE
DEFINE_CONSTANT LEFT_VOL_MUTE DEFINE_VARIABLE INTEGER PRESET[2] INTEGER VOL_LEVEL DEFINE_CONNECT_LEVEL (vVol,1,VOL,1,TP,1) DEFINE_START CREATE_LEVEL VOL,VOL_LEVEL BUTTON_EVENT[TP,34] { PUSH: { OFF[VOL,LEFT_VOL_MUTE] } RELEASE: { SEND_COMMAND VOL,P1L,ITOA(PRESET[1]) } HOLD[20]: { PRESET[1] = VOL_LEVEL // STORES CURRENT LEVEL IN PRESET SEND_COMMAND TP,ADBEEP // ELEMENT ONE AND DOUBLE BEEPS PANEL } } DEFINE_PROGRAM [TP,34] = (PRESET[1] =VOL_LEVEL // IF BUTTON HELD FOR 2 SECONDS // ASSOCIATES VOL BOX LEVEL WITH VARIABLE // PRESET SELECT BUTTON // STORAGE SPACE FOR 2 PRESET VOLUMES // VARILABLE TO TRACK THE VOL BOX LEVEL = 3
131
Levels
Preset Example: DEFINE_VARIABLE VOL_LEVEL PRESET[2] BUTTON_EVENT[TP,29] BUTTON_EVENT[TP,30] { PUSH: { OFF[VOL,3] } RELEASE: { SEND_COMMAND VOL,"'P0L',ITOA(PRESET[BUTTON.INPUT.CHANNEL - 28])" } HOLD[5,REPEAT]: { SEND_COMMAND TP,'ADBEEP' PRESET[BUTTON.INPUT.CHANNEL - 28] = VOL_LEVEL } }
This example illustrates CREATE_LEVEL, SEND_LEVEL, subroutine (CALL), and toggle shortcut (x=!x) Volume Levels DEFINE_VARIABLE Volatile CHAN_LEVEL[9] Volatile OLD_CHAN_LVL[9] DEFINE_EVENT BUTTON_EVENT[MSP8,11] { PUSH: { CH_MUTE[4] = ! CH_MUTE[4] IF (CH_MUTE[4]) { OLD_CHAN_LVL[4] = CHAN_LEVEL[4] CALL 'AM8 SET GAIN' (AM8_ADDRESS,4,31) SEND_LEVEL MSP8,1,0 } ELSE { // SET CHANNEL 4 BACK TO ORGINAL LVL CALL 'AM8 SET GAIN' (AM8_ADDRESS,4,OLD_CHAN_LVL[4]) SEND_LEVEL MSP8,1,(255-(OLD_CHAN_LVL[4] * 8)) // SENDS BARGRAPH TO ORGINAL LVL } } } // SAVE CURRENT LEVEL // MUTE CHANNEL 4 // SENDS BARGRAPH TO 0 // HOLDS VOL LVL FOR EACH INPUT CHAN AND MAIN OUT *) // HOLDS OLD VOL LEVEL OF EACH CHANNEL AND MAIN OUT *)
132
SEND_COMMAND / SEND_STRING Arrays Arrays As Strings String Literals String Expressions ASCII Codes DATA_EVENT/ DATA.TEXT Buffers Buffer Keywords Array & String Manipulation Keywords
SEND_COMMAND / SEND_STRING
Two main keywords will be used extensively with arrays and strings. The primary difference between them is the intended destination device. SEND_COMMAND
SEND_STRING
Passes a command string through the AMX device to an external piece of equipment.
SEND_STRING device, 'string'
Arrays
Arrays are the most common way of combining a number of data items into a single unit. An array is a collection of variables that are of the same data type, and are referenced by the same Identifier. Each item in an array is called an Element. All Elements in the array are referenced by the name of the array and by an index number corresponding to their position in the array. NetLinx enhances the handling of arrays. Arrays can be of any data type (CHAR, INTEGER, FLOAT, SIGNED, LONG, etc.) Arrays can have up to 5 dimensions You can define arrays of structures, initialize arrays within the DEFINE_VARIABLE or DEFINE_START section, and define arrays as constants.
133
All arrays discussed to this point have a range of values in each element of to 255 and are classified as character arrays. (See ASCII Table for character values.) The range of values in a single variable is to 255, and when a value greater than 255 is assigned to an array element, the number is truncated above 255. For example, if the number 500 is assigned to an element in an array, the actual number that is assigned is 244. The easiest way to find the actual number is to subtract 256 from the number until the number is less than 256 (in this example, 500 - 256 = 244).
To create an array in which each element can contain values greater than 255, use an integer array. An integer array is just like a character array, except each element can hold values from to 65,535.
To declare an integer array, place the keyword INTEGER in front of the array definition in the DEFINE_VARIABLE section. If you want your CAM_PRESETS array to be an integer array, you would include the keyword INTEGER before the array identifier:
DEFINE_VARIABLE INTEGER CAM_PRESETS[6] //CAMERA PRESETS
This declares an integer array with six elements; each element can hold values from to 65,535. The contents of an integer array are often referenced by an element number. Example:
CAM_PRESETS[2] = 128
There are certain limitations of integer arrays. If an integer array is loaded into a CHAR array, values above 255 are truncated. For example:
INT = "'H','E','L','L','O'" //EACH LETTERS VALUE IS LESS THAN 255
This also happens if an integer array is sent to a device using the keywords SEND_STRING or SEND_COMMAND. There is no problem, however, in assigning a string array to an integer array. An integer array takes up twice as much memory than would a string array of the same storage capacity. If your array is only going to hold alphanumeric values, it is not necessary to make it an integer array.
STR = "12345,256,1525" //WOULD BE TRUNCATED TO "251,0,254"
134
Multi-Dimensional Arrays
Any of the single dimension array types listed above can be used to define an array of ndimensions. A 2-dimensional array is simply a collection of 1-dimensional arrays; a 3-dimensional array is a collection of 2-dimensional arrays, and so forth. Here's an example:
INTEGER Num1D[10] INTEGER Num2D[5][10] INTEGER Num3D[2][5][10] // [Column] // [Row][Column] // [Table][Row][Column]
One way to view these arrays is to think of Num2D as being a collection of five Num1D's and Num3D as being a collection of two Num2D's. When referencing elements of the above arrays:
Num1D[1] Num2D[1] Num2D[1][1] Num3D[1] Num3D[1][1] Num3D[1][1][1] refers refers refers refers refers refers to to to to to to the the the the the the 1st 1st 1st 1st 1st 1st element row element of the 1st row table row of the 1st table element of the 1st row of the 1st table
LENGTH_ARRAY and MAX_LENGTH_ARRAY are used to determine the effective and maximum
135
Arrays as Strings
There are two ways of referencing array data in AMX programs. Each element can be referenced as an individual value; or, each array can be referenced as a group of characters. An entire array can be accessed as one unit. If you refer to an array without specifying an index value, the contents of the entire array is referenced as a string, as shown in the following example:
DEFINE_VARIABLE S1[1] DEFINE_PROGRAM S1='TEST ONE' SEND_STRING CARD,"S1"
This small section of code will send a string to the specified DEVICE: 'TEST ONE'. We assigned a string expression to S1 and then sent it to the device; the entire string expression was sent.
Suppose that during power-up of an AMX Control System you want to set all the presets to default values. You could do this by assigning values to each individual element in the CAM_PRESETS array. It is recommended, however, to use a string expression to set all six at once, as shown below:
DEFINE_VARIABLE CAM_PRESETS[6] DEFINE_START CAM_PRESETS = ",3,9,128,191,255" //set all preset values at power-up
In many cases you may need to transfer a series of data values at once. You can do this by using strings and string expressions. A string is a set of values grouped together with single and/or double quotes. Strings enclosed in single quotes are called string literals. Examples of strings include names and the actual command portion of SEND_COMMAND statements.
String keywords (i.e. FIND_STRING, REMOVE_STRING, MID_STRING, etc.) do not work on integer arrays.
136
Sending Strings
To send a string to the outside world, use the SEND_STRING keyword. This tells the processor to send the string through the AMX port to the OEM device. The syntax is:
SEND_STRING device,<string, variable, or string expression>
The first value after the SEND_STRING keyword is the device number or identifier to which you wish to send the string. Following that is a comma, then the string, variable (which can be either a normal variable or an array), or string expression you wish to send. When an array variable is specified, the number of transmitted array characters is determined by the array length value. Set the length value for the array with the SET_LENGTH_STRING function.
For example, if you need to send the TEMP array to a card named RS232, you would write the following line:
SEND_STRING RS232,"TEMP"
String literals and string expressions can also be sent using SEND_STRING. For example:
SEND_STRING RS232,'THIS IS A STRING LITERAL'
Sends the entire set of characters enclosed in the single quotes, from left to right, to the device named RS232.
SEND_STRING RS232,"'EXPRESSION', TEMP,$D,$A"
This statement first builds the string expression using a string literal, followed by the characters stored in TEMP (defined by its length value), and then two numbers (expressed here in hexadecimal). The hexadecimal numbers in the example represent the codes for carriage return and line feed, respectively.
String Lengths
Every array declared in the DEFINE_VARIABLE section has a string length value associated with it. The string length of an array has an internal value set for arrays by string assignment operations. This number is different than the storage capacity declared in the DEFINE_VARIABLE section. You can get the length value of an array by using the LENGTH_STRING function. For example:
LENGTH = LENGTH_STRING (CAM_PRESETS)
Here are examples of some assignments, and what the above line of code would return to the variable length in each case:
PRESETS = 'FOUR' PRESETS = 'ONE' PRESETS = "12,5,'123'" PRESETS = "PLAY,5,,'NO',X" //LENGTH = 4 //LENGTH = 3 //LENGTH = 5 //LENGTH = 9
The length of a string array cannot exceed the number of storage locations allocated to it in the DEFINE_VARIABLE section. For example, if the string GOODBYE is placed in the CAM_PRESETS variable, the array will only contain the string GOODBY, dropping the final E because CAM_PRESETS was defined to hold a maximum of six locations. The length of CAM_PRESETS would also be set to 6. If you attempt to assign an array that exceeds the storage allocations, the system will generate a run time error message: BAD SET LENGTH.
137
When string literals and string expressions are assigned, the length of the string array is automatically set to the length of the string literal or string expression being assigned to it. However, assigning values to individual elements of an array does not affect the length value of the array. For instance, if the letters W, O, R, and D are assigned individually to elements of CAM_PRESETS, as shown below, the length will not change; if the length was previously 3, it will still be 3.
PRESETS[1] = 'W' PRESETS[2] = 'O' PRESETS[3] = 'R' PRESETS[4] = 'D'
The SET_LENGTH string keyword explicitly sets the string length value of an array variable. For instance, to set the length value of CAM_PRESETS to 4, you would use the statement:
SET_LENGTH_STRING(CAM_PRESETS,4)
String lengths play an important role in the handling of strings. The following string expression contains an array:
NEW_STRING = "5,TEMP,'GO'"
As the string is constructed from this expression, the number of characters it adds from NEW_STRING will equal the TEMP string's length value. If TEMP contains 1, 2, 3, 4, 5, 6, but its string length value is 3, the resulting string from the above string expression will look like the following example:
TEMP[1] = 1 TEMP[2] = 2 TEMP[3] = 3 TEMP[4] = 4 TEMP[5] = 5 TEMP[6] = 6 SET_LENGTH_STRING(TEMP,3) NEW_STRING = "5,TEMP,'GO'" //NEW_STRING now equals "5,1,2,3,'G','O'"
The array string length is important to many string operations. This value determines how much of the string is used when the entire array is referenced. Knowing this will prevent subtle errors in your code. For instance, if you assign values to individual elements in an array, and then assign that array to another, nothing is copied. For example:
DEFINE_PROGRAM TEMP[1] = SCREEN_UP TEMP[2] = 5 TEMP[3] = TEMP[4] = 'N' TEMP[5] = 'O' TEMP[6] = X CAM_PRESETS = TEMP
138
The contents of the array CAM_PRESETS, after this code is executed, depend on the length value of the TEMP variable. If this were the entire program, TEMP would have a default length of , so nothing would be copied into CAM_PRESETS. To assure that CAM_PRESETS holds a copy of TEMP, you would first need to set the length value of the TEMP array with this line inserted before the copy statement:
SET_LENGTH_STRING(TEMP,6)
The line above, when executed with the previous code example, renders the following result:
TEMP = "SCREEN_UP,5,,'NO',X"
After this, the length value of TEMP is 6; so, the first 6 locations of TEMP will be used in all cases where you refer to the entire array.
String Literals
Single quotes can only enclose values ranging from decimal 32 (the space character) to decimal 126 (the tilde character '~'). (See ASCII Code Chart section on page 142 for details.) These string literals are constant values that are set at compile time. Once loaded into the Central Controller, these strings cannot be changed, except when a new program is loaded into the Central Controller.
An index value is not given when strings are assigned to arrays. The first letter is automatically placed into the first storage location; the second letter is placed into the second storage location, and so on.
When the program processes this assignment, it places the F (ASCII value 70) in location 1 of PRESETS, O (ASCII value 79) in location 2, and so on, as shown in FIG. 1. String FOUR is placed in the array PRESETS.
139
String Expressions
Single and double quotes are interpreted in two different ways. Single quotes enclose string literals, double quotes enclose string expressions. A string expression combines several types of data into a single string. It can contain any ASCII value ( to 255), variables, string literals, and arrays. The difference between a string literal and the string expression is that the string expression is built at run time instead of compile time. As a string expression is processed, each member of the expression is evaluated from left to right; the result is a complete string. For example:
DEFINE_PROGRAM TEMP = "SCREEN_UP,5,,'NO',X" A string expression cannot contain another string expression; i.e., a set of double quotes cannot enclose another set of double quotes.
Assuming that SCREEN_UP is a constant with the value of 1, and X with the value of 10, the string expression is evaluated as a string with values: 1, 5, , 'N', 'O', 1, as shown in FIG. 2. Since the expression is evaluated at run time, whatever value is in the variable X when the expression is evaluated is what is placed into the result.
140
ASCII Codes
A string is broken up into single letters when placed into a string array. Each storage space returns the letter it is holding when referenced. For the following example, assume that TEMP[3] holds the letter R. There are actually three ways you can reference this array location, shown in this example using IF statements:
DEFINE_PROGRAM IF (TEMP[3] = 'R') { SEND_STRING ,"'TEMP[3] IS EQUAL TO "R"',$D,$A" } IF (TEMP[3] = $52) { SEND_STRING ,"'TEMP[3] IS EQUAL TO "R"',$D,$A" } IF (TEMP[3] = 82) { SEND_STRING ,"'TEMP[3] IS EQUAL TO "R"',$D,$A" }
The letter R has an ASCII value of 82 decimal, which is equivalent to 52 in hexadecimal. In the AMX programming language, hexadecimal numbers begin with a dollar sign ($). Therefore, the 2nd IF statement above shows $52, a hexadecimal number. To the processor, all three of these values are identical.
All three methods (letters, decimal equivalents codes, and hexadecimal values) can be used interchangeably. Use whichever method is easiest for the task at hand.
141
142
Conversion keywords
The following keywords automatically set the length value of the resulting string. Conversion Keywords
ATOI ATOI stands for "ASCII to integer". It takes a string literal, string expression, or array as a parameter, and returns a single integer as the result. Example:
DEFINE_CONSTANT STR1 = '456' STR2 = 'YES789GO19' DEFINE_PROGRAM NUM = ATOI('123') NUM = ATOI(STR1) NUM = ATOI(STR2) (* NUM = 123 *) (* NUM = 456 *) (* NUM = 789 *)
If the string contains all non-numeric characters (such as HELLO), ATOI returns the integer . However, if there are any numeric characters embedded in the string, ATOI returns the first complete set it comes upon, as is the case with STR2 above. Notice that only the first set of numbers from STR2 is returned. ITOA ITOA stands for "integer to ASCII". It creates a string that represents the decimal value of a number. Example:
DEFINE_CONSTANT CONST = 456 DEFINE_VARIABLE STR[5] VAR DEFINE_PROGRAM VAR = 789 STR = ITOA(123) STR = ITOA(CONST) STR = ITOA(VAR) (* STR = '123' *) (* STR = '456' *) (* STR = '789' *)
The comment after each statement shows the value of the array STR after each assignment. The length value of STR is set to 3 in each case. ITOHEX ITOHEX stands for "integer to hexadecimal". It works in the same manner as ITOA, except that the integer is transformed into a hexadecimal ASCII string. If you substitute the ITOA keywords in the previous example with ITOHEX keywords, this would be the result:
Notice there are no dollar signs ($) in the results. This is because the dollar sign indicates a numerical value expressed in hexadecimal, and is only used when telling Axcess that a number is hexadecimal.
143
ATOL
This function converts a character representation of a number to a signed 32-bit integer. SLONG ATOL (CHAR STRING[ ]) Parameters: STRING: A string containing the character representation of the integer. The result is a 32-bit signed integer representing the converted string. Any nonnumeric characters in the string are ignored. ATOL returns the value representing the first complete set of characters that represents an integer. Valid characters are "0" through "9" and the sign designators "+" and "-". If no valid characters are found, zero is returned as a result. Num = ATOL('Value = -128000') // Num = -128000
ATOF
This function converts a character representation of a number to a 64-bit floating-point value. It recognizes a character representation of a signed integer or floating-point number (with or without exponent). FLOAT ATOF (CHAR STRING[ ]) Parameters: STRING: An input string containing the character representation of the floating-point number. The result is a 64-bit floating-point number representing the converted string. Any non-numeric characters in the string are ignored. ATOF returns the value representing the first complete set of characters that represents a floating-point value. Valid characters are "0" through "9", ".", the sign designators ("+" and "-"), and the exponent ("e" or "E"). If no valid characters are found, zero is returned as a result. Num = ATOF('The total = -1.25e-3')// Num = -0.00125
FTOA
This function converts a 64-bit floating-point value to an ASCII string containing the decimal representation of the number. CHAR[ ] FTOA (DOUBLE Num, INTEGER nDigits) Parameters: Num: 64-bit floating-point number to convert to a decimal string. nDigits: Maximum number of digits to use to represent the number. If nDigits is not large enough to represent the number, exponential notation is used. At least two digits will always be used regardless of the value of nDigits. The result is a character string that contains the decimal representation of the specified floating-point number. The character representation will use exponents if necessary. STRING = FTOA(123.4, 4)// STRING = '123.4'STRING = FTOA(123.4, 3)// STRING = '1.23e2'STRING = FTOA(123.4, 2) // STRING = '1.2e2'
HEXTOI
This function converts an ASCII string containing the hexadecimal representation of a number to an unsigned 32-bit integer. LONG HEXTOI (CHAR STRING[ ]) Parameters: STRING: Hexadecimal formatted string to be converted to an integer The result is a 32-bit unsigned integer representing the converted string. Any nonhexadecimal characters in the string are ignored. HEXTOI returns a value representing the first complete set of characters that represents an integer. Valid characters are "0" through "9", "A" through "F" and "a" through "f". If no valid characters are found, zero is returned as a result. Num = HEXTOI('126EC') // Num = 75500
144
DATA_EVENTs
This keyword defines a data event handler. This type of handler processes COMMAND, STRING, ONLINE, OFFLINE and ONERROR events. It can only be used in the DEFINE_EVENT section of the program. DATA_EVENTs provide some interesting capabilities in a NetLinx system. At first glance, DATA_EVENT seems to be concerned with receiving strings of data either from a serial data device such as an NXC-COM2 card or an interface device such as a touch panel. While this is a valid function, DATA_EVENT has many more capabilities and work with many devices. Here is the structure for a DATA_EVENT:
DATA_EVENT [<device>] { COMMAND: { //command data event handler } STRING: { //string data event handler } ONLINE: { //online data event handler } OFFLINE: { //offline data event handler } ONERROR: { //error data event handler } }
NetLinx is able to process data received by a DATA_EVENT in real time. When data is received, it enters the message queue and triggers a DATA_EVENT. If a buffer has been created for the device, the data is placed within the buffer and can then be used by either the DATA_EVENT or mainline. The data can be evaluated in two ways. The actual string that is received by the message queue can be evaluated using the DATA.TEXT object within the event. The string in DATA.TEXT is also added to the end of the devices buffer. This becomes a factor when receiving large strings or when receiving strings with an embedded string length or start and end characters. The DATA_EVENT can then evaluate the buffer to see if the entire string has been received before processing it. However, the evaluation is done immediately upon receipt of another chunk of data, and is only done when data is received. For example, DATA.TEXT may equal {over the lazy brown dog,ETX} and the DATA_BUFFER[500] might equal {STX,The quick grey fox jumps over the lazy brown dog,ETX}. By evaluating the buffer value, you can evaluate the entire string at once.
145
Two other important aspects of the DATA_EVENT are the ONLINE and OFFLINE event handlers. ONLINE and OFFLINE events are triggered when the master recognizes a device has come on the bus or has dropped off the bus.
In NetLinx all device initializations and offline warnings are handled through the DATA_EVENT. Since every device triggers an ONLINE event when the master is reset, this not only ensures that the device will be initialized on startup but also insures that the device will be initialized anytime the device comes online. The DATA_EVENT is also evaluated on an as needed basis, rather than on each pass through mainline. NetLinx Data Event:
DEFINE_START CREATE_BUFFER TP1, TP1_BUFFER . . DEFINE_EVENT .. DATA_EVENT[TP1](* EVALUATE TP1 DATA *) { STRING: { SELECT { ACTIVE (FIND_STRING (DATA.TEXT,'PAGE-',1)): { JUNK = REMOVE_STRING (DATA.TEXT,'PAGE-',1) CUR_PAGE = DATA.TEXT } ACTIVE (FIND_STRING (DATA.TEXT,'KEYP-',1)): { // keypad code } ACTIVE (FIND_STRING (DATA.TEXT,'KEYB-',1)): { // keyboard code } ACTIVE (1): { // default code } } CLEAR_BUFFER TP1_BUFFER } ONLINE: { SEND_COMMAND TP1, 'TPAGEON' } }
Each event handler contains several imbedded data objects, which pass data values into the event handler code. A complete listing of these objects is available for each event handler in the NetLinx Programming Language Instruction Manual.
Please see the Appendix - Embedded Event Data Objects on page 223 for more information on this Event.
146
Buffers
One of the most powerful features of AMX devices is their ability to send and receive any combination of values using RS-232, RS-422, RS-485, PA-422, MIDI, and a variety of other formats. You have the ability to construct any combination of numbers and characters with the string expression and send it to an external device. In addition, you can receive strings from external devices and interpret them to obtain useful information. The received strings are temporarily stored in Buffers. A Buffer is an array variable that is associated with a particular device that stores information sent by the device. Buffer Keywords:
Receiving Strings
Receiving strings requires several more steps than sending strings. You must first create a buffer to receive strings from a device. A buffer is an array variable associated with a particular device for the purpose of storing information received from the device.
Creating Buffers
To create a buffer, use the CREATE_BUFFER keyword to create a link between the device and the destination array. This keyword can only appear in the DEFINE_START section of your program; the syntax is:
CREATE_BUFFER device, array
The CREATE_BUFFER keyword directs the processor to place any data received from the specified device into the specified array. When the bytes are placed into the array, it increments the length value for the array and then places the bytes into the array at the current end of the array. See FIG. 3 for a pictorial explanation.
Even though the array is acting as a buffer, it is still an array and can be treated as one. You can still access the individual locations, send it to a device, assign it to other arrays, assign other arrays to it and use the array manipulation keywords,
147
FIG. 3 When data comes in from a device, it goes into the spot determined by the length value of the array. Here, the length value was 3. So the 'Y' is put into location 4, and the length value is incremented to 4.
Storing Characters
When a device sends string information to the Central Controller, the Central Controller places the incoming information into the buffer created for that device, and updates the buffer's length value. These actions are executed after the Central Controller has passed through mainline. Since all data going in and out of these devices is serial, each byte is handled one at a time.
NetLinx drops characters that exceed the array length (FIG. 4).
FIG. 4 In NetLinx, inserting a character into a full Buffer causes the first character to be dropped.
Because of this condition it is EXTREMELY important to properly size and clear your buffers after use.
148
Retrieving Characters
Use the keyword GET_BUFFER_CHAR to retrieve characters. This keyword has a two-part operation: First, it retrieves the first character in the buffer for your own utilization. This creates the same effect as if you retrieved the first storage location of a normal string array. Second, it removes that character from the buffer, causing all the other characters to shift up one place. The second character is now the first, the third is now the second, and so on. Here is the syntax:
string = GET_BUFFER_CHAR (array)
The parameter passed to GET_BUFFER_CHAR must be an array, but does not need to be a buffer. Remember that all buffers are arrays, but not all arrays are buffers. The statement will operate identically in either case. The result must be a simple variable (not an array), because only one character will be returned. These examples show how to create an array called SWT_BUFFER with a capacity of a hundred characters, and how to make it a buffer associated with a device named SWT.
DEFINE_DEVICE SWT = 1 //AXC-232: AUTOPATCH 4YDM *) //BUFFER FOR SWITCHER *) //FOR PARSING ABOVE *) DEFINE_VARIABLE SWT_BUFFER[1] TEMP_CHAR DEFINE_START CREATE_BUFFER SWT,SWT_BUFFER
Now all string data sent to the Central Controller from the device SWT will go into the array SWT_BUFFER. Getting the data out of the buffer as soon as it enters is usually a two-step process, as shown in this example:
DEFINE_PROGRAM IF (LENGTH_STRING(SWT_BUFFER)) { TEMP_CHAR = GET_BUFFER_CHAR(SWT_BUFFER) IF (TEMP_CHAR = 'T' || TEMP_CHAR = '.') { SEND_STRING ,"'SWITCH COMMAND COMPLETE',$D,$A" } } //SEND RESULT THROUGH //MASTER PORT TO TERMINAL //REMOVE FIRST CHAR //THERE IS AT LEAST ONE CHARACTER IN BUFFER
These two lines of code are actually one IF statement. The condition of the IF is the result of the LENGTH_STRING keyword. If there are not any characters in the buffer (the length value of SWT_BUFFER is ), then the central controller will skip the second part of the statement.
149
The second part, which will be executed if there is one or more characters in SWT_BUFFER, retrieves the first character in SWT_BUFFER, and places it into the variable TEMP_CHAR, as shown in FIG. 5
FIG. 5 Getting the next character out of a buffer with GET_BUFFER _CHAR.
Characters should be continuously retrieved and removed from the buffer so that incoming strings have enough spaces to enter completely. Be sure to place a GET_BUFFER_CHAR statement in a position to do this. Remember, mainline is constantly running through the main program, and will execute the GET_BUFFER_CHAR statement as long as it is in its path of execution.
To get the data of the SWT_BUFFER using REMOVE_STRING, use the following code:
IF (LENGTH_STRING(SWT_BUFFER)) AND (FIND_STRING(SWT_BUFFER,'T',1) OR FIND_STRING(SWT_BUFFER,'.',1))) { REMOVE_STRING(SWT_BUFFER,'T',1) IF (LENGTH_STRING(TRASH) = ) REMOVE_STRING(SWT_BUFFER,'.',1) IF (LENGTH_STRING(TRASH) = 1) SEND_STRING ,"'SWT ACK',13,1" }
The code on the previous page is similar and has the same effect as the previous code. The IF condition is looking to see if SWT_BUFFER has any characters in it with a FIND_STRING and then it looks to see if the string contains either a 'T' or a '.'. Once these two conditions are met, we attempt to remove a 'T' from the buffer. If that attempt fails, then the length of TRASH will be . Only then will it attempt to remove the '.' since it did not find a 'T'. The REMOVE_STRING will remove all characters up to and including the 'T' or the '.'. So if the SWT_BUFFER contained a 'CI1O1T', then after the line of code:
TRASH = REMOVE_STRING(SWT_BUFFER,'T',1)
150
Notice that the string literals FRED and Fred are not the same. However, in the case of identifiers Identifier_1 and Identifier_2, the program does not differentiate based on the case of the letters in the identifier name. Also, notice that in this example the keyword "if" is not capitalized, making no difference to the compiler. Setting Uppercase and Lowercase In a string literal, the lowercase letter 'a' is not the same as the uppercase letter 'A' Each has its own decimal ASCII code (the code for 'a' is 97, 'A' is 65). This could become problematic when, for example, your program compares the incoming string ABC against another, as shown below:
IF (ABC = 'YES') { //statement(s) }
If the incoming string is 'YES', there is no problem. The statements are executed as normal. However, if ABC equals 'Yes', since 'YES' and 'Yes' do not have the same decimal ASCII value, the statements below the IF statement would not be executed.
The solution is to change all incoming strings to either uppercase or lowercase. The keywords that do this are UPPER_STRING and LOWER_STRING. For example, the following statement can be added before the preceding program:
ABC2 = UPPER_STRING(ABC)
The IF statement can now compare ABC2 against 'YES', providing that the IF statement reads IF (ABC2 = 'YES'). The string 'Yes' is accepted since it has been converted into uppercase. Conversely, LOWER_STRING converts a string into lowercase.
151
Buffer Keywords
The AMX Buffer keywords are described below: Buffer Keywords
CLEAR_BUFFER Clears a buffer. This keyword effectively sets the length of the buffer to zero, so that subsequent GET_BUFFER_CHAR statements will not return anything. Using CLEAR_BUFFER is preferable to other methods, such as assigning a null string to the buffer, or using SET_LENGTH_STRING. The CLEAR_BUFFER keyword actually compiles into smaller code and executes faster than the other methods, plus it is clearer to the reader as to what the programmer is trying to accomplish. This keyword can only appear in the DEFINE_START section of your program, and has the following syntax: CREATE_BUFFER device, array CREATE_BUFFER places any strings received from the specified device into the specified array. When the byte is placed into the array, the length value is incremented for the array and then placed at the end of the array. In Axcess, when the array is full, all bytes in the array are shifted to make room for the new byte at the end. In NetLinx, overflow bytes are dropped. Though the array is acting as a buffer, it is still an array and can be treated as one. You can access its individual locations, send it to a device, assign it to other arrays, assign other arrays to it, and use keywords to manipulate the array. GET_BUFFER_CHAR This keyword is used to remove characters from a buffer. It has a two-part operation: First, it retrieves the first character in the buffer for your own utilization. This creates the same effect as if you retrieved the first storage location of a normal string array. Second, it removes that character from the buffer, causing all the other characters to shift up one place. The second character is now the first, the third is now the second, and so on. Here is the syntax: result = GET_BUFFER_CHAR (array) The parameter passed to GET_BUFFER_CHAR must be an array, but does not need to be a buffer. The keyword will operate identically in either case. Only one byte (character) will be returned, and this value can be assigned to a variable, array, or a cell in an array.
152
X = FIND_STRING (TEMP,'LO',1)
When Axcess executes this statement, it will search the array TEMP from the beginning, looking for the string LO. If Axcess finds the substring, it returns the starting position of the substring in the TEMP array: in this case, 4. The third parameter (in this example, 1) tells Axcess where (in the string) to start the search.
153
REMOVE_STRING
The REMOVE_STRING keyword is similar to the FIND_STRING keyword. However, when Axcess finds the sequence it is looking for, it extracts every character up to and including the sequence, starting from the number in the third parameter. All other characters move up to fill in the space. Example:
DEFINE_VARIABLE SOURCE[2] DEST[2] DEFINE_PROGRAM SOURCE = 'THIS IS A TEST' DEST = REMOVE_STRING (SOURCE,'IS',1)
After the last line is executed, DEST will contain THIS, and SOURCE will contain IS A TEST. Notice that after the removal, the first location of the array SOURCE contains a space. This is because REMOVE_STRING removed all characters from the beginning of SOURCE up to and including the string IS. It did not remove the space following the string IS in SOURCE. Also notice that the first occurrence of IS is embedded in the word THIS. The length values of both arrays are set according to the results of the operation. In this case, the length value of SOURCE is set to 4; DEST is set to 10. In FIND_STRING, each of the first two parameters can be a string literal, a string expression, or an array. However, in the case of REMOVE_STRING, having anything except an array as the first parameter is illogical because Axcess cannot remove part of a string literal or string expression, only an array variable. This is because string literals are constant values and string expressions may contain constant values. Once loaded into the Central Controller, constant values cannot be changed, as shown in the following examples:
STR = REMOVE_STRING(TEMP,"12",1) OK *)
(*
STR = REMOVE_STRING("2,'HELLO',1,13",'HELLO',1) (* NO *)
REMOVE_STRING changes the first parameter after it removes whatever characters it needs. Only variables can be changed at run time. Supply the starting position of the search as the third parameter for both FIND_STRING and REMOVE_STRING. LENGTH_STRING Returns the current length value of an array. This number is different from the storage capacity of an array, which is defined in the DEFINE_VARIABLE section. The length value of an array is used by several of the Axcess string operation keywords; this value can change during program execution. Syntax:
154
Code Examples:
This example illustrates CREATE_BUFFER, Sending text to the touch panel and clearing buffers. A buffer can be declared volatile since it's contents are not required after the system is shutdown. The device will report it's new status in response to the next command. Buffers DEFINE_VARIABLE Volatile CHAR strAP800_BUFF[255] INTEGER nLEN DEFINE_START CREATE_BUFFER strAP800, straAP800_BUFF DEFINE_PROGRAM IF (FIND_STRING(strAP800_BUFF,"13",1)) { SEND_COMMAND dvTP,"'@TXT',1,strAP800_BUFF" SEND_STRING 0,"'RESPONSE IS ',strAP800_BUFF" strAP800_BUFF = REMOVE_STRING(strAP800_BUFF,"13",1) nLEN = LENGTH_STRING(strAP800_BUFF) SET_LENGTH_STRING(strAP800_BUFF,nLEN-1) nMUTEFB = ATOI(RIGHT_STRING(strAP800_BUFF,1)) CLEAR_BUFFER strAP800_BUFF strAP800_BUFF = '' } //CLEAR IT OUT (SETS INDEX POINTER TO 0) //ALTERNATE METHOD TO CLEAR
OR
DEFINE_VARIABLE Volatile CHAR strAP800_BUFF[255] INTEGER nLEN DATA_EVENT [dvTP] { STRING: { SEND_COMMAND dvTP,"@TXT, 1,DATA.TEXT" STRAP800_BUFF = LEFT_STRING (DATA.TEXT, LENGTH_STRING (DATA.TEXT)-1) nMUTEFB = ATOI ("RIGHT_STRING (DATA.TEXT, 1)") } }
155
156
Loops
Loops
Lesson Topics
While Loops
The WHILE family of keywords allow the program to loop through a certain section of a program until a condition becomes false. If the condition is false, NetLinx skips the statements immediately following the WHILE. If the condition is true, NetLinx executes the statements, and rechecks the WHILE's conditional expression. If the condition is still true, the statements are executed again. This sequence continues until the condition is evaluated as false.
WHILE (<conditional expression>) { //conditional statements }
In NetLinx, statements are executed repeatedly while the conditional expression evaluates to true. The condition is tested before each pass through the conditional statements. While Keywords
This keyword executes its statement block as long as its associated condition evaluates to true. The condition is evaluated before the first pass through the statements. Therefore, if the conditional expression is never true the conditional statements will never be executed. WHILE (<conditional expression>) { (* conditional statements *) } This keyword is the same as a WHILE statement except that input messages are retrieved after each pass to allow the LONG_WHILE statements to process the input. LONG_WHILE (<conditional expression>){(* conditional statements *)} This keyword is obsolete in the new NetLinx system. The compiler will treat it as a WHILE keyword.
WHILE
LONG_WHILE
MEDIUM_WHILE
AMX recommends avoiding the use of WHILE Loops. Incorrect usage of a WHILE Loop can cause a program to get stuck in the loop.
157
Loops
FOR Loops
FOR loops are an alternative looping procedure to traditional loops. Functionally they do the same thing, but FOR loops are more readable. FOR loops, like WHILE loops, do not process input changes from the message buffer.
Parameters:
<INITIAL> One or more statements that are executed one time before any FOR loop statements are executed. Each statement must be separated with a comma; this is typically a FOR loop index initialization statement. A condition whose value is computed before each pass. If the condition evaluates to TRUE, the FOR loop statements are executed. If the condition evaluates to FALSE, the loop is terminated. One or more statements that are executed after each pass through the statements. Each statement must be separated with a comma. This is typically a statement that increments the FOR loop index.
<condition>
<after pass>
The <initialization expression> contains one or more statements that are executed one time before any FOR loop statements are executed. Each statement must be separated by a comma (,). The <test expression> is the condition for which the loop is evaluated before each pass. If the condition evaluates TRUE, the FOR loop statements execute. If the condition evaluates FALSE, the loop terminates. The <incremental expression> contains one or more statements that are executed after each pass through the loop statements. Each statement is separated by a comma (,).
In NetLinx you can write the same loop with a FOR statement and clarify how the loop operates:
FOR (COUNT=0 ; COUNT<10 ; COUNT++) { //loop statements }
By defining the loop like this, you clearly see both how the loop is initialized and how the loop is incremented. If you forget to initialize the WHILE loop or forget to initialize the counter, you dont get any errors. The FOR loop helps to insure proper structure.
158
Introduction to TPDesign4 Transfer and Upload File from TPD4 Use Web Control with G4 Panels
Introduction to TPDesign4
TPDesing4 is a proprietary software program designed by AMX to create touch panel pages. The following chart gives an overview of the features of TPD4. TPDesign4 Features
Supports AMX G4 graphics 24-bit color palette with 256 levels of transparency More than 40 families of button borders each including multiple sizes Directly utilizes Windows TrueType Fonts Imports graphics in multiple formats Undo/Redo functionality Multi-State buttons Button animation Dynamic Images Computer Control
In TPDesign4, all file transfer operations are routed through the NetLinx Master to which the target/source touch panels are connected. You will never actually connect directly to the panels. There are two types of file transfer operations in TPDesign4 (both accessible via the Transfer menu): Send To Panel: Sends your TPDesign4 project file to a specified NetLinx Master. Receive From Panel: Receives your TPDesign4 project file from a NetLinx Master. Connections are maintained separate from the transfer itself, so they do not need to be established/ dropped each time a transfer is performed. Use the Connect dialog to define and save one or more connection settings.
159
The Connect dialog allows you to set up communications, and save multiple connection configurations for easy access. Select Transfer > Connect to access this dialog. There are three possible ways to connect to a NetLinx Master: TCP/IP, Serial or Modem:
4. 5. 6. 7. 8.
4. 5. 6. 7.
160
3. 4. 5. 6.
Use the File > Receive From Panel option to connect to a Master and upload a panel file from a compatible G4 touch panel on that Master's bus. There are three ways to connect and transfer Panel files: TCP/IP, Serial and Modem.
To transfer to a G4 panel, verify that the NetLinx Master Firmware is build 85 or later. Verify the TPDesign4 program being used is Version 1.01 or higher. Earlier versions of the firmware and TPD4 software are incompatible with G4 panels.
161
Master that are currently online (according to the Filter setting). The online device tree lists the online devices by System #, Device #, Description, (firmware) Version, and Manufacturer.
To refresh the Online Devices Tree, disconnect and reconnect via the commands in the Transfer menu.
4.
Use the Options checkboxes in the Send to Panel or Receive From Panel dialog to enable/ disable the following transfer options:
Smart transfer (updated panel files only): Select to utilize the Smart Transfer feature, which reduces the transfer time by only replacing those panel files that have been updated (relative to the files already loaded in the panel). Any bitmaps, sound files and fonts that all already resident on the target panel, or in your panel file on your PC (for uploads) are not included in the transfer. Normal transfer (all panel files): This option sends all panel files. Full clean transfer (all panel & system graphic files): Select this option to automatically wipe out any existing project files resident in the target panel before loading the new panel file.
If you are simply sending a panel file to a panel, you don't need to use the Full Clean option, since any existing panel files on the target panel will be wiped out anyway. The Full Clean option adds considerable time to the transfer, since it involves sending many more files, and is not necessary in most cases.
Open received panel (uploads only): Select this option to automatically open the panel file once it is received. Clear from status queue when complete: This option (enabled by default) clears each transfer from the Transfer Status Window when complete.
5.
If you encounter a transfer error, verify the IP Address, Panel ID, and connection status of both NetLinx Master and Modero panel.
162
d. Click OK to save the configuration and close the Connection Settings dialog 2. 3. Click Connect in the Connect dialog to establish the serial connection. Once communication is established, either the Send To Panel or Receive From Panel dialog is invoked (depending on wether you selected Send to Panel or Receive From Panel from the Transfer menu), displaying an online device tree, indicating all devices connected to the Master that are currently online (according to the Filter setting). The online device tree lists the online devices by System #, Device #, Description, (firmware) Version, and Manufacturer.
To refresh the Online Devices Tree, disconnect and reconnect via the commands in the Transfer menu.
4.
Use the Options checkboxes in the Send to Panel or Receive From Panel dialog to enable/ disable the following transfer options:
Smart transfer (updated panel files only): Select to utilize the Smart Transfer feature, which reduces the transfer time by only replacing those panel files that have been updated (relative to the files already loaded in the panel). Any bitmaps, sound files and fonts that all already resident on the target panel, or in your panel file on your PC (for uploads) are not included in the transfer. Normal transfer (all panel files): This option sends all panel files. Full clean transfer (all panel & system graphic files): Select this option to automatically wipe out any existing project files resident in the target panel before loading the new panel file.
If you are simply sending a panel file to a panel, you don't need to use the Full Clean option, since any existing panel files on the target panel will be wiped out anyway. The Full Clean option adds considerable time to the transfer, since it involves sending many more files, and is not necessary in most cases.
Open received panel (uploads only): Select this option to automatically open the panel file once it is received. Clear from status queue when complete: This option (enabled by default) clears each transfer from the Transfer Status Window when complete.
5.
163
d. Click OK to save the configuration and close the Connection Settings dialog 2. 3. Click Connect in the Connect dialog to establish the modem connection. Once communication is established, either the Send To Panel or Receive From Panel dialog is invoked (depending on wether you selected Send to Panel or Receive From Panel from the Transfer menu), displaying an online device tree, indicating all devices connected to the Master that are currently online (according to the Filter setting). The online device tree lists the online devices by System #, Device #, Description, (firmware) Version, and Manufacturer.
To refresh the Online Devices Tree, disconnect and reconnect via the commands in the Transfer menu.
4.
Use the Options checkboxes in the Send to Panel or Receive From Panel dialog to enable/ disable the following transfer options:
Smart transfer (updated panel files only): Select to utilize the Smart Transfer feature, which reduces the transfer time by only replacing those panel files that have been updated (relative to the files already loaded in the panel). Any bitmaps, sound files and fonts that all already resident on the target panel, or in your panel file on your PC (for uploads) are not included in the transfer. Normal transfer (all panel files): This option sends all panel files.
164
Full clean transfer (all panel & system graphic files): Select this option to automatically wipe out any existing project files resident in the target panel before loading the new panel file.
If you are simply sending a panel file to a panel, you don't need to use the Full Clean option, since any existing panel files on the target panel will be wiped out anyway. The Full Clean option adds considerable time to the transfer, since it involves sending many more files, and is not necessary in most cases.
Open received panel (uploads only): Select this option to automatically open the panel file once it is received. Clear from status queue when complete: This option (enabled by default) clears each transfer from the Transfer Status Window when complete.
5.
Modem transfer is the slowest method of transferring TPD4 panel files to the target device. This method can range in speed but on average communicates at 3 Kbps.
There are three basic steps to Masterless TCP/IP file transfers: 1. 2. 3. Configure the touch panel for Masterless TCP/IP transfers Configure TPDesign4 for Masterless TCP/IP transfers Transfer the Files Using a Virtual NetLinx Master TCP/IP connection
165
6.
To receive files from the panel, select Transfer > Receive From Panel.
Allow several seconds after the panel is rebooted for it to appear in the Online Device list in the Send To Panel or Receive From Panel dialogs.
Configuring the Touch Panel for Virtual NetLinx Master TCP/IP Transfers
If it is not already powered up and connected, apply power to the touch panel and verify that it is connected to the LAN via the TCP/IP connector on the rear (or side) of the panel (G4 panels only).
To configure the panel for Virtual NetLinx Master transfers: 1. 2. 3. 4. 5. 6. 7. 8. 9. Press and hold the grey Front Setup Access button (below the touch screen) for 3 seconds to access the Setup page. Press the Protected Setup button to access the Protected Setup page. Use the on-screen keyboard to enter the password (the default password is 1988). Press the System Connection button to access the System Connection Setup page. Select Ethernet as the Master Connection. Select URL as the Connection Mode. Set the System Number to 0 (zero). Select the Master URL / IP input box and enter the IP address of your PC (displayed in the Virtual NetLinx Master Properties dialog). Press the Back button to return to the Protected Setup page and press the Reboot button to reboot the panel.
10. After several seconds, the panel should appear in the online device tree, listed as Virtual NetLinx Master. Once you can see the device online, you may transfer panel files to and from the G4 device without the need for an intermediate NetLinx master.
166
Receiving Files From The Panel 1. 2. 3. Select Transfer > Receive from Panel to open the Receive from Panel dialog. Select any Options (Smart Transfer, Normal Transfer or Full Clean) as desired. Click the Receive button to initiate the transfer. The progress of the transfer is indicated in the Status column of the Transfer Status Window.
See Tech Note 608, USB connection to Work on MVP or CV7 Panels for more detailed information on this topic.
167
Configuring TPDesign4 for Virtual NetLinx Master USB Transfers 1. 2. 3. Select Transfer > Connect to open the Connect dialog (or click the toolbar button). Select [Virtual NetLinx Master] from the Connection drop-down list. Select Transfer > Send to Panel to open the Send To Panel dialog. The panel should appear in the list of Online Devices. Once you can see the panel online, you may transfer panel files without the need for an intermediate NetLinx master. To receive files from the panel, select Transfer > Receive From Panel.
Allow several seconds after the panel is rebooted for it to appear in the Online Device list in the Send To Panel or Receive From Panel dialogs.
Receiving Files From The Panel 1. 2. 3. Select Transfer > Receive from Panel to open the Receive from Panel dialog. Select any Options (Smart Transfer, Normal Transfer or Full Clean) as desired. Click the Receive button to initiate the transfer. The progress of the transfer is indicated in the Status column of the Transfer Status Window.
168
Default setting is zero Displays the connection type used on the panel for communication (detected only after the panel is rebooted)
2. 3.
Press the Protected Setup button (located on the lower-left of the panel page) to begin opening the Protected Setup page and display an on-screen keypad. Enter 1988 into the Keypads password field and press Done when finished.
Clearing Password #5, initially from the Passwords page, removes any future need for entering the factory default password before accessing the Protected Setup page.
4. 5.
Press the blue Device Number field to open the Device Number keypad (FIG. 2). Enter a Device Number for the panel into the Device Number Keypad. The default is 10001 and the range is from 1 - 32000.
169
When using multiple panels within a NetLinx System, remember to assign unique Device Number values to each Modero panel so that all assigned panels appear in the System listing for the target Master.
6. 7.
Press the Web Control Name field to open the Web Name keyboard. From the Web Name keyboard, enter a unique alpha-numeric string to identify this panel. This information is used by the NetLinx Security Web Server to display on-screen links to the panel. The on-screen links uses the IP Address of the panel and not the name for communication (FIG. 3).
8. 9.
Press Done after you are finished assigning the alpha-numeric string for the Web Control name. Press the Web Control Password field to open the Web Password keyboard.
10. From the Web Password keyboard, enter a unique alpha-numeric string to be assigned as the G4 Authentication session password associated with VNC web access of this panel. 11. Press Done after you are finished assigning the alpha-numeric string for the Web Control password. 12. Press the Web Control Port field to open the Web Port Number keypad.
170
13. Within the keypad, enter a unique numeric value to be assigned to the port the VNC Web Server is running on. 14. Press Done to close the keypad, assign the number, and return to the Protected Setup page. 15. Press the on-screen Reboot button to restart the panel and incorporate any changes. 16. Press Done when you are finished entering the value. The remaining fields within the G4 Web Control Settings section of this page are read-only and cannot be altered. 17. Press the Up/Down arrows on either sides of the G4 Web Control Timeout field to increase or decrease the amount of time the panel can remain idle (no cursor movements) before the session is closed and the user is disconnected. 18. Press the Protected Setup button to open the Protected Setup page. 19. Press the on-screen Reboot button to reboot the panel and save your changes.
171
172
Multi-Dimensional Arrays Data Structures Assigning Values to Arrays and Structures Data Sets
Multi-Dimensional Arrays
NetLinx has the ability to store up to 5-dimensional arrays. Multi-dimensional arrays give us the ability to store groups of similar data.
It is a good idea to limit the scale of arrays to two-dimensional or three-dimensional arrays, because of the complexity of documenting the arrays and clarifying the use of the array in the code.
Since each dimension in multi-dimensional array to contain 65,535 elements, it is important to know how much memory is allocated to an array. A character array defined with five dimensions each containing only 64 elements that array will occupy 1,073,741,824 bytes or 1 giga-byte of memory! More memory than is currently available in the NetLinx system.
Multi-dimensional arrays are also limited to only one data type, and may not be the right type of tool for the job.
Examples:
This will define a character array that can hold up to 25 elements (characters). This array can store one song title.
DEFINE_VARIABLES CHAR CD_LIST [25]
This defines a two dimensional character array that can hold 12 sets of 25 elements (characters). This array can store twelve song titles each with 25 characters.
DEFINE_VARIABLES CHAR CD_LIST [12][25]
173
This defines a three dimensional character array that can hold 300 groups of 12 sets of 25 elements (characters). This array can store three hundred list with twelve song titles each with 25 characters.
DEFINE_VARIABLES CHAR CD_LIST [300][12][25]
This defines a four dimensional character array that can hold four divisions each containing 300 groups of 12 sets of 25 elements (characters). This array can store 1200 lists with twelve song titles each with 25 characters.
DEFINE_VARIABLES CHAR CD_LIST [4][300][12][25]
This defines a five dimensional character array that can hold twenty sets each containing four divisions of 300 groups of 12 sets of 25 elements (characters). This array can store four divisions of 1200 lists with twelve song titles each with 25 characters.
DEFINE_VARIABLES CHAR CD_LIST [20][4][300][12][25]
Now that an array to store song titles has been defined, how much memory will be allocated to this variable? 1 byte *25*12*300*4*20 = 7,200,000 bytes
Data Structures
NetLinx has the ability to define Structures within the NetLinx program. Structures define a new data type, which contains a group or set of member variables. The members define the data contained in the structure and describe the function of the data in the structure.
The Structure is defined within the DEFINE_TYPE section of the NetLinx Program. A structure is defined in the following format:
DEFINE_TYPE STRUCTURE struct_tag { data_type1 member1 data_type2 member2 . . data_type_n member_n }
Where:
struct_tag is a unique identifier given to the structure data_type_n is any NetLinx data type or previously defined structure member_n is an identifier unique to the structure and can be defined as a single variable
or an array
174
The definition of the structure only outlines the template for the data type. The definition of the structure does not actually reserve any memory.
Using Structures
The first step to creating a Structure is to list the data that is required: Using the CD collection as an example:
Now that the Structure has been defined as a new data type, you must define a variable. The variable can be defined as a single variable or an multi-dimensional array.
DEFINE_VARIABLE struct_tag struct_variable1 struct_tag struct_array1[3][5] Where: struct_tag is the structure defined in DEFINE_TYPE struct_variable1 is a unique identifier for a single instance of the structure struct_array1[3][5] is a two-dimensional array of the structure
//2-DIMENSIONAL STRUCTURE
The individual member of the structure can be accessed using the dot operator. For example we can assign values to member1 of the structures above using the following statements:
struct_variable1.member1 = value struct_array1[2][2].member1 = value
Using the dot operator, the members of the structure can be used anywhere a variable of the same data type would be used.
To assign data to a structure variable is slightly different than to an intrinsic variable type. You must reference the variable name and the element of the structure desired. Assigning data to a structure variable array is similar but also includes the array index. For example:
BUT_SERIOUSLY[5].TITLE=Colours BUT_SERIOUSLY[5].MIN=8 BUT_SERIOUSLY[5].SEC=51
175
One of the features of NetLinx structures is the ability to use a previously defined Structure in another Structure. For Example:
DEFINE_TYPE STRUCTURE CD_INFO { CHAR CD_TITLE[30] SONGS TRACK[15] INTEGER REL_YEAR CHAR GENRE[20] }
SONGS was defined as a new data type previously. This structure uses an array of the data type SONGS to list the songs of a CD. The total amount of space that would be allocated to this data type is 487 bytes.
Now that another Structure has been defined as another new data type, it can also be used in the DEFINE_VARIABLES section.
DEFINE_VARIABLES SONGS TRACK5 SONGS BUT_SERIOUSLY[12] CD_INFO CD_LIST[300]
Assigning data to this new structure variable array is similar but also includes the elements of the embedded structure. For example:
CD_LIST[1].CD_TITLE=But Seriously CD_LIST[1].TRACK[1].MIN=8 CD_LIST[1].TRACK[1].SEC=51 CD_LIST[1].TRACK[1].TITLE=Hang In Long Enough CD_LIST[1].TRACK[2].TITLE=Thats Just The Way It Is CD_LIST[1].REL_YEAR=1987 CD_LIST[1].GENRE=POP
176
2.
5.
The members of structures can only be assigned individually, except when the member is a CHAR array or string, outside the DEFINE_VARIABLE section.
//RIGHT //RIGHT //WRONG
6. 7.
Arrays with the same data type, number of dimensions and number of elements can be directly assigned to each other. Structures with the same structure type can be directly assigned to each other.
Data Sets
NetLinx predefines several structures that are designed to work with NetLinx device numbers, channels, and levels. Data sets allow you to group and in essence, combine certain elements of NetLinx devices. There are three data set structures supported by NetLinx: DEV (Device Sets), DEVCHAN (Device-Channel Sets), and DEVLEV (Device-Level Sets). You have already seen the structure DEV structure in the DEFINE_DEVICE section. the structure DEV in the DEFINE_TYPE section it would look like this:
STRUCTURE DEV { INTEGER DEVICE INTEGER PORT INTEGER SYSTEM }
177
DEV
Devices can also be grouped to allow functions or commands to be issued to the group. NetLinx includes a built-in Structure called a DEV which contains integers for the device number, port number and system number.
The actual instancing of the structure is unique to the DEV structure because you separate the individual structures elements with colons instead of enclosing the structure with braces and separating the elements with commas.
DEVCHAN
Similar to DEV sets, pairs of device,channels can be grouped. DEVCHAN is a built-in structure which contains the DEV structure and an integer to represent a channel. An array of device,channel pairs can be created:
DEFINE_VARIABLE DEVCHAN VCR_BTNS[] = {{TP,1},{TP,2}, {TP,3},{TP,4},{TP,5}} DEVCHAN RELAYS[] = {{RELAY,1},{RELAY,2},{RELAY,3}}
Once a Structure is defined that Structure can be used in another Structure. This is done in the DEVCHAN and DEVLEV Structures.
STRUCTURE DEVCHAN { DEV DEVICE INTEGER CHANNEL } STRUCTURE DEVLEV { DEV DEVICE INTEGER LEVEL }
178
DEVCHAN and DEVLEV Structures are initialized in the same way as other NetLinx structures. For example using DEVCHAN we can create a group of buttons on a user interface that are used for similar functions:
DEVCHAN SWT_INPUTS[4]= { {dvTP,41}, {dvTP,42}, {dvTP,43}, {dvTP,44} }
This can enable the use of a group of device channel or device level sets as the parameter to an event. DEVLEV is another built-in structure, similar to DEVCHAN, that contains the DEV structure and an integer referring to a level. Using DEVLEV device,level pairs can be grouped.
179
180
Combining Devices
Combining Devices
Lesson Topics
DEFINE_COMBINE in NetLinx
This definition section allows the combination of functionally identical devices, such as identically programmed Touch Panels and Softwire Panels. When the program references one of these devices, all other combined devices in the set are also referenced. The Master recognizes all devices in the combine list as the first device listed. This will cause any button pushed on any of the touch panels to respond as if that button was pushed on the first touch panel. Operations are programmed to the first device in the combine list. The set of devices, called a combine list, must be enclosed in parentheses. For example:
DEFINE_COMBINE (VPANEL, PANEL1,PANEL2,PANEL3)
NetLinx provides several new methods for combining the functionality of devices. You can combine functionality within mainline by stacking push and release statements. Stacking pushes allows you the flexibility to conditionally change what elements of the program share functionality, but the program can be more difficult to maintain over time than if the panels were combined using DEFINE_COMBINE.
Virtual Devices
NetLinx uses Virtual Devices. Virtual Devices carry a device number ranging from 32,768 to 36,863, a port number of 1, and a system number of 0.
A Virtual Device must be in position 1. (see example above)
Virtual Devices are devices that cannot be taken off the bus. By listing a virtual device as the first device in a DEFINE_COMBINE statement or as the first device in a COMBINE_DEVICES, the abnormalities seen in Axcess DEFINE_COMBINE statements are eliminated.
DEFINE_DEVICE TP=128:1:0 TP2=132:1:0 vTP=33128:1:0 DEFINE_START DEFINE_COMBINE (vTP, TP, TP2)
181
Combining Devices
COMBINE_DEVICES and UNCOMBINE_DEVICES are used as stand-alone statements in an event or mainline or in assignment statements. COMBINE_DEVICES and UNCOMBINE_DEVICES will return a value of 0 or 1 depending on the success or failure of the operation. The first device in a COMBINE_DEVICES statement should be a Virtual Device. The devices, listed after the virtual device, are either a list of individual device numbers, DEV sets or any combination of devices and DEV sets. The UNCOMBINE_DEVICES statement requires only the first device in the COMBINE_DEVICES list, which should be a Virtual Device. The format for COMBINE_DEVICES and UNCOMBINE_DEVICES is:
COMBINE_DEVICES (<virtual device>, <device1>, <device2>) UNCOMBINE_DEVICES (<virtual device>)
Devices combined with COMBINE_DEVICES respond like devices combined using the DEFINE_COMBINE section. The central controller recognizes any input from the devices in the combine list as the first device in the list.
182
Bitwise Operations
Bitwise Operations
Lesson Topics
Bitwise Operators
Bitwise operators perform the same logical operations mentioned earlier, but on a bit-by-bit basis. These operators are BAND, BOR, BXOR, and BNOT. They are similar to logical operators. For example, the keyword BAND performs a logical AND operation between two bytes on a bit-by-bit basis. Instead of producing a true or false result, bitwise operations form a new byte. For example:
X = $A1 BAND $8A
The variable X now equals $8 (see FIG. 1). The AND operation is applied to the first bit of each value (1 and 1), setting the first bit of the result to 1. This is done again for each bit of the values, producing a new byte.
1 0 1 0 0 0 0 1 And 1 0 0 0 1 0 1 0
$A1 $8A
FIG. 1 BAND applies the logical operator And on a bit-by-bit basis. Since both bits are true in the first location, the resulting bit is also true.
Operators in that perform bit-by-bit logical operations on one byte or between two bytes. They are similar to logical operators. For example, the keyword BAND performs a logical AND operation between two bytes on a bit-by-bit basis. These operators are: BAND, BOR, BXOR, BNOT, RSHIFT, and LSHIFT.
183
Bitwise Operations
1 0 0 1
0 0 1 0
BAND 0 0 0 0 = 0 0 0 0 0 0 1 0 0 0 1 0
BOR - Bitwise OR
Uses BOR keyword or | Compares the individual bits of two bytes returns a byte result
1 0 0 1
0 0 1 0
BOR 0 0 0 0 = 1 0 0 1 0 0 1 0 0 0 1 0
184
Bitwise Operations
1 0 0 1
0 0 1 0
BXOR 0 0 0 0 = 1 0 0 1 0 0 0 0 0 0 1 0
185
Bitwise Operations
186
Bitwise Operations
187
Bitwise Operations
Assignment Operators
The assignment operators may appear only once in a single NetLinx statement. Assignment Operators
Operator = ++ -Function Assignment Increment by 1 Decrement by 1
The following rules apply to the use of assignment operators: The "=" operator may be used to assign
Expressions to intrinsic type variables (see Data Types) Arrays to other array of matching size and type Structures to other structures of the same type
The "++" and "--" operators are statements, and cannot appear within expressions. For example:
FOR (I=1; I<10; I++) I = j++; // Legal // Illegal
Operator Precedence
The table below shows the inherent precedence assigned to the operators. As noted in the chart, the NOT (!) operator has the highest precedence in NetLinx systems. Operator Precedence
Level 1 2 3 4 5 6 7 < <= * + > >= & && | || Operators ! ~ / % = == <> ^ ^^ << >> Associability Left To Right Left To Right Left To Right Left To Right Left To Right Left To Right Left To Right
188
TCP/IP Communication
TCP/IP Communication
Lesson Topics
IP Communication
Clients and servers communicate via Internet Protocol (IP) using either a connection-oriented or connection less protocol.
Connection-oriented input/output (I/O) channels require a connection or virtual circuit to be established between the client and server before data can be transmitted or received. Transmission Control Protocol (TCP) is the transport protocol typically used for connection-oriented I/O. With TCP, delivery of the data is guaranteed.
With a connection less I/O, a connection is not established between the client and server before data is exchanged. Instead, the identity of the client and server is established each time data is sent or received. This type of communication is usually recommended for applications that transfer only small amounts of data. User Datagram Protocol (UDP) is the transport protocol used for connection less I/O. With UDP, delivery of the data is not guaranteed.
Both the client and the server must be able to identify incoming and outgoing data for a particular conversation. To achieve this, each application assigns a unique number to the conversation. This number is the local port number. A local port is not a physical port but rather a virtual port on the NetLinx Master that identifies the source or destination for data exchanged during the conversation. Local ports are specific to either the client or the server; they need not match across applications.
The application assigns the number for the local port - as opposed to letting the system assign it (for instance, as the return value for IP_CLIENT_OPEN or IP_SERVER_OPEN) - to satisfy the static nature of DEFINE_EVENT handlers. All event handlers must specify a device, port, and system to identify the events' source. This device information must be constant; that is, it cannot change at run-time. A constant IP device specification can be defined using a local port number. For example:
Device Number = 0 Port = LocalPort System = 0 The master The local port number This system (where the application is running)
189
TCP/IP Communication
A NetLinx Master can maintain up to 200 simultaneous TCP/IP connections. This includes connections to NetLinx Studio, NetLinx Diagnostics, Internet Inside Applications, URL List entries, and Ethernet devices such as the TPI4 and Modero panels.
A range of numbers is reserved for local port numbers to make sure that this IP device-naming convention does not interfere with future naming schemes. The program can only assign local port numbers at or above the value of the keyword, FIRST_LOCAL_PORT. All port numbers below FIRST_LOCAL_PORT are reserved for future use. For example:
DEFINE_CONSTANT PORT_REMOTE_MASTER1 = FIRST_LOCAL_PORT PORT_REMOTE_MASTER2 = FIRST_LOCAL_PORT + 1 PORT_REMOTE_MASTER3 = FIRST_LOCAL_PORT + 2
Server Programming
Listening for Client Requests
A client gains access to a service by sending a request to the server specifying the port assigned to the service. For the request to be acknowledged, the server must be listening on that port. To do this, the server calls IP_SERVER_OPEN. This opens the port and allows the server to listen for requests from client applications.
IP_SERVER_OPEN requires the caller to supply a local port number. This local port number is a virtual port as opposed to an actual physical port on the server. When TCP is the transport protocol, the local port represents a single client connection on the server's physical port. When UDP is the transport protocol, it represents a single point where all client requests on the associated port are routed. Review of Requirements:
An assigned port on the Master IP Port number of the application TCP or UDP to be specified
The local port number is the key to identifying data sent to or received from a client application. A local port number may not be used in another call to IP_SERVER_OPEN until IP_SERVER_CLOSE is called for that port number. The syntax:
IP_SERVER_OPEN(LocalPort, ServerPort, Protocol)
Parameters: LocalPort: The local port number to open. This port number must be passed to IP_CLIENT_CLOSE to close the conversation. ServerPort: The port number on the server identifies the program or service the client is requesting. Protocol: The transport protocol to use (1 = TCP, 2 = UDP). If this parameter is not specified, TCP (1) is assumed.
190
TCP/IP Communication
To support concurrent requests, the server must call IP_SERVER_OPEN once for each simultaneous connection allowed. For example:
IP_SERVER_OPEN (First_Local_Port, 10510, 1) IP_SERVER_OPEN (First_Local_Port+1, 10510, 1) IP_SERVER_OPEN (First_Local_Port+2, 10510, 1)
This allows three simultaneous connections on port 10510. Note that each call to IP_SERVER_OPEN uses a different local port number.
Connection-oriented Notifications
The server receives the following notifications when a client connects or disconnects. The protocol in this case must be TCP.
DATA_EVENT[0:LocalPort:0] { ONLINE: { // client has connected } OFFLINE: { // client has disconnected } }
where Device is (or contains as part of an array) the device representing the conversation (0:LocalPort:0).
191
TCP/IP Communication
Receiving Data
To receive data from a client, use a DATA event handler or a buffer created with CREATE_BUFFER or CREATE_MULTI_BUFFER. If an event handler is used, the data is located in the Text field of the DATA object. The syntax:
DATA_EVENT[0:LocalPort:0] { STRING: { // process incoming string (Data.Text) } }
where Device is (or contains as part of an array) the device representing the conversation (0:LocalPort:0).
Sending Data
To send data to the client, use the SEND_STRING command.
SEND_STRING 0:LocalPort:0, '<string>'
The device specification (0:LocalPort:0) is interpreted as follows: Device Number: 0: The master Port: LocalPort: The local port number System: 0: This system (the client)
Multicast
NetLinx can send and receive multi-cast UDP messages. To send a multi-cast UDP message, all you need to do is specify a multi-cast address and port in the IP_CLIENT_OPEN function such as the following:
IP_CLIENT_OPEN (dvIPClient.Port,'239.255.255.250',1900,2)
To receive multi-cast UDP messages, you must call the IP_MC_SERVER_OPEN function:
IP_MC_SERVER_OPEN (dvIPServer,'239.255.255.250',1900)
The NetLinx master will join the multi-cast session and allow you to receive and transmit UDP multi-cast messages.
192
TCP/IP Communication
Client Programming
Initiating a Conversation
To initiate a conversation with a server, the client must use the IP_CLIENT_OPEN command and supply either the IP address or domain name of the server and a port number for the requested service. The client must also specify a local port number to use for sending and receiving data. This number represents a virtual port on the client machine; it is not the actual port number used to create the client-end socket. A local port number may not be used in another call to IP_CLIENT_OPEN until IP_CLIENT_CLOSE is called for that port number. Review of Requirements:
An assigned port on the Master IP Address or URL of the device or application IP Port number of the application TCP or UDP to be specified
Parameters: LocalPort: A user-defined, non-zero integer value representing the virtual port on the client machine that will be used for this conversation. This port number must be passed to IP_CLIENT_CLOSE to close the conversation. ServerAddress: A string containing either the IP address (in dotted-quad-notation) or the domain name of the server to connect to. ServerPort: The port number on the server that identifies the program or service the client is requesting. Protocol: The transport protocol to use (1 = TCP, 2 = UDP). If this parameter is not specified, TCP (1) is assumed.
Terminating a Conversation
To terminate a conversation you must use the IP_CLIENT_CLOSE command and pass the number of the local port used for the conversation. The syntax:
IP_Client_Close(LocalPort)
Parameters: LocalPort: A user-defined, non-zero integer value representing the virtual port on the client machine that will be used for this conversation
193
TCP/IP Communication
Sending Data
To send data to the server, use the SEND_STRING command.
SEND_STRING 0:LocalPort:0, '<string>'
The device specification (0:LocalPort:0) is interpreted as follows: Device Number: 0: The master Port: LocalPort: The local port number System: 0: This system (the client)
Receiving Data
To receive data from the server use a DATA event handler or a buffer created with CREATE_BUFFER or CREATE_MULTI_BUFFER. If an event handler is used, the data is located in the Text field of the DATA object. The syntax is shown below:
Data[0:LocalPort:0] { STRING: { // process incoming string (Data.Text) } }
Parameters: Device: Is (or contains as part of an array) the device representing the conversation (0:LocalPort:0)
Example IP Code
PROGRAM_NAME='IPExample' (***********************************************************) (* DEVICE NUMBER DEFINITIONS GO BELOW *) (***********************************************************) DEFINE_DEVICE dvIPServer dvIPClient (* DEFINE_CONSTANT TCP_IP nIPPort (* DEFINE_VARIABLE = 1 = 8000 VARIABLE DEFINITIONS GO BELOW *) = 0:2:0 = 0:3:0 CONSTANT DEFINITIONS GO BELOW *)
(***********************************************************) (***********************************************************)
(***********************************************************) (***********************************************************)
194
TCP/IP Communication
IP_ADDRESS_STRUCT MyIPAddress
*) *) *) *) *) *)
(***********************************************************) (* DEFINE_START (* Get My IP Address *) GET_IP_ADDRESS(0:0:0,MyIPAddress) (* Open The Server *) IP_SERVER_OPEN(dvIPServer.Port,nIPPort,TCP_IP) (* Open The Client *) IP_CLIENT_OPEN(dvIPClient.Port,MyIPAddress.IPAddress,nIPPort,TCP_IP) (***********************************************************) (* THE EVENTS GOES BELOW *) (***********************************************************) DEFINE_EVENT (* Server Data Handler *) DATA_EVENT[dvIPServer] { ONERROR: { SEND_STRING 0,"'error: server=',ITOA(Data.Number)" } ONLINE: { SEND_STRING 0,"'online: server'" } OFFLINE: { SEND_STRING 0,"'offline: server'" } STRING: { SEND_STRING 0,"'string: client=',Data.Text" IF (FIND_STRING(Data.Text,'ping',1)) SEND_STRING 0:2:0,"'pong',13" } } (* Client Data Handler *) STARTUP CODE GOES BELOW (***********************************************************)
195
TCP/IP Communication
DATA_EVENT[dvIPClient] { ONERROR: { SEND_STRING 0,"'error: client=',ITOA(Data.Number)" } ONLINE: { SEND_STRING 0,"'online: client'" } OFFLINE: { SEND_STRING 0,"'offline: client'" } STRING: { SEND_STRING 0,"'string: client=',Data.Text" } } (***********************************************************) (* DEFINE_PROGRAM (* Send Ping To Server *) WAIT 50 SEND_STRING dvIPClient,"'ping',13" THE ACTUAL PROGRAM GOES BELOW *) (***********************************************************)
(***********************************************************) (* (* END OF PROGRAM DO NOT PUT ANY CODE BELOW THIS COMMENT *) *)
(***********************************************************)
196
Timelines
Timelines
Lesson Topics
Timelines were originally developed as an improved method for writing show control programs. Timelines are now becoming the preferred method for writing any timed event or repeating sequence.
Timeline Functions
The NetLinx timeline functions provide a mechanism for triggering events based upon a sequence of times. The sequence of times is passed into the timeline functions as an array of LONG values with each value representing a time period (in milliseconds) that is either relative to the start time of the timeline or to the previously triggered event. WAIT (0.01 Second increments) Timers (0.1 Second increments)
GET_TIMER SET_TIMER
Timelines (1 ms increments)
Timelines introduce the capability to dynamically set up a timed sequence, provide the user with a mechanism to modify the sequence, and allow the user to create, delete, and modify sequences.
The old way of programming timed sequences was to cascade or nest WAITs. Using nested WAITs hard-coded the timed sequence so the only way to modify the timing was to modify the NetLinx program, recompile, and download. NetLinx is more accurate
Accurate to 10ms. Timelines are measured in 1ms units. Waits are measured in 10ms units (0.01s) Not affected by mainline if events are used.
197
Timelines
Timelines make adding, deleting and editing the sequence much simpler for the programmer. Timeline functions and debugging allow the timings to be modified without the modify/ compile/ download cycle because the array of times may be modified via NetLinx debugging. Once the timings have been tweaked, the changes can be incorporated in the NetLinx program.
Timelines can operate in two modes: Absolute and Relative. In Absolute Timelines, every event time is based upon the start of the timeline. In Relative Timelines, every event time is based upon the occurrence of the last event.
Creating a Timeline
When creating a Timeline you need to list the sequence of events that include: Order of the sequence. Duration of each event. Interdependence of events.
If one event cant start before another one finishes make sure to note that.
Then, you will want to draw your timeline. Next, you will want to convert the information from the drawing to a list of times. Time can be specified as absolute or relative: Absolute
LONG TIMES[]={0,200,500,12000,27000,45000}
Relative
LONG TIMES[]={0,200,300,11500,15000,18000}
How long can a timeline run? Absolute timeline can run for more than 49 days without repeating! Relative timelines can run for more than 8900 years without repeating!
198
Timelines
Timeline Keywords
Timelines are created and begin when the TIMELINE_CREATE command is executed.
TIMELINE_CREATE ( id, tl_array[], count, tl_mode, tl_repeat )
Where:
id is unique constant that is used to reference the timeline tl_array is a single dimensional LONG array of the timeline times count is the number of events to be run in the timeline. Typically count is equal to the
Times Array
An array of LONG INTEGER values representing when the events should begin.
Length
Type
Two keywords are provided to indicate the type of values in the Times Array:
TIMELINE_RELATIVE TIMELINE_ABSOLUTE
Repeat
TIMELINE_ONCE TIMELINE_REPEAT
199
Timelines
Timelines can be stopped with the TIMELINE_KILL command. When a timeline is killed, it is no longer running and no longer active.
TIMELINE_KILL ( id )
Timelines can be paused and restarted using the TIMELINE_PAUSE and TIMELINE_RESTART commands. Pausing a timeline keeps the timeline active and maintains the current location within the timeline sequence, similar to pausing a VCR or DVD.
TIMELINE_PAUSE ( id ) TIMELINE_RESTART ( id )
Anytime the TIMELINE_CREATE command is executed the tl_array values are reread. Since tl_array is a variable, values can easily be adjusted and updated. tl_array values can also be adjusted and updated dynamically while the timeline is active and running using the TIMELINE_RELOAD command. If the timeline is currently running when the command is issued the new array of times takes affect immediately. The next matching time from the new time array triggers the next TIMELINE_EVENT.
TIMELINE_RELOAD cannot change the mode of the timeline or the repeat status. TIMELINE_RELOAD can adjust the tl_array times and the number of events in the timeline. There are several commands that will return the status of a timeline outside the context of an array event.
TIMELINE_ACTIVE will return a value of 1 if the timeline is currently running and a value of 0 if the timeline is currently stopped.
TIMELINE_ACTIVE ( id )
TIMELINE_GET returns the current timer value. TIMELINE_GET returns an absolute time value based upon the start of the timeline, and returns a LONG value in milliseconds.
TIMELINE_GET ( id )
TIMELINE_SET changes the value of the timer. Like TIMELINE_GET, TIMELINE_SET is an absolute time and is a LONG value based upon the start of the timeline.
TIMELINE_SET( id, value )
200
Timelines
Timeline Keywords
TIMELINE_ACTIVE This function is used to determine if a timeline has been created. If the timeline does not exist (i.e. TIMELINE_CREATE has not been called) this function returns zero. INTEGER TIMELINE_ACTIVE(LONG Id) Parameters: Id: A user defined value that uniquely identifies this timeline. Each timeline must be assigned a unique identifier starting with number one. Returns: 0: Not created Non-zero: The timeline has been created IF(TIMELINE_ACTIVE(TL1)) // if timeline 1 is running{// do something} TIMELINE_CREATE Creates an initial timeline and specifies the attributes of the timeline. INTEGER TIMELINE_CREATE(LONG Id, LONG Times[ ],LONG Length, LONG Relative, LONG Repeat) Parameters: Id: A user defined value that uniquely identifies this timeline. Each timeline must be assigned a unique identifier starting with number one. Times: An array of times where each time specifies when a TIMELINE_EVENT will be triggered. The times in the array may be relative to each other or relative to the start of the timeline depending upon the Relative parameter. For an absolute timeline it is NOT necessary for the times in the array to be sorted in any particular order (the NetLinx master does this internally for you). The NetLinx master makes an internal copy of the values in the array allowing the user to modify the passed in array as desired without affecting the operation of the timeline. Length: The count of times in the Times array. Relative: Indicates whether the Times array contains relative times or absolute times. Relative indicates the each time given is relative to the last event time (i.e. the time delay in between the triggered events). Absolute indicates that each time given is absolute with respect to the start of the timeline. Repeat: Indicates whether the timeline should automatically start over again when Length events have been triggered. TIMELINE_EVENT These events are generated when a timeline's internal timer is equal to one of the specified times in the times array. The TIMELINE_EVENT must be placed in the DEFINE_EVENT section of the program. TIMELINE_EVENT[timelineID] See the TIMELINE_CREATE function for a more detailed description.
201
Timelines
TIMELINE_GET
This function returns the value of the specified timeline's timer. The timer indicates the number of milliseconds that have passed since the timeline started. If the timeline is paused the timer is also paused and subsequent calls to TIMELINE_GET will return the same value. LONG TIMELINE_GET (LONG Id) Parameters: Id: A user defined value that uniquely identifies this timeline. Each timeline must be assigned a unique identifier starting with number one. This function returns the specified timeline's internal timer. The timer value represents the number of milliseconds that have passed since the timeline started. TIMELINE_SET (TL1,TIMELINE_GET (TL1)+1000) // jump ahead 1 second
TIMELINE_KILL
This function is used to terminate a timeline. Any further references to the specified timeline ID are invalid. INTEGER TIMELINE_KILL(LONG Id) Parameters: Id: A user defined value that uniquely identifies this timeline. Each timeline must be assigned a unique identifier starting with number one. Result: 0: Successful 1: Specified timeline ID invalid TIMELINE_KILL(TL1) // permanently destroy the timeline
TIMELINE_PAUSE
This function is used to suspend the execution of a timeline. It may be restarted from where it left off with the TIMELINE_RESTART function. INTEGER TIMELINE_PAUSE(LONG Id) Parameters: Id: A user defined value that uniquely identifies this timeline. Each timeline must be assigned a unique identifier starting with number one. Result: 0: Successful 1: Specified timeline ID invalid TIMELINE_PAUSE(TL1) // momentarily suspend the timeline
202
Timelines
TIMELINE_RELOAD
This function is used to change the array times of a timeline. The new array of times takes affect immediately even if the timeline is currently executing. If the timeline is executing when this function is called the timeline continues to execute and the next matching time from the new array triggers an event. INTEGER TIMELINE_RELOAD(LONG Id, LONG Times[],LONG Length) Parameters: Id: A user defined value that uniquely identifies this timeline. Each timeline must be assigned a unique identifier starting with number one. Times: An array of times where each time specifies when a TIMELINE_EVENT will be triggered. The times in the array must utilize the same time base (TIMELINE_RELATIVE or TIMELINE_ABSOLUTE) as determined by the original call to TIMELINE_CREATE. The NetLinx master makes an internal copy of the values in the array allowing the user to modify the passed in array as desired without affecting the operation of the timeline. Length: The count of times in the Times array. Result: 0: Successful 1: Timeline ID already in use 2: Specified array is not an array of LONGs 3: Specified length is greater than the length of the passed array 4: Out of memory TimeArray[1] = 1000TimeArray[2] = 1500TimeArray[3] = 2000TIMELINE_RELOAD(TL1,TimeArray,3) // Modify the timeline
TIMELINE_RESTART
This function is used to continue execution of a timeline that was suspended with TIMELINE_PAUSE. INTEGER TIMELINE_RESTART(LONG Id) Parameters: Id: A user defined value that uniquely identifies this timeline. Each timeline must be assigned a unique identifier starting with number one. Result: 0: Successful 1: Specified timeline ID invalid TIMELINE_RESTART(TL1) // continue the timeline
TIMELINE_SET
This function is used to modify the current timer value of a timeline. The timeline's timer is immediately set to the new value regardless of whether the timeline is executing or not. INTEGER TIMELINE_SET (LONG Id, LONG Timer) Parameters: Id: A user defined value that uniquely identifies this timeline. Each timeline must be assigned a unique identifier starting with number one. Timer: The new value for the timeline's internal timer. Result: 0: Successful 1: Specified timeline ID invalid 2: Specified timer value out of range TIMELINE_SET (TL1,0) // start it over again
203
Timelines
TIMELINE_EVENTs
Timelines are represented by the illustration in (FIG. 6). When the TIMELINE_CREATE function is executed, the timeline starts at zero and begins counting. When the timer value equals a value in the TIMES array, a TIMELINE_EVENT is triggered. Within the timeline event, a TIMELINE structure is available to get information about the specific time from the TIMES array that generated the event. When a relative timeline is created, the NetLinx Master converts the provided relative times into absolute times that are stored internally.
TIMELINE_EVENT[TL1]
Triggered
TIMELINE_CREATE
Time 0
1000
5000
Timeline.Sequence =
TIMELINE_EVENT does not have any subevents or clauses. The events within TIMELINE_EVENT can be tracked using the data objects present within the event.
204
Timelines
Returns:
0 1 2 3 4 Successful Timeline ID already in use Specified array is not an array of LONGs Specified length is greater than the length of the passed array Out of memory
Example:
DEFINE_VARIABLE LONG TimeArray[100] DEFINE_CONSTANT TL1 = 1 TL2 = 2 DEFINE_EVENT TIMELINE_EVENT[TL1] // capture all events for Timeline 1 { switch(Timeline.Sequence) // which time was it? { case 1: { SEND_COMMAND dvPanel,"'TEXT1-1 1'" } case 2: { SEND_COMMAND dvPanel,"'TEXT1-1 2'" } case 3: { SEND_COMMAND dvPanel,"'TEXT1-1 3'" } case 4: { SEND_COMMAND dvPanel,"'TEXT1-1 4'" } case 5: { SEND_COMMAND dvPanel,"'TEXT1-1 5'" } } } TIMELINE_EVENT[TL2] { switch(Timeline.Sequence) { case 1: { SEND_COMMAND dvPanel,"'TEXT2-2 1'" } case 2: { SEND_COMMAND dvPanel,"'TEXT2-2 2'" } case 3: { SEND_COMMAND dvPanel,"'TEXT2-2 3'" } case 4: { SEND_COMMAND dvPanel,"'TEXT2-2 4'" } case 5: { SEND_COMMAND dvPanel,"'TEXT2-2 5'" } } } DEFINE_PROGRAM PUSH[dvPanel,1] Continued
205
Timelines
{ TimeArray[1] = 1000 TimeArray[2] = 2000 TimeArray[3] = 3000 TimeArray[4] = 4000 TimeArray[5] = 5000 TIMELINE_CREATE(TL1, TimeArray, 5, TIMELINE_ABSOLUTE, TIMELINE_REPEAT) } PUSH[dvPanel,2] { TimeArray[1] = 1000 TimeArray[2] = 1000 TimeArray[3] = 1000 TimeArray[4] = 1000 TimeArray[5] = 1000 TIMELINE_CREATE(TL2, TimeArray, 5, TIMELINE_RELATIVE, TIMELINE_ONCE) }
The example above creates two timelines (TL1 and TL2) that trigger events at the same rate (once per second).
TL1 uses TIMELINE_ABSOLUTE to specify that the times in TimeArray are absolute
with respect to the start of the timeline. Since TL1 specifies the TIMELINE_REPEAT, it is also repeating and will generate a TIMELINE_EVENT every second iterating through all five times in a round-robin fashion: 1,2,3,4,5,1,2,3,4,5,1,2,3, and so on.
TL2 uses TIMELINE_RELATIVE to specify that the times in TimeArray are relative to
each other (i.e. each events occurs 1000 milliseconds after the previous). Since TL2 specifies the TIMELINE_ONCE parameter, it will execute the entire timeline once, then stop: 1,2,3,4,5.
206
Master to Master
Master to Master
Lesson Topics
The functionality of master-to-master (M2M) includes several new features including master routing and intersystem control. Master routing supports the ability to route messages to any other master or device and is the foundation of all M2M functionality. Intersystem control allows a master, or its NetLinx program, to control and get status of any other device (or master) that is connected to any other master.
FIG. 1 depicts a typical system of two interconnected NetLinx Control Systems with several devices connected to each one. The top portion of the illustration shows the physical connections and the devices represented. The bottom portion shows the logical connections that have been assigned.
Physical Connections Ethernet Infrastructure
10/100Mb Ethernet
10/100Mb Ethernet
NetLinx Studio
ICSNet AXlink 10/100Mb Ethernet AXlink ICSNet
S=7 D=32002
NetLinx Studio NetLinx Cardcage S=1 D=1-12 AXlink Touchpanel S=1 D=128 System #1
S=7 D=32002
AMX Installer
207
Master to Master
Master Routing
The implementation of master routing primarily involves the communication of routing tables between masters. Routing tables are exchanged between masters upon their initial connection and updates to the routing tables are exchanged as the connections change.
NetLinx masters do not automatically connect to other NetLinx masters by virtue of being on the same network. The URL List of the NetLinx master is used to force the master to initiate a TCP connection to the specified URL/IP address. Therefore, the first step in assembling an M2M system is to setup the URL in at least one of the masters to point to the other master. For example, in FIG. 1 NetLinx Master System #1 could have its URL set with a single entry that contains the IP address of the NetLinx Master System #7.
Note that any TCP/IP device, including NetLinx masters, which utilize DHCP to obtain its TCP/IP configuration are subject to having their IP address change at any time. Therefore, NetLinx masters IP address must be static unless the network supports Dynamic DNS AND a DHCP server capable of updating the DNS tables on behalf of the DHCP client. If Dynamic DNS/DHCP server are available then the NetLinx masters host name may be used in the URL list. As of this writing, the author is aware that only Windows 2000s DNS server/DHCP servers support the required dynamic capabilities.
Once the systems are connected to each other they exchange routing information such that each master will learn about all the masters connected to the other. Consider the following system of interconnected NetLinx masters:
The arrows depict the direction of the initiated connection. For example System #1 initiated the connection to System #2 by having the IP address of System #2 in its URL List.
208
AMX Installer
Master to Master
As a diagnostic aid, the "show route" command can be issued from a telnet session to show how masters are connected to each other.
>show route Route Data: System Route Metric PhyAddress -------------------------------1 2 3 4 -> 5 106 111 2 2 2 4 5 106 106 2 1 2 1 0 1 2 TCP Socket=18 IP=192.168.12.76 Index=3 TCP Socket=18 IP=192.168.12.76 Index=3 TCP Socket=18 IP=192.168.12.76 Index=3 TCP Socket=16 IP=192.168.12.80 Index=1 AXlink TCP Socket=19 IP=192.168.12.106 Index=2 TCP Socket=19 IP=192.168.12.106 Index=2
The "->" to the left of system number 5 indicates that system number 5 is the local system (i.e. the system that the telnet session is connected to). The System column lists all of the systems that are in the masters routing table. The Route column indicates which system number packets are to be routed to in order to get to the destination. For example, to send a message from system #5 to system #1 the message must be sent to/through system #2. You can see this visually in Illustration 2 or by examining the Route entry for System #1 in the "show route" table.
The Metric column indicates the number of system masters that the message must transverse in order to get to its destination. In FIG. 2, the metric is 2 because the message must enter system #2, then system #1. Note that a metric of 16 indicates a "dead" route (i.e. a "dead" route is a route that used to exist but is no longer valid). Further, since the maximum usable metric is 15 there is a limit of 16 masters in the width plus height of the master topology (see section 2.1.1 Design Considerations and Constraints).
The PhyAddress column indicates the internal connection parameters used by the master to maintain the connection information.
The end result of all this routing and connection data is that any device or master can communicate with any other device or master regardless of the physical connection of the device. Note that masters may only be "connected" to each other via Ethernet/TCP/IP. As an example (using FIG. 1), NetLinx Studio is running on a PC that is connected to System #7 as device number 32002. The routing capabilities of the NetLinx master allow NetLinx Studio to download IR codes to the NXCIRS4 (S=7 D=24), download a master firmware upgrades to NetLinx master #1, and download new touch panel pages to the touch panel on master #1. All of this is possible simply by having NetLinx Studio connected to a NetLinx master with M2M firmware.
AMX Installer
209
Master to Master
When determining the interconnection topology of many NetLinx masters, special consideration should be made to have masters that communicate much information with each other to connect to each other. Thus if you have two systems that share devices, control, or information they should be side-by-side in the topology and not at opposite ends of the connection matrix where each message is forced to pass through several NetLinx masters. FIG. 3 displays 20 systems connected in a linear fashion. Unfortunately for this design, if the program in Master 1 needed to control a device on Master 17, the message would be discarded by Master 16 since the message would have traversed through 15 masters thus exceeding the 15 hop limit.
M1
M2
M3
M4
M5
M6
M7
M8
M9
M 10
M 20
M 19
M 18
M 17
M 16
M 15
M 14
M 13
M 12
M 11
The 15 hop limit can easily be remedied by adding a connection between Master 1 and Master 20 (adding an entry for one master in the URL list of the other).
M1
M2
M3
M4
M5
M6
M7
M8
M9
M 10
M 20
M 19
M 18
M 17
M 16
M 15
M 14
M 13
M 12
M 11
On the following page an example of radial topology is shown (FIG. 5). This indicates how more than 64,000 masters can be connected using only 40 entries in each URL list and limiting the number of hops between any Master to 6 or less.
210
AMX Installer
AMX Installer
Master 1,642
62,319 Systems 40 Systems
Master 1,682
Master 64,001
40 Systems
Master 64,041
Master 43
40 Systems
Master 83
1,518 Systems
Master 1,601
40 Systems
Master 1,641
Master 2
40 Systems
Master 42
Each system has 40 systems connected to it. In 6 hops or less any master can communicate to any other master.
Master 1
Master to Master
211
Master to Master
When NetLinx Studio connects to a single master, yet allows the user to access all other system masters, some confusion will occur. Therefore, it is a good idea to document each system's, number and the topology of the interconnections.
212
AMX Installer
The 4 Cs
The 4 C's of control are the Control Destination, Control Link, Control Port, and Control Function. All four parts must be present for a Control System to function properly.
Types of Control
Contact closure IR and wired serial RF Volume Voltage Serial (RS232-422-485) Miscellaneous types Contact Closure Contact closures are an on-off switch in an electrical circuit. Momentary- the relay only closes for a moment then goes back to the open position Latching- the relay remains in either a closed or an open position Discrete - multiple relays are incorporated together for unique functions Toggle - one relay performs multiple functions
213
IR Infrared remote control generates light pulses in specific patterns unique to each device. The optical range is 30-40 feet from the controlled device. Wired IR Communicates by sending pulses through a wire in specific patterns unique to each device RF In an AMX control system RF (Radio Frequency) is used for communications between user interfaces and a control system. Frequencies for transmitter/receiver pairs are preset at the factory. Radio codes can be selected by the installer in the field. Volume Volume control occurs by placing a variable resistance on the incoming signal by either increasing or decreasing the amount of signal going to the device. Voltage (Analog) For Voltage control, the control system generates a voltage between a high end and low set points to control the movement or level of a device. Serial Definitions (Digital) Serial Control - two-way communication between the Control System and the Control Destination Single-ended Serial - connects only one transmitter to one receiver Broadcast - allows one transmitter to send messages to multiple receivers at the same time. Multi-drop - allows more than one transmitter and receiver to share the same physical wires simultaneously without interfering with each other's messages. Full Duplex - sends and receives data at the same time and requires separate wires for receiving and transmitting data.
Half Duplex - can only send or receive data at one time. Handshaking - ensures that the receiving device is ready to receive the data before the data gets sent. Baud Rate - the number of bytes per second that are transferred across an interface. Parity - is used to detect data corruption that may occur during transmission. Start and Stop Bits - identify the beginning and ending of a data word. Word Length - data can be sent in 5,6,7, or 8 bit increments. Serial (RS232/RS422/RS485) RS232 - connects only one transmitter and receiver (single-ended). Maximum run length of 50 feet RS422 - serial digital interface standard that uses a balanced data signal (reduces interference) to allow long runs with no perceived degradation of signal quality (single-ended or multi-drop). Maximum run length of 4000 feet RS485 - uses a balanced data signal to reduce interference, which allows long runs with no perceived degradation of signal quality (multi-drop). Maximum run length of 4000 feet Miscellaneous Types of Control MIDI - provides a standardized and efficient means of conveying musical performance information as electronic data DMX512 - lighting system control protocol X10 - modulated data signal on a 110 VAC power circuit DTMF - telephone keypad signaling tones in which each key produces a slightly different signal
214
Central Controllers
The Central Controller is a shell, which contains the Master Processor and Device Controllers. The Central Controller can come in several forms including a CardFrame, NXI, or the NI series. Master Processor The Master Processor, sometimes referred to as the brain of the system, is the programming memory and network manager for the entire system. It recognizes what button the user pushes then triggers the requested event. It can also provide the security for a Control System. Hubs
User Interface
The user interfaces are the components of the Control System that allow people to interact with the control system.
Panel Sizes Touch panels come in many different sizes to help make your control system have the look and function you want and need. The sizes that the AMX touch panels come in are:
4" 6" 7" 7.5" 8.4" 12" 15" 17"
To assist the Master Processor manage the control networks AMX has developed several network Hub Cards. These Hub Cards extend the distance or number of network connections of the Master Processor. The Hub Cards can be installed in NetLinx CardFrames, NXIs, or in NXS-MHS (NetLinx Master/ Hub Module).
Device Controllers
Device Controllers act as a bridge that allows AMX control technology to interact with virtually any device or system. It receives a signal, translates the command, and then directs it to the appropriate device. Device controllers are Control Cards for the CardFrame or control ports on the Integrated Controllers.
Displays There are many different types of displays which include various options for colors, audio, video, etc.
Color Passive Color Active Color Graphic Color Video NXP-TPI/4 G3 G4
Panel Packages Different packages are available depending on where the display is needed.
Table Top Rack Mount Touch Panel Monitor ViewPoint Flush Mount
215
Accessories
Accessories are devices that support the control system. Some examples include: Power Supplies Sensors
Power Current Sensor Dual Power Current Sensor Video Sync Sensor Room Temp Sensor TV Sensor
Software Solutions
MeetingManager is a meeting room management and monitoring software package PictureFrame allows you to transform any of the Modero panels into dynamic digital photo albums Platinum Series Solutions are a series of integration solutions perfect for controlling Presentation Rooms, Entertainment, and Education G4 Web Control allows an AMX G4 User Interface to be remotely controlled by any computer on the control network G4 Computer Control gives you full access to any computer from an AMX Touch Panel Internet Inside Applications combine the dynamics of NetLinx with the features of the World Wide Web
Surge Protection
System Tools
STS IRIS Ethernet Crossover Adapter Programming Cables Rack Kits
Hardware Solutions
MAX Integrated Content Servers designed to store, manage, instantly locate and play audio and video. Consists of Integrated Music Server, Backup Storage Module, Multi-Media Server, and Audio/Video Module. Lighting AMX offers two solutions for lighting needs; Radia and Lutron. Radia is more often used as the solution for commercial applications, while Lutron provides an ideal solution for Residential needs. Volume Control Device Controller in the form of a card that provides 4 line-level audio volume channels. Camera Control AMX offers camera controllers in the form of the PosiTrack Pilot and camera positioning controllers such as the PosiTrack pan/tilt heads. Temperature Control The ViewStat Communicating Thermostat offers complete digital thermostat functionality, including the ability to schedule automatic temperature adjustments throughout the day, control relative humidity levels and power outage protection. Switchers AMX offers a video switcher, the PLH-VS8 which is an 8X8 Composite Video Switch with 8 VSS inputs. Audio AMX also has an audio switcher, the PLB-AS8 that routes eight stereo line-level audio inputs to eight stereo line-level outputs.
216
Addressing
There are two main types of addresss; MAC and IP. A MAC (Media Access Control) address is a unique hardware number. This address is physical. The second type of address is virtual, this the IP address (Internet Protocol). An IP address is a unique identifier for a host connection on an IP network. . IP Address: 204.169.48.4 PHYSICAL LOGICAL ADDRESS ADDRESS MAC Address: 00-60-9F-10-05-D3
Ethernet
Ethernet is the most widely installed local area network technology. The most commonly installed Ethernet systems are called 10BaseT or 100BaseT and provide transmission speeds up to 10 or 100 Mbps. Your actual speed will be determined by the amount of traffic on the network. AMX uses 10/100BaseT Ethernet running TCP/IP to connect NetLinx systems to other NetLinx systems or other Ethernet controlled devices.
There are two ways to assign an address to a device, static and dynamic. A static address is a permanent address. Dynamic addresses are temporary and are assigned by using the Dynamic Host Configuration Protocol also referred to as DHCP. A process called subnetting divides the single IP address of the main network into multiple addresses for the subnet. DNS enables Internet clients and hosts to refer to one another using human-readable names like www.company.com, rather than IP addresses like 12.5.139.189
What does 10/100BaseT Ethernet tell us about the network? The network topology - either star or hybridstar network The required cable rating - 10/100BaseT networks will typically require CAT5 Unshielded Twisted Pair cable (UTP) The type of connectors - RJ45 The speed of the network - 10/100 Mbps The signal type - Baseband signal The type of cabling - twisted-pair
CAT5 Currently CAT5 cable is the minimum standard for AMX network implementation. It has a nominal impedance of 100 ohms.
217
Ping - lets you verify that a particular IP address exists and can accept requests Tracert - records the route through the Internet between your computer and a specified destination IPConfig- used to view TCP/IP configuration of your computer
Gateway - a hardware and software combination that connects a network to an unrelated network. Firewall protects the resources of a private network from users coming from other networks TCP/IP Utilities To test the IP connectivity when using TCP/IP on the network there are several utilities to help you do this:
218
AXlink
AXlink is a proprietary communication protocol designed by AMX. All Axcess devices are connected with AXlink. AXlink can connect up to 255 devices provides data at 20 Kbps the total cable length within an AMX system is 3,000 feet or 914 meters AXlink Cabling Specifications AXlink can use a variety of wire gauges and standards and can be wired in series or parallel.
3 4
ICSNet
ICSNet is used to distribute communications between the NetLinx Master and other NetLinx and Landmark devices. The key difference between ICSNet and ICSHub is that ICSNet will provide power to connected devices. ICSNet connects up to 32,000 devices to the NetLinx master provides data at 625 Kbps provides 12 VDC
219
power to remote ICSNet devices supports up to 500ma loads per cable run total cable run length of 1000 feet or 300 meters from the NetLinx Master or Net Hub ICSNet Cabling Specifications Unlike ICSHub, ICSNet is not considered directional, so you can plug in ICSNet from any ICSNet port to any other ICSNet port. category 5 (or greater) cabling and RJ45 connectors should be wired to the EIA/TIA 568B standard all runs must be terminated ICSNet Pinout Information Pin 1 2 3 4 5 6 7 8 Transmit + Transmit Not used Ground 12 VDC Not Used Receive Receive +
ICSHub Cabling Specifications ICSHub is directional, ICSHub Out must be connected to an ICSHub In port on another device. category 5 (or greater) cabling and RJ45 connectors should be wired to the EIA/TIA 568B standard correct pairing must be observed
Ethernet
10/100Base T Ethernet is a widely used computer networking standard. 10/100 BaseT Ethernet provides an economical and flexible medium for Local Area networks (LANs). Ethernet... communicates at 10Mpbs or 100 Mbps does not carry power the total cable length within an AMX system is 328 feet or 100 meters Ethernet Cabling Specifications Ethernet networks typically use Category 5 cabling and are terminated using RJ-45 connectors. Changes in the layout of cabling can effect the overall performance of the client's network. NetLinx uses the TCP/IP suite of protocols. The client's IT department must be consulted for network addressing information. You will also need to make arrangements through the IT department if the NetLinx system needs to be accessed from outside the local area network.
ICSHub
The ICSHub network is used to connect a NetLinx Master to NetLinx Hub devices and connects hubs to hubs. ICSHub, unlike ICSNet, does not provide power to connected devices. ICSHub provides data at 625 Kbps requires a local power supply ICSHub is regenerated at each NetLinx Hub card for a maximum of 1000 feet or 300 meters between each hub.
220
Appendix - Keywords
Appendix - Keywords
This is a list of all AMX programming keywords.
#DEFINE #END_IF_ #IF_DEFINED #IF_NOT_DEFINED _DATE_ _FILE_ _LDATE_ _LINE_ _NAME_ _TIME_ _VERSION_ ACTIVE AND( && ) ATOI BAND( & ) BNOT( ~ ) BOR( | ) BREAK BUTTON_EVENT BXOR( ^ ) CALL CANCEL_ALL_WAIT CANCEL_ALL_WAIT_UNTIL CANCEL_WAIT CANCEL_WAIT_UNTIL CASE CHANNEL_EVENT CHAR CLEAR_BUFFER COMBINE_CHANNELS COMBINE_DEVICES COMBINE_LEVELS COMMAND COMPARE_STRINGS CONSTANT CREATE_BUFFER CREATE_LEVEL CREATE_MULTI_BUFFER DATA_EVENT DATE DAY DEFINE_PROGRAM DEFINE_START DEFINE_TOGGLING DEFINE_TYPE DEFINE_VARIABLE DEV DEVCHAN DEVICE_ID DEVICE_ID_STRING DEVLEV DO_PUSH DO_RELEASE DOUBLE ELSE EXTERNAL_CONTROL FIND_STRING FIRST_LOCAL_PORT FLOAT FOR GET_BUFFER_CHAR GET_MULTI_BUFFER_STRING GET_PULSE_TIME GET_TIMER HOLD IF INCLUDE INTEGER ITOA ITOHEX LDATE LEFT_STRING LENGTH_STRING LEVEL_EVENT LOCAL_VAR LONG LONG_WHILE LOWER_STRING LSHIFT MASTER_SLOT MASTER_SN MEDIUM_WHILE PAUSE_ALL_WAIT PAUSE_WAIT PERSISTENT PROGRAM_NAME PULSE PUSH PUSH_CHANNEL PUSH_DEVCHAN PUSH_DEVICE RANDOM_NUMBER REDIRECT_STRING RELEASE RELEASE_CHANNEL RELEASE_DEVCHAN RELEASE_DEVICE REMOVE_STRING REPEAT RESTART_ALL_WAIT RESTART_WAIT RETURN RIGHT_STRING RSHIFT SELECT...ACTIVE SEND_COMMAND SEND_LEVEL SEND_STRING SET_LENGTH_STRING SET_PULSE_TIME SET_TIMMER SINTEGER SLONG STACK_VAR STRING STRUCTURE SWITCH...CASE SYSTEM_CALL SYSTEM_NUMBER SYSTEM_RESET TIME TIMED_WAIT_UNTIL TO
221
Appendix - Keywords
DEFAULT DEFINE_CALL DEFINE_COMBINE DEFINE_CONNECT_LEVEL DEFINE_CONSTANT DEFINE_DEVICE DEFINE_EVENT DEFINE_FUNCTION DEFINE_LATCHING DEFINE_MODULE
TOTAL_OFF UNCOMBINE_CHANNELS UNCOMBINE_DEVICES UNCOMBINE_LEVELS UPPER_STRING VOLATILE WAIT WAIT_UNTIL WHILE WIDECHAR XOR( ^^ )
DEFINE_MUTUALLY_EXCLUSIVE OR( || )
222
Data Type
DEVCHAN DEV INTEGER INTEGER INTEGER INTEGER LONG DEV INTEGER INTEGER INTEGER
Description
[device,channel] Device (d:p:s) Device Number Device Port Number Device System Number (not zero) Channel Number Current Hold Time (milliseconds) Source device of button event Source device number Source device port Source device system. If the event handler is specified using an array for DEV,CHANNEL, or a DEVCHAN array, GET_LAST can determine which index in the array caused the event to run.
Data Type
DEV INTEGER INTEGER INTEGER INTEGER DEV INTEGER INTEGER INTEGER
Description
Device (d:p:s) Device Number Device Port Number Device System Number (not zero) Channel Number Source Device of Channel Event Source Device Number Source Device Port Source Device System. If the event handler is specified using an array for DEV, CHANNEL, or a DEVCHAN array, GET_LAST can be used to determine which index in the array caused the event to run.
Data Type
DEV INTEGER INTEGER INTEGER LONG DEV INTEGER INTEGER INTEGER CHAR Array CHAR Array
Description
Device (d:p:s) Device Number Device Port Number Device System Number (not zero) Event Number Source Device of Data Event Source Device Number Source Device Port Source Device System Text associated with IP address Text associated with the event
Continued
223
Data Type
DEVCHAN DEV INTEGER INTEGER INTEGER INTEGER Numeric DEV INTEGER INTEGER INTEGER
Description
[device,channel] Device (d:p:s) Device Number Device Port Number Device System Number (not zero) Level Number Level Value Source Device of Level Event Source Device Number Source Device Port Source Device System
Data Type
INTEGER INTEGER CHAR array INTEGER INTEGER
Description
ID of Timeline Indexed Sequence of Event Time the event occurred Set if the timeline is relative Number of times the timeline has repeated (starting at 0)
224
Appendix - IR Functions
Appendix - IR Functions
Hand Control IR Functions - Standard Order
Function
1 2 3 4 5 6 7 8
Description
play > stop [ ] pause I I or still ffwd >> rewind <<
Function
22 23 24 25 26
Description
channel up or + channel down or volume up or + volume down or mute on (power typically) Discrete ON off (power typically) Discrete OFF TV/Video or TV/VCR or TV/LDP (one button source selection) TV Video1, LineA, VCR1, VDP, or input + Video2, Line B, VCR2, or input Video3 RGB1 or Tape1 RGB2 or Tape2 CD tuner phono aux AM/FM play < (play reverse) A/B
search fwd >>I (AMS music 27 search fwd for CD) search rev I<< (AMS music search fwd for CD) record 28 29
9 10 11 12 13 14 15 16 17 18 19 20 21
power or on/off 0 or 10 1 (channel digits or tracks for CD) 2 3 4 5 6 7 8 9 +10 (for CD players typically) enter (used in conjunction with numbers typically)
30 31 32 33 34 35 36 37 38 39 40 41 42
225
Appendix - IR Functions
226
227
228
Terminal setup and security configuration is still valid and supported in the new build of NetLinx Master firmware. New Terminal security features include the use of two new commands: ssl security enable and ssl security disable.
SSL (Secure Sockets Layer) is a protocol that works by encrypting data that is transferred over the SSL connection. URLs that require an SSL connection begin with https: instead of http: in the browsers Address field. These security capabilities are configured to function via a web session within your browser.
After the installation of build 130 or higher to your Master, Telnet security configuration access is disabled. This new build migrates the NetLinx Master security setup from a TELNET environment to a web-based application.
The new NetLinx Web Server used to power the Master security and SSL certificate features on AMX Masters, not only provides user name/password security for the target Master, but also a new level of secure encryption through the use of a unique server certificate.
The first layer of security for the Master is an on-screen HTTP user name and password field that prompts a user to provide correct security information before gaining access to a target Master. The second layer of protection is an SSL Certificate (specifically identifying the target Master) that can either be requested or self-generated. This certificate is then installed onto the target Master and added to the trusted site certificate listing within the computers Internet browser.
229
NetLinx Security web browser and feature support The following table describes the web browsers (associated to each operating system) recommended for use with the new NetLinx Security features on the NXC-ME260. Supported Browser and Feature Compatibility
OS Platform Windows Recommended Browser Internet Explorer 6.0 or higher Safari - (see note below) Mozilla NetLinx Security Feature support Yes G3 Web Panel Control support Yes Sun Java must be installed Yes Yes - (see note below) Yes No G4 Web Panel Control support Yes
MAC Linux
When using Safari on a MAC machine, certificates must be externally requested from the Server Certificates page. Self-generated certificates do not allow access back to the target Master and will display an invalid certificate message.
The migration from a Telnet session to the use of an HTTP web browser allows a user to fully utilize the latest SSL encryption features available within the newest release of NetLinx Master firmware.
230
User Administrator
A user is a single potential client of the NetLinx Master. An administrator has privileges to modify existing NetLinx Master access groups, users, and their rights. The administrator can also assign NetLinx communication access rights for different users or groups (ex: Telnet and HTTP access) and configure the SSL server certificate. A group is a logical collection of users. Note that any properties possessed by groups (ex: access rights, directory associations, etc.) are inherited by all of the members of the group. A user name is a valid character string (4 - 20 alpha-numeric characters) defining the user. This string is case sensitive. Each user name must be unique. A group name is a valid character string (4 - 20 alpha-numeric characters) defining the group. This string is case sensitive. Each group name must be unique. A password is a valid character string (4 - 20 alpha-numeric characters) to supplement the user name in defining the potential client. This string is also case sensitive. Each of the NetLinx Master features has security procedures defined for them. The access right for a particular feature determines if the user or group will have access to the feature. A Directory Association is a path that defines the directories or files a particular user or group can access via the Web Server on the NetLinx Master. This character string can range from 1 to 128 alpha-numeric characters. This string is case sensitive. This is the path to the file or directory you want to grant access.
Group
Access Rights
Directory Associations
231
WebControl Tab
This tab (FIG. 1) displays links to both G3 web panel pages downloaded to the target Master and G4 panels running the latest G4 Web Control feature.
G3 panel pages accessed through the WebControl tab are virtual pages created by a user in TPDesign3 and then downloaded to the target Master. Interaction with these pages are not reflected on an actual G3 panel unless you use specific programming commands that link these virtual pages with their real G3 panel counterparts.
The following table lists the WebControl tab features that an administrator or other authorized user can select from: WebControl Tab Features
Feature Description This area displays: Compatible Devices Field Links to G3 user designed web panels (containing an index.htm page) that are installed on the NetLinx Master. G4 icons (with associated links) if a G4 panel running Web Control is communicating with the target Master. Allows you to choose from among two compression options: These compression settings are most useful when working over a bandwidth-restricted network or over the Internet. Use Compression allows the user to specify that the transmitted data packets be compressed. This speeds up the visual responses from the panel by minimizing the size of the information relayed through the web and onto the PC screen. Use Low Color allows the user to specify the number of colors used to display the image from the panel be reduced. By reducing the numbers of colors used to display the panel page on the PC, the size of the information is reduced, and the response delay is decreased.
232
Security Options:
FTP Security - Enabled Admin Change Password Security - Enabled All other options - Disabled
SSL security is disabled by default. If the user/group is given FTP access rights by the administrator, all directories can become accessible (read/write/modify).
The administrator user account cannot be deleted or modified with the exception of its password. Only a user with "Change Admin Password Access" rights can change the administrator password. The NetLinx user account is created to be compatible with previous NetLinx Master firmware versions. This account is initially created by default and can later be deleted or modified. The administrator group account cannot be deleted or modified. The FTP Security and Admin Change Password Security are always enabled and cannot be disabled.
Internet Explorer is used for the purposes of these instructions. Refer to the Table , Supported Browser and Feature Compatibility, on page 230 for browser and OS compatibility information.
233
Security Tab
NetLinx system security allows you to define access rights for users or groups. The Enable/Disable Security features (FIG. 2) are only displayed after the left Enable Security link is selected.
The following table lists the NetLinx System Security Enable or Disable options that an administrator or other authorized user can grant or deny access to: Security Tab Features
Feature System section Description Provides an authorized user with the ability to alter the current security options assigned to the target Master. Provides an authorized user with the ability to alter group properties such as creating a group, modifying an existing groups rights, and define the files/directories accessible by a particular group. Any properties possessed by a group (access rights/directory associations, etc.) are inherited by all members of that group. Users section Provides an authorized user with the ability to alter user properties such as creating a user, modifying an existing users communication rights, and defining the files/directories accessible by a particular user. Allows an authorized user to select the method for SSL certificate generation and implementation on the target Master. SSL Certificate section A certificate can be self generated, requested, or regenerated. Once a certificate has been installed onto a target Master, that certificate remains there until it is either replaced or regenerated.
Groups section
234
The Enable Security link toggles the appearance of the NetLinx Master security options. Security System Features
Feature Description This option allows an authorized user the ability to grant/deny access to the security configuration commands of the on-board Master. Only those users with security access rights granted will have access to the security configuration commands. Master Security Configuration These are global options that enable or disable the rights given to both users and groups. Ex: If you would want to disable Telnet Security for all users, you would access this tab and uncheck the Telnet Access option to disable Telnet security for the entire Master. Terminal (RS232) Security This selection enables or disables Terminal Security (through the RS232 Program port). If Terminal Security is enabled, a user must have sufficient access rights to login to a Terminal session. This selection enables or disables Web Server access. If Security is enabled, a user must have sufficient access rights to browse to the NetLinx Master with a Web Browser. Enabling this field prompts the user (upon their return) to submit a valid user name and password. Telnet Access This selection enables or disables Telnet Security. If Telnet Security is enabled, a user must have sufficient access rights to login to a Telnet session. This selection enables or disables the ability of a group to alter the Security Configuration settings. If Security Configuration Security is enabled, a user/group must have sufficient access rights to access the Main Security Menu. This option allows an administrator the ability to enable or disable the SSL feature on the Master. This field will not be enabled until after the initial self-generated certificate has been installed onto the Master. This configures the Master for secure communication. This security is necessary before installing any encrypted CA server certificates. If the self-generated SSL certificate has been installed on the Master, the user is prompted with a Security Alert popup that informs them of possible conflicts between the Masters certificate and those registered through the web browser as valid and secure. Press OK to accept any changes made within this tab and incorporate the information into the target Master. Press Cancel to void any changes made within this tab, exits without making changes to the target Master, and blanks-out the Security tab.
HTTP Access
SSL Enable
OK/Cancel
You must first enable the Master Security selection and then click OK before altering any settings. Click OK again after making alterations to any of these features (such as Terminal, HTTP, and Telnet access) and save these changes to the target Master.
235
Security tab - Add Group page The Groups > Add Group link allows an authorized user to add a group account (FIG. 3) and then assign that groups current Master access rights.
236
Security tab - Modify Group page The Groups > Modify Group link allows an authorized user to select from a listing of available groups (FIG. 4) and then modify the access rights for the selected group.
237
Security tab - Group Directory Associations page The Groups > Directory Associations link allows an authorized user to view current directory associations assigned to the selected group, add paths for new directory associations, and delete any previously configured directory associations (FIG. 5).
A Directory Association is a path that defines the directories and files a particular user or group can access via the Web Server on the NetLinx Master. This character string can range from 1 to 128 alpha-numeric characters. This string is case sensitive. This is the path to the file or directory to which you want to grant access.
A single '/' is sufficient to grant access to all files and directories in the user directory and subdirectory. The '/*' wildcard can also be added to enable access to all files. All entries should start with a '/'.
Here are some examples of valid entries: Valid Directory Association Entries
Path / /* Description Enables access to the all files within the users main directory and subdirectories. Enables access to the all files within the users main directory and subdirectories. If user1 is a file in the user directory, only the file is granted access. If user1 is a subdirectory of the user directory, all files in the user1 and its sub-directories are granted access. user1 is a subdirectory of the user directory. All files in the user1 and its sub-directories are granted access. /Room1/iWebControlPages is a subdirectory and all files and its subdirectories are granted access.
/user1
/user1/ /Room1/iWebControlPages/*
238
By default, all accounts that enable HTTP Access are given a '/*' Directory Association if no other Directory Association has been assigned to the account. Group Directory Association Entries
Feature Description Provides a drop-down listing of the available groups. Initially, administrator is listed as a default group. Thereafter, the last group accessed is then always shown. Select New Group As more groups are added through the Add Group section of the Security tab; those groups appear within the drop-down selection. The checkbox alongside each access right is populated when a new group is selected. This field displays all existing directories currently on the target Master. Add Association These folders can consist of G3 HTML project folders, data file folders, etc. These folders are located beneath the User directory on the Master. This field is used to specify the path for the file or directory granted for access and then assigned to the selected group. Adding Association Clicking on a folder within the Add Association area populates the Adding Association association field with the folders path. The directory path can also manually be entered. Press Add to accept the new path and assign it to the selected group. Press Cancel to void any path changes. This drop-down listing displays any current directory associations assigned to the group and prompts you to select the association you want to delete. Delete/Select Association Press Delete to remove the currently selected directory association and save those changes to the group profile. Press Cancel to void any association changes.
239
Description A valid character string defining the name of the user (4 - 20 alpha-numeric characters). The string is case sensitive and must be unique. Provides a drop-down listing of the available groups. Any properties possessed by groups (ex: access rights, directory associations, etc.) are inherited by users assigned to a particular group. This selection enables or disables Terminal Security Access (through the RS232 Program port) for the target user. This selection enables or disables the users right to change the administrators user passwords. Note: Once the Administrators password has been changed, the default password can no longer be used to gain access. This selection enables or disables FTP Access for the target user. This selection enables or disables Web Server access for the target user. This selection enables or disables Telnet Security access for the target user. This selection enables or disables the ability of a user to alter the Security Configuration settings. Enter a password for the new user. A user password is a valid character string (4 - 20 alpha-numeric characters) that is used to supplement the user name/ID in defining the potential client. The string is case sensitive and must be unique. Press OK to accept any changes made within this tab and incorporate the information into the target Master.
Group
Password/Confirm
OK/Cancel
Press Cancel to void any changes made within this tab, disables the security configuration session, voids any changes made to the Master, and returns you to the empty Security tab.
Security tab - Modify User page The Users > Modify User link allows an authorized user to select from a listing of available users (FIG. 7) and then modify the Masters access rights for the selected user.
Group Rights are greyed-out and are read-only from within Modify User.
The Group Rights column will appear greyed-out when viewed within the Mozilla browser on a Linux machine.
240
Provides a drop-down selection listing of the available users. Initially, administrator and NetLinx are listed as a default users. The administrator has ALL available group and User access rights. The NetLinx user has only FTP user rights and no pre-assigned group rights. Thereafter, the last user accessed is then always shown. As more users are added through the Add User section of the Security tab; those users appear within the drop-down selection (along with checkmarks alongside their selected user access rights). Provides a drop-down selection listing of the available groups. Select New Group As more groups are added through the Add Group section of the Security tab; those groups appear within the drop-down selection (along with their directory associations). Any properties possessed by groups (ex: access rights, directory associations, etc.) are inherited by users assigned to a particular group. Terminal (RS232) Access This selection enables or disables Terminal access (through the RS232 Program port) for the selected user. This selection enables or disables the users right to change the administrators user passwords. Note: Once the administrators password has been changed, the default password can no longer be used to gain access. This selection enables or disables FTP Access for the selected user. This selection enables or disables Web Server access for the selected user. This selection enables or disables Telnet access for the selected user. This selection enables or disables the ability of a user to alter the Security Configuration settings. Enter a new password assigned to the selected user. A user password is a valid character string (4 - 20 alpha-numeric characters). The string is case sensitive and must be unique. If this field is left blank the current password is left unchanged. If a new alpha-numeric string is entered, it becomes incorporated as the new password after pressing the OK button. Press OK to accept any changes made within this tab and incorporate the information into the target Master. OK/Cancel/Delete Press Cancel to void any changes made within this tab, disables the security configuration session, voids any changes made to the Master, and returns you to the empty Security tab. Press Delete to remove the selected user from the list of authorized users on the Master.
Select User
Password/Confirm
241
Security tab - User Directory Associations page The Users > Directory Associations link allows an authorized user to view current directory associations assigned to the selected user, add paths for new directory associations, and delete any previously configured directory associations (FIG. 8).
A Directory Association is a path that defines the directories and/or files a particular user or group can access via the Web Server on the NetLinx Master. This character string can range from 1 to 128 alpha-numeric characters. This string is case sensitive. This is the path to the file or directory to which you want to grant access.
A single '/' is sufficient to grant access to all files and directories in the user directory and it's subdirectory. The '/*' wildcard can also be added to enable access to all files. All entries should start with a '/'. Here are some examples of valid entries: Valid Directory Association Entries
Path / /* /user1 Description Enables access to the user directory and all files and subdirectories in that user directory. Enables access to the user directory and all files and subdirectories in that user directory. If user1 is a file in the user directory, only the file is granted access. If user1 is a subdirectory of the user directory, all files in the user1 and its sub-directories are granted access. user1 is a subdirectory of the user directory. All files in the user1 and its sub-directories are granted access. /Room1/iWebControlPages is a subdirectory and all files and its subdirectories are granted access.
/user1/ /Room1/iWebControlPages/*
242
By default, all accounts that enable HTTP Access are given a '/*' Directory Association if no other Directory Association has been assigned to the account. User Directory Association Entries
Feature Description Provides a drop-down listing of the available users. Initially, administrator and NetLinx are listed as default users. Thereafter, the last user accessed is then always shown. Select User As more users are added through the Add Group section of the Security tab; those users appear within the drop-down selection. The checkbox alongside each access right is populated when a new user is selected. This field displays all existing directories currently on the target Master. Add Association These folders can consist of G3 HTML project folders, data file folders, etc. These folders are located beneath the User directory on the Master. This field is used to specify the path for the file or directory granted for access and then assigned to the selected user. Adding Association Clicking on a folder within the Add Association area populates the Adding Association association field with the folders path. Another field option is to manually enter the directory path. Press Add to accept the new path and assign it to the selected user. Press Cancel to void any path changes. This drop-down listing displays any current directory associations assigned to the user and prompts you to select the association you want to delete. Delete/Select Association Press Delete to remove the currently selected directory association and save those changes to the user profile. Press Cancel to void any path changes, disables the security configuration session, and returns you to a blank Security tab.
Security tab - SSL Server Certificate page A certificate is a cryptographically signed object that associates a public key and an identity. Certificates also include other information in extensions such as permissions and comments. A "CA" is short for Certification Authority and is an internal entity or trusted third party that issues, signs, revokes, and manages these digital certificates.
Before initially enabling the SSL feature on the Master, a self-generated certificate must first be installed. This initial installation allows users to then later install the different types of certificates (requested, self-generated, or regenerated).
243
The SSL > Server Certificate link (FIG. 9) allows an authorized user to display an installed certificate, create a certificate request, self-generate, and regenerate SSL Server Certificates.
Bit Length
244
If a certificate has been purchased from an external CA and then installed onto a specific Master, DO NOT regenerate the certificate or alter its properties (ex: bit length, city, etc.). If the purchased certificate is regenerated, it becomes invalid.
A certificate consists of two different Keys: Master Key is generated by the Master and is incorporated into the text string sent to the CA during a certificate request. It is unique to a particular request made on a specific Master. Public Key is part of the text string that is returned from the CA as part of an approved SSL Server Certificate. This public key is based off the submitted Master key from the original request. Regenerating a previously requested and installed certificate invalidates that certificate because the Master Key has been changed.
245
Security tab - Export Certificate Request page The SSL > Export Certificate Request link opens an Export Certificate Request field (FIG. 10) where an authorized user can copy the raw text from a generated Certificate request into their clipboard and then send it to the CA.
Security tab - Import Certificate page The SSL > Import Certificate link opens an Import Certificate field (FIG. 11) where an authorized user can paste the raw text from a CA issued Certificate.
A CA server certificate can only be imported to a target Master only after both a self-generated certificate has been created and the SSL Enable feature has been selected on the Master. These actions configure the Master the secure communication necessary during the importing of the CA certificate.
246
System Tab
Displays the firmware version and log information for the NetLinx Master (FIG. 12).
Network Tab
Provides a list of the DNS and URL associated with the NetLinx Master. The DNS List identifies the Domain Name servers that translates domain names for the Master into IP Addresses. The URL List identifies all URL entries within the Masters URL list.
247
Self-Generating a SSL Server Certificate Request 1. 2. Click on the Security tab (FIG. 14). Refer to the Security tab - SSL Server Certificate page section on page 243 for more detailed descriptions on the security configuration options. Click the Server Certificate link (on the left of the browser window) to display the Security tab with the fields necessary for developing a new certificate.
3.
Click the down arrow from the Bit length field to open a drop-down listing of available public key lengths. The three available public key lengths are: 512, 1024, and 2048. Higher selected key lengths result is increased certificate processing times. A larger the key length results in more secure certificates.
4.
Enter the Domain Name. Example: If the address being used is www.amxuser.com, that must be the Common name and format used in the Common Name field. This string provides a unique name for the desired user. This domain name does not need to be resolvable URL Address when self-generating a certificate.
248
5. 6. 7. 8.
Enter the name of the business or organization into the Organization Name field. This is an alpha-numeric string (1 - 50 characters in length). Enter the name of the department using the certificate into the Organizational Unit field. This is an alpha-numeric string (1 - 50 characters in length). Enter the name of the city where the certificate will reside into the City/Location field. This is an alpha-numeric string (1 - 50 characters in length). Enter the name of the state or province where the certificate will reside into the State/Province field. This is an alpha-numeric string (1 - 50 characters in length). The city/province name must be fully spelled out. Click the down arrow from the Country Name field to open a drop-down listing of listing of currently selectable countries.
9.
10. Click the down arrow from the Action field to open a drop-down listing of available certificate generation options. 11. Choose Self Generate Certificate from the drop-down list. When this request is submitted, the
certificate is generated and installed into the Master in one step.
12. Click OK to save the new encrypted certificate information to the Master or click Cancel to void any changes made within this tab and exit without making changes to the target Master.
ONLY use the Regenerate certificate option when you have Self Generated your own certificate. DO NOT regenerate an external CA-generated certificate.
13. Click the Security tab > Enable Security link to return to the Enable Security page. 14. Place a checkmark into the SSL Enable selection box to enable the SSL security feature on the target Master. Activating this option creates a secure connection to and from the target Master. It is recommended that a secure connection to the target Master be used when importing a CA server certificate. Creating a Request for a SSL Server Certificate 1. 2. 3. Click on the Security tab. Refer to the Security tab - SSL Server Certificate page section on page 243 for more detailed descriptions on the security configuration options. Click the Server Certificate link (on the left of the browser window) to display the Security tab with the fields necessary for generating a new certificate. Click the down arrow from the Bit length field to open a drop-down listing of available public key lengths. The three available public key lengths are: 512, 1024, and 2048. Higher selected key lengths result in increased certificate processing times. A longer key length results in more secure certificates. 4. Enter the used Domain Name. Example: If the address being used is www.amxuser.com, that must be the Common name and format used in the Common Name field. This string provides a unique name for the desired user.
249
This domain name must be associated to a resolvable URL Address when creating a request for a purchased certificate. The address does not need to be resolvable when obtaining a free certificate. 5. 6. 7. 8. Enter the name of the business or organization into the Organization Name field. This is an alpha-numeric string (1 - 50 characters in length). Enter the name of the department using the certificate into the Organizational Unit field. This is an alpha-numeric string (1 - 50 characters in length). Enter the name of the city where the certificate will reside into the City/Location field. This is an alpha-numeric string (1 - 50 characters in length). Enter the name of the state or province where the certificate will reside into the State/Province field. This is an alpha-numeric string (1 - 50 characters in length). The state/province name must be fully spelled out. Click the down arrow from the Country Name field to open a drop-down listing of listing of currently selectable countries.
9.
10. Click the down arrow from the Action field to open a drop-down listing of available certificate generation options. 11. Choose Create Request from the drop-down list. 12. Click OK to accept the information entered into the above fields and generate a certificate file. Refer to the Security tab - Export Certificate Request page section on page 246. This refreshed the Server Certificate page and if the certificate request was successful, displays a "Certified request generated" message. 13. Click the Export Certificate Request link (on the left of the browser window) to display the certificate text file. 14. Place your cursor within the certificate text field. 15. Press the Ctrl + A keys simultaneously on your keyboard (this selects all the text within the field).
YOU MUST COPY ALL OF THE TEXT within this field, including the -----BEGIN CERTIFICATE REQUEST----- and the -----END CERTIFICATE REQUEST-----. Without this text included in the CA submission, you will not receive a CA-approved certificate.
16. Press the Ctrl + C keys simultaneously on your keyboard (this takes the blue selected text within the field and copies it to your temporary memory/clipboard). 17. Paste this text into your e-mail document and then send that information to a CA with its accompanying certificate application.
When a certificate request is generated, you are creating a private key on the Master. YOU CAN NOT REQUEST ANOTHER CERTIFICATE UNTIL THE PREVIOUS REQUEST HAS BEEN FULFILLED. Doing so will void any information received from the previously requested certificate and it will be nonfunctional if you try to use it.
18. Once you have received the returned CA certificate, follow the procedures outlined in the following section to import the returned certificate, over a secure connection, to the target Master.
250
Importing a CA certificate to the Master over a secure SSL connection Before importing a CA server certificate, you must: First, have a self-generated certificate installed onto your target Master. Secondly, enable the SSL security feature from the Enable Security page, to establish a secure connection to the Master prior to importing the encrypted CA certificate. Refer to the Security tab - Enable Security page section on page 235 for more information about enabling SSL security. 1. Take the returned certificate (signed by the CA and encrypted with new information which makes it different from the text string that was previously sent) and copy it into your clipboard. Refer to the Security tab - Import Certificate page section on page 246. Click the Import Certificate link to open the empty Import Certificate window. Place your cursor within the empty window and paste the raw text data (in its entirety) into the field. Click OK to enter the new encrypted certificate information and save it to the Master or click Cancel to void any changes made within this tab and exit without making changes to the target Master.
2. 3. 4.
Once a certificate has been purchased from an external CA and then installed onto a specific Master, DO NOT regenerate the certificate or alter its properties (example: bit length, city, etc.).If the purchased certificate is regenerated, it becomes invalid.
A certificate consists of two different Keys: Master Key is generated by the Master and is incorporated into the text string sent to the CA during a certificate request. It is specific to a particular request made on a specific Master. Public Key is part of the text string that is returned from the CA as part of an approved SSL Server Certificate. This public key is based off the submitted Master key from the original request. Regenerating a previously requested and installed certificate, invalidates the previously purchased certificate because the Master Key has been changed. 5. Use the Display Certificate option to confirm that the new certificate was imported properly to the target Master.
Display SSL Server Certificate Information 1. Click on the Security tab (FIG. 14 on page 248). Refer to the Security tab - SSL Server Certificate page section on page 243 for more detailed descriptions on the security configuration options. Click the Server Certificate link (on the left of the browser window) to populate the Security tab.
2.
By default, the Display Certificate Action is selected and these fields are populated with information from an installed certificate. If the Master does not have a previously installed certificate, these fields are blank.
251
3. 4. 5.
Click the down arrow from the Action field to open a drop-down listing of available certificate generation options. Choose Display Certificate from the drop-down list. Click OK to accept the action and populate the fields with the certificate information.
Regenerating an SSL Server Certificate Request 1. 2. Click on the Security tab. Refer to the Security tab - SSL Server Certificate page section on page 243 for more detailed descriptions on the security configuration options. Click the Server Certificate link (on the left of the browser window) to display the Security tab with the fields necessary for developing a new certificate.
This method of certificate generation is used to modify or recreate a previously existing certificate already on the Master. By default, if a certificate is already present on the target Master, the Display Certificate Action is selected and these fields are populated with information. EX: if the company has moved from Dallas to Houston, all of the information is reentered exactly except for the City.
3. 4. 5.
Enter any new or changed information into its respective field. Click the down arrow from the Action field to open a drop-down listing of available certificate generation options. Choose Regenerate Certificate from the drop-down list.
When this request is submitted, the certificate is generated and installed into the Master in one step.
6. 7.
Click OK to save the newly modified certificate information to the Master or click Cancel to void any changes made within this tab and exit without making changes to the target Master. Before exiting the Master and beginning another session: verify that all users have been assigned the correct rights, and are using the correct passwords. In the Enable Security window of the Security tab, verify that the Master Security and HTTP Access are enabled. Enabling HTTP Access will prompt users to enter pre-configured user names and passwords.
252
6. 7.
YOU MUST COPY ALL OF THE TEXT within this field, including the -----BEGIN CERTIFICATE REQUEST----- and the -----END CERTIFICATE REQUEST-----. Without this text included in the CA submission, you will not receive CA approved certificate.
8. 9.
Press the Ctrl + C keys simultaneously on your keyboard (this takes the blue selected text within the field and copies it to your temporary memory/clipboard). Paste this text into the Submit Request field on the CAs Retrieve Certificate web page.
10. Choose to view the certificate response in raw DER format. 11. Note the Authorization Code and Reference Number (for use in the e-mail submission of the request). 12. Submit the request. 13. Paste this certificate text field (copied from steps 7 & 8 above) into your e-mail document and then send that information to a CA with its accompanying certificate application.
253
14. Complete the certificate installation procedures outlined in the Creating a Request for a SSL Server Certificate section on page 249.
The only way to avoid a CA certificate becoming invalid due to a time expiration is to request a new certificate from your current CA.
Refer to the Creating a Request for a SSL Server Certificate section on page 249 for more information on how to request an externally generated certificate.
For more information on setting up NetLinx Security settings and SSL Certificates please look to the NetLinx Integrated Controllers Instruction Manual in the NetLinx Security and Web Server section on amx.com.
254
Protocol Stack
The NetLinx master's software runs a single protocol stack-the IP protocol. Of the IP protocol, both UDP and TCP are managed and utilized. The NetLinx master's IP address configuration may be either static or DHCP. The DHCP client conforms to RFC1541 with support for option 12 (Host name) of RFC1533. The inclusion of the Host Name option in the DHCP client allows DHCP servers that support updating dynamic DNS tables to add the NetLinx masters host name to the DNS.
Application Protocols
The NetLinx master implements the following protocols:
ICSP (port 1319 UDP/TCP)- The Internet Control System Protocol (ICSP) was developed by AMX to facilitate Control System communication and management. The ICSP protocol has been registered with the Internet Assigned Numbers Authority (www.iana.org) and should not conflict with any other protocol used on the network. ICSP is a peer-to-peer protocol used for both masterto-master and master-to-device communications. For maximum flexibility, the NetLinx master can be configured to utilize a different port than 1319 or disable ICSP over Ethernet completely from either Telnet or the Program Port located on the NetLinx master itself. Telnet (port 23 TCP) - The NetLinx telnet server provides a mechanism to configure and diagnose a NetLinx system. For maximum flexibility, the NetLinx master can be configured to utilize a different port than 23 or disable Telnet completely from either Telnet or the Program Port located on the NetLinx master itself. Once disabled, the only way to enable Telnet again is from the NetLinx master's program port. HTTP (port 80 TCP) - The master has a built-in web server that complies with the HTTP 1.0 specification and supports all of the required features of HTTP v1.1. FTP (port 21/20 TCP) - The built-in FTP server conforms to RFC959.
255
Internet Inside (port 10500 TCP) - The Internet Inside feature of the NetLinx master uses, by default, port 10500 for the XML based communication protocol. This port is connected to by client web browser's JVM when Internet Inside control pages are retrieved from the NetLinx master's web server. For maximum flexibility, the NetLinx master can be configured to utilize a different port than 10500 or to disable Internet Inside completely.
The source of network packets may come from any of the application protocols mentioned in the previous section. HTTP, FTP, and Telnet protocols are well understood and the full implications, with respect to network utilization, of their usage are not covered by this document. However, they require interaction with a user and, therefore, their network utilization is very sporadic.
Regarding ICSP, the NetLinx master generates a UDP broadcast message of 60 bytes every five seconds. The following information pertains to a quiescent system, which has no "events" occurring. For every Ethernet ICSP device (including other NetLinx masters) that's connected TCP, there are two outbound messages and one response every five seconds. The outbound messages are 29 bytes and 60 bytes, while the inbound response is 40 bytes.
An "event" in NetLinx is defined as a button press on a user interface, a level value change, or other control message. By their nature, control messages are relatively short and infrequent. For example, a button press message is 33 bytes longfor each button press event there is a corresponding button release event that occurs (also 33 bytes long).
The following table shows the percentage of network bandwidth utilization for a 10Mbps network with a number of ICSP devices (or NetLinx masters) connected to a NetLinx master. Number of Devices (ICSP Over Ethernet)
1 2 3 10 50 100 1000
Bytes/Sec
12 37.8 75.6 340.2 1852.2 3742.2 37762.2
256
Internet Inside uses an XML representation of the ICSP data to facilitate Java client application communications with the master. The following information pertains to a quiescent system, which has no "events" occurring. For every Internet Inside device that's connected TCP, there is a single outbound message and one response message every five seconds. Both messages are approximately 500 bytes long. Additionally, the Java client sends a single message to the master that requires one response. These occur every ten seconds and each is approximately 500 bytes.
An "event" in NetLinx is defined as a button press on a user interface, a level value change, or other control message. For example, a button press message is approximately 500 bytes longfor each button press event there is a corresponding button release event that occurs (also ~500 bytes long). The following table shows the percentage of network bandwidth utilization for a 10Mbps network with a number of Internet Inside device connected to a NetLinx master. Number of Devices (ICSP Over Ethernet)
1 2 3 10 50 100 1000
Bytes/Sec
300 600 900 3000 15000 30000 300000
257
258
Appendix - Troubleshooting
Appendix - Troubleshooting
ESCAPE
The key to troubleshooting any problem including an AMX control system is a structured approach.
Explain the problem completely Switches and Settings should be checked Cables and Connectors should be checked Attributes should be verified Programming should be verified Equipment should be checked
Explain
You need to get as much detail as you can about the problem. When does happen? What makes the problem occur?
Attributes
Make sure all properties are set correctly. Is the button set to the right type? Is it part of a Mutually Exclusive Group? Is the carrier and data type set correctly for an IR/Serial deice? Are the communication parameters set correctly on the NXI/ NI Series?
Programming
The program should never be the first solution to a problem if the system worked correctly previously. Does the programming do what the customer wants? Has the program been modified?
Equipment
If everything else checks out okay then it could be a faulty piece of equipment. Verify that the device is working properly. Verify that the controlled device is working properly.
For FAQs and Tips you can go to the Technical Support page on AMX.com.
259
Appendix - Troubleshooting
Troubleshooting Tools
Terminal Window
In the NetLinx Studio choose Tools > Terminal to open the Terminal Emulator window.
The Terminal Emulator window puts the Master Controller into terminal control mode. Anything that is typed on the screen exits through the Master communications port, and anything coming in from the communications port is displayed on your monitor. The Terminal Emulator window communicates directly with the Master Controller and can be used to debug RS-232-controlled devices. You cannot use the Terminal Emulator window while a communication port is in use for a file transfer operation. Type "ECHO ON" in the Terminal Emulator window display messages. To use the Terminal Emulator with NetLinx systems, you must be connected to the Master via the PROGRAM port. Otherwise, you can use Windows TelNet for terminal control of NetLinx systems via an Ethernet connection.
260