Introduction
So far, you have used channels in devices to interact both with the user and with what he or she wants to control. Channels, however, are not the only method of controlling some devices, such as volume control, voltage generator, and pan/tilt control devices. Devices such as these use “levels”
to interface with the outside world. Also, several control panels have bar graph displays capable of displaying a level. This unit will show you how to create, read, and modify these levels, plus show you how to use bar graphs and sliders on some of these devices.
What is a Level?
An input/output (I/O) channel in AMX Control Systems is usually digital in nature; that is, it can only have an “on” or an “off” state. 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.
Imagine that a volume control card has two volume knobs: one for the left speaker and one for the right. Each knob has a range of values from 0 to 255. These knobs represent the two levels present in the volume control card. When a “level” is discussed in the text, it is usually referring to the value of one of these imaginary knobs.
Creating Levels
In most AMX devices levels can have a value between 0 and 255. Level values can be stored in a variable for later use. In order to read a level from a device that supports levels, you use the keyword CREATE_LEVEL. Here is the syntax:
CREATE_LEVEL device, level number, variable
CREATE_LEVEL takes three parameters:
! The device from which to read the level
! Which level of the device to read (some devices have many different levels)
! The variable in which to store the level
This keyword creates an association between the specified level of the device and the specified variable. During execution of your program, the Master will continually update the variable to contain the value of the level with which it is associated. Since this association only needs to be done once, this keyword is only allowed to appear in the DEFINE_START section of your program.
In this unit, you will develop a new program that handles levels. This system will contain a volume control card to control a volume level, and a Touch Panel (FIG. 1) for the user to control the volume card. On the Touch Panel, there will be four buttons: Volume Up, Volume Down, Volume Mute, and Volume Preset. There will also be a bar graph on the Touch Panel to display and control the volume level.
Here are some code excerpts to get started:
DEFINE_DEVICE VOLUME = 17:1:0 TP = 128:1:0
DEFINE_CONSTANT
(* Three channels to control both outputs together *) V_UP = 1
V_DN = 2 V_MT = 3 DEFINE_VARIABLE
VOL_LEVEL (* This will store the volume level value*) PRESET (* This will store the preset level value*) FIG. 1 Touch Panel used for Level Exercise
The companion code to this section is STEP4a.
Chapter 7 – Creating and Using Levels
DEFINE_START
CREATE_LEVEL VOLUME, 1, VOL_LEVEL
This code defines the devices you will use, a variable in which to store the volume level value, and the statement in the startup code to create the association between level number 1 of the volume card and the VOL_LEVEL variable. It also defines some constants that give names to the different channels available in the volume control card. By turning on and off these channels the user can raise, lower, and mute the volume levels of the card. Here is the code for the Volume Up, Volume Down, and Volume Mute buttons on the Touch Panel:
DEFINE_EVENT
Notice that the Volume Up and Volume Down buttons will automatically un-mute the volume before starting to ramp the volume up or down. Also, these control channels affect both levels of the volume card simultaneously, ramping both up and down together. This code handles all of the functions of your system except for the bar graph and the Volume Preset button.
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. In your program, as the user ramps the volume level up, the value in VOL_LEVEL increases. When the volume is ramped up to the maximum, VOL_LEVEL will contain 255. The same goes for ramping down; when the volume is muted, the variable will contain zero.
Making a Preset
Now you are going to add the code necessary to create a preset. A preset is a level stored for later retrieval. What you will do here is give the Volume Preset button a dual role. If the button is pressed and held for two seconds, the current level of the volume card is stored in the variable PRESET. If the button is pressed for less than two seconds, it sends a command to the volume card to set the level of the card to the previously saved level in PRESET. First, here is the code:
BUTTON_EVENT[TP,4] //VOL PRESET {
RELEASE:
{
SEND_COMMAND VOLUME, "'P0L', ITOA(PRESET)"
OFF[VOLUME,V_MT]
}
HOLD[20]:
{
PRESET = VOL_LEVEL }
}
DEFINE_PROGRAM
[TP,4] = (PRESET = VOL_LEVEL)
This code uses the HOLD keyword to be sure the button is held for at least 2 seconds (20 tenths).
Then the current level of the card (stored in VOL_LEVEL) is saved into the variable PRESET. When the button is released a command is sent to the volume card to go to the level saved in PRESET (even if only saved a moment earlier), and the volume is un-muted. Note that the feedback for the Volume Preset button is turned on whenever the current volume level equals the value of the PRESET variable.
AMX volume devices remember the previous level when it is muted so that it can un-mute to that same level.
Remember that Hold times can be measured in as little as a hundredth of a second (.1)
Chapter 7 – Creating and Using Levels
Using Bar Graphs
Now you will add the code to continuously display the current level of the volume card on the Touch Panel’s bar graph. To update a bar graph on a device, you use the SEND_LEVEL keyword.
Here is the syntax:
SEND_LEVEL device, level number, value
This keyword is used to update a level in a device. Assume your bar graph display on the Touch Panel has level number 1. In order to keep the display updated continually, you will add the following line into your program (in mainline):
SEND_LEVEL TP, 1, VOL_LEVEL
Since this code resides in mainline it will be executed continually, thus making sure that the bar graph reflects the value of level number 1 of the volume card. As the volume ramps up, VOL_LEVEL increases and the bar graph fills. As the volume ramps down, VOL_LEVEL decreases and the level indicated on the bar graph also decreases. Since both volume levels are ramping together, you only have to track one of them for the bar graph.
Connecting Levels
Touch Panel bar graphs have a unique feature if they are set to the active bar graph type: you can touch and slide the bar graph itself and the level will raise or lower to that point; the level simply tracks the movement of your finger. However, to do this you must set up a connection between the bar graph and the volume level. That is what the keyword DEFINE_CONNECT_LEVEL accomplishes.
DEFINE_CONNECT_LEVEL is not a keyword that is used inside mainline, but is actually a definition section like DEFINE_DEVICE or DEFINE_START. When you use it, the best location to place it is immediately following the DEFINE_DEVICE section. Underneath the DEFINE_CONNECT_LEVEL header is where all level connections are listed. Here is how DEFINE_CONNECT_LEVEL is used:
DEFINE_CONNECT_LEVEL
(device 1,level number 1,device 2,level number 2,...etc.)
The section inside the parentheses represents a single connection. All levels listed in the connection will follow each other. If any one level changes, all others will change to match. Any number of levels may be supported per connection, and there is no limit to the number of connections. Here is how you would use DEFINE_CONNECT_LEVEL in your program to connect the Touch Panel's bar graph to the volume card's levels:
DEFINE_CONNECT_LEVEL
(PANEL, 1, VOLUME, 1, VOLUME, 2)
This connects level number 1 on the Touch Panel (your bar graph) and levels 1 and 2 on the volume card together. The reason that two levels on the volume card are included is because volume control cards have two levels: the left audio channel and the right audio channel. These connections are a two-way street: anytime the bar graph is changed, both volume levels will follow, and anytime a volume level is changed (probably by the volume control buttons on the Touch Panel), the bar
graph will automatically follow. When using DEFINE_CONNECT_LEVEL, it is not necessary to use the SEND_LEVEL keyword in your program since the connection constantly takes care of updating the bar graph.
The companion code to this section is STEP4b.