Education

Extron GlobalScripter and Global Configurator Programming

Extron's programming environment has two tiers: Global Configurator Plus (GCP) for graphical no-code room control, and Global Configurator Professional (GCPro) which adds full GlobalScripter scripting for complex logic. Both run on Windows and output programs that execute on IPCP Pro control processors. Understanding both tiers — when each is appropriate and how they interact — is essential for Extron system design. The vast majority of Extron rooms use GCP alone; GCPro and GlobalScripter are needed when device communication, conditional logic, or third-party API integration exceeds GCP's built-in capabilities.

See control-systems/extron-basics for the platform overview and control-systems/extron-sis-protocol for the SIS command reference used in GlobalScripter device communication.

Global Configurator Plus (GCP) — Graphical Programming

GCP Workspace Structure

GCP organizes a project into four areas visible in the main window:

  • System tab — define all hardware: IPCP Pro processor, connected devices (displays, switchers, DSP, cameras), touchpanels
  • Design tab — the main programming canvas; drag device modules, logic blocks, and panel page references onto the canvas and wire them together
  • Pages tab — TouchLink Pro touchpanel page designer; buttons, sliders, labels, background images
  • Configuration tab — network settings, IP addresses, firmware upload targets

Device Modules

Every controllable device in an Extron system has a device module — a pre-built communication driver that handles all protocol details (RS-232 framing, IR codes, IP handshaking). Extron maintains a library of thousands of device modules covering displays, projectors, switchers, audio DSP, cameras, and third-party AV equipment.

Adding a device module:

  1. In the System tab, click Add Device
  2. Search the Extron device library by manufacturer and model
  3. Select the communication method (RS-232, IR, IP, relay)
  4. Assign the IPCP Pro port (RS-232 port 1, IR port 2, etc.)
  5. Configure baud rate, IP address, or IR channel as required

The device module appears in the Design canvas as a block with labeled ports — one port per controllable function (power, input selection, volume, etc.).

Logic Blocks

Logic blocks connect device module ports to touchpanel buttons and to each other. Common logic blocks:

Block TypeFunction
Button ActionExecute commands when a touchpanel button is pressed/released
FeedbackUpdate touchpanel button state based on device status
ConditionalBranch logic based on input state (if/else)
TimerDelay or schedule actions
RampSmoothly change a value over time (volume fade)
CounterCount events; trigger at threshold
String ParserExtract values from RS-232 response strings
VariableStore and recall values (current input, volume level, room mode)

Wiring in GCP: Logic blocks connect with graphical wires. An output port of one block connects to an input port of another. Data flows along these wires when events fire. The visual wiring makes signal flow traceable without reading code.

Typical GCP Room Program Structure

A standard single-room conference room in GCP:

[TouchLink Pro Panel]
  Button 1 (Display On)  →  [Button Action]  →  Display Power ON command
  Button 2 (Display Off) →  [Button Action]  →  Display Power OFF command
  Button 3 (HDMI 1)      →  [Button Action]  →  Switcher Input 1 Select
  Button 4 (HDMI 2)      →  [Button Action]  →  Switcher Input 2 Select
  Slider (Volume)        →  [Ramp Block]     →  DMP Volume control
  
[Display Device Module]
  Power Feedback  →  [Feedback Block]  →  Button 1/2 active state on panel

[Switcher Device Module]
  Active Input Feedback  →  [Feedback Block]  →  Button 3/4 active state

GCP handles all RS-232/IP command formatting internally. The programmer never writes protocol strings — the device module knows the commands.

EDID Minder and Signal Management

EDID Minder is a GCP feature for CrossPoint matrix switchers. It stores a copy of the downstream display's EDID (Extended Display Identification Data) on the switcher input, so the source always sees a valid EDID even when the display is off or disconnected. Configure EDID Minder in the System tab → CrossPoint device → EDID Management. Set each output's EDID to the connected display's native resolution, then apply to all inputs.

Without EDID Minder configuration, sources connected to an Extron switcher may default to 1080p or 720p output instead of native 4K — one of the most common commissioning complaints.

Global Configurator Professional (GCPro) — Adding Scripts

GCPro adds a Script Editor alongside the GCP canvas. Script blocks can be placed on the canvas and wired to device modules and logic blocks like any other block. The script inside executes when triggered by an incoming wire signal or timer.

When to Use GCPro Scripts

Use GCPro scripts when GCP logic blocks cannot express the required behavior:

  • Parsing complex RS-232 or TCP response strings (JSON, XML, proprietary protocols)
  • Conditional logic with more than 2–3 branches
  • State machines (room modes with 4+ states)
  • HTTP REST API calls (room booking, calendar, building management)
  • Mathematical calculations (lumen calculations, dB conversions)
  • String manipulation (building display labels, log entries)
  • Custom TCP/UDP device communication for undocumented protocols

GlobalScripter Language Reference

GlobalScripter is Extron's proprietary scripting language with syntax similar to JavaScript/ECMAScript. It runs on the IPCP Pro processor inside the GCP program context.

Data Types and Variables

// Primitive types
var myInt    = 42;
var myFloat  = 3.14;
var myString = "Conference Room A";
var myBool   = true;

// Arrays
var inputs = ["HDMI 1", "HDMI 2", "Wireless", "Camera"];
var volumes = [0, 25, 50, 75, 100];

// Accessing array elements (zero-indexed)
print(inputs[0]);   // "HDMI 1"
print(inputs[2]);   // "Wireless"

// String operations
var roomName = "Room" + " " + "A";          // concatenation
var len      = roomName.length;              // 6
var upper    = roomName.toUpperCase();       // "ROOM A"
var idx      = roomName.indexOf("A");        // 5
var sub      = roomName.substring(0, 4);    // "Room"

Event Handlers

Event handlers are the core of GlobalScripter programming. They fire in response to hardware events — button presses, RS-232 data received, IP data received, timer expiry.

// Touchpanel button press
// Parameters: tlp (panel object), page (page number), button (button number)
function Button_Press(tlp, page, button) {
    if (page === 1) {
        if (button === 1) {
            // Display power on
            Send(rs232_display, "\x02POWR1\x03");
        } else if (button === 2) {
            // Display power off
            Send(rs232_display, "\x02POWR0\x03");
        } else if (button === 3) {
            SelectInput(1);
        }
    }
}

// Touchpanel button release (for momentary actions)
function Button_Release(tlp, page, button) {
    if (button === 10) {
        Send(rs232_pan_tilt, "\xFF\x01\x00\x00\x00\x00\x01");
    }
}

// RS-232 data received from a device
function RS232_Receive(port, data) {
    // data is the string received
    if (data.indexOf("POW=1") !== -1) {
        // Display confirmed on — update button feedback
        SetButtonState(tlp1, 1, 1, 1);  // panel, page, button, state
        print("Display is ON");
    } else if (data.indexOf("POW=0") !== -1) {
        SetButtonState(tlp1, 1, 1, 0);
        SetButtonState(tlp1, 1, 2, 1);
    }
}

// IP / TCP data received
function IP_Receive(device, data) {
    ProcessResponse(device, data);
}

// Timer fired
function Timer_Event(timer) {
    if (timer === poll_timer) {
        QueryDisplayStatus();
    }
}

RS-232 Communication

// Send a command string to RS-232 port
// Special characters: \x0D = CR, \x0A = LF, \x03 = ETX, \x02 = STX
Send(rs232_1, "POW1\x0D");                 // Send "POW1<CR>"
Send(rs232_1, "\x02POWR1\x03");            // Send STX + "POWR1" + ETX

// Send hex bytes directly
SendHex(rs232_1, "FF 01 00 00 00 00 01");   // VISCA camera home

// Set RS-232 port parameters (baud, data bits, parity, stop bits)
SetSerialParams(rs232_1, 9600, 8, "N", 1);

// Receive buffer — accumulate until delimiter found
var rx_buffer = "";
function RS232_Receive(port, data) {
    rx_buffer += data;
    var end = rx_buffer.indexOf("\r\n");
    while (end !== -1) {
        var line = rx_buffer.substring(0, end);
        ParseResponse(line);
        rx_buffer = rx_buffer.substring(end + 2);
        end = rx_buffer.indexOf("\r\n");
    }
}

IP / TCP Communication

// Connect to a TCP device
Connect(ip_device_1, "192.168.1.50", 4352);

// Check connection status before sending
function SendCommand(cmd) {
    if (IsConnected(ip_device_1)) {
        Send(ip_device_1, cmd);
    } else {
        print("Device not connected — reconnecting");
        Connect(ip_device_1, "192.168.1.50", 4352);
    }
}

// Connection established callback
function IP_Connect(device) {
    print("Connected to: " + GetDeviceName(device));
    Send(device, "init\r\n");  // send init command on connect
}

// Disconnection callback
function IP_Disconnect(device) {
    print("Disconnected — scheduling reconnect");
    StartTimer(reconnect_timer, 10000);  // retry in 10 seconds
}

Timers

// Start a one-shot timer (fires once after delay_ms milliseconds)
StartTimer(my_timer, 5000);         // fire after 5 seconds

// Start a repeating timer
StartRepeatingTimer(poll_timer, 30000);  // fire every 30 seconds

// Stop a timer
StopTimer(poll_timer);

// Timer event handler (see Event Handlers above)
function Timer_Event(timer) {
    if (timer === poll_timer) {
        Send(rs232_display, "POWR?\x0D");  // query display power state
    } else if (timer === reconnect_timer) {
        Connect(ip_device_1, "192.168.1.50", 4352);
    }
}

State Machines

State machines are essential for rooms with multiple operating modes:

// Room mode state machine
var ROOM_MODE_IDLE        = 0;
var ROOM_MODE_PRESENTATION = 1;
var ROOM_MODE_CONFERENCE   = 2;
var ROOM_MODE_SHUTDOWN     = 3;

var currentMode = ROOM_MODE_IDLE;

function SetRoomMode(newMode) {
    // Exit current mode
    if (currentMode === ROOM_MODE_PRESENTATION) {
        // Turn off presentation display
        Send(rs232_display, "\x02POWR0\x03");
    } else if (currentMode === ROOM_MODE_CONFERENCE) {
        // Hang up any active calls
        Send(ip_codec, "hangup\r\n");
    }

    currentMode = newMode;

    // Enter new mode
    if (newMode === ROOM_MODE_PRESENTATION) {
        Send(rs232_switcher, "1!\r\n");         // select input 1
        Send(rs232_display, "\x02POWR1\x03");   // power on display
        SetButtonState(tlp1, 1, 1, 1);            // highlight Presentation button
        SetButtonState(tlp1, 1, 2, 0);
    } else if (newMode === ROOM_MODE_CONFERENCE) {
        Send(rs232_switcher, "2!\r\n");         // select camera input
        Send(ip_codec, "autodial\r\n");
        SetButtonState(tlp1, 1, 1, 0);
        SetButtonState(tlp1, 1, 2, 1);
    } else if (newMode === ROOM_MODE_SHUTDOWN) {
        Send(rs232_display, "\x02POWR0\x03");
        SetAllButtonStates(tlp1, 0);
        StartTimer(shutdown_complete_timer, 3000);
    }
}

function Button_Press(tlp, page, button) {
    if (button === 1) { SetRoomMode(ROOM_MODE_PRESENTATION); }
    if (button === 2) { SetRoomMode(ROOM_MODE_CONFERENCE); }
    if (button === 9) { SetRoomMode(ROOM_MODE_SHUTDOWN); }
}

String Parsing

Parsing RS-232 or IP responses from devices is one of the most common GlobalScripter tasks:

// Parse volume level from response like "Vol035\r\n"
function ParseVolumeResponse(data) {
    var prefix = "Vol";
    var idx = data.indexOf(prefix);
    if (idx !== -1) {
        var volStr = data.substring(idx + prefix.length, idx + prefix.length + 3);
        var vol = parseInt(volStr, 10);
        if (!isNaN(vol)) {
            SetSliderPosition(tlp1, 1, 5, vol);  // update slider on panel
            print("Volume: " + vol);
        }
    }
}

// Parse JSON response from a booking API (via HTTP)
function ParseBookingResponse(jsonStr) {
    try {
        var obj = JSON.parse(jsonStr);
        if (obj.occupied) {
            SetLabel(tlp1, 1, 10, obj.meeting_name);
            SetButtonState(tlp1, 1, 20, 1);  // show occupied indicator
        } else {
            SetLabel(tlp1, 1, 10, "Available");
            SetButtonState(tlp1, 1, 20, 0);
        }
    } catch (e) {
        print("JSON parse error: " + e);
    }
}

HTTP Requests (GCPro)

GCPro supports outbound HTTP GET and POST for room booking and API integration:

// HTTP GET request
function CheckRoomBooking() {
    var url = "http://booking.company.com/api/rooms/101/status";
    var headers = "Authorization: Bearer " + api_token + "\r\n";
    HttpGet(booking_client, url, headers);
}

// HTTP response callback
function HTTP_Response(client, code, data) {
    if (code === 200) {
        ParseBookingResponse(data);
    } else {
        print("HTTP error: " + code);
    }
}

Debugging and Diagnostics

print("message") sends output to the GCP debug console when connected to the IPCP Pro over the network. Use liberally during development — the output is discarded in production. Include variable values: print("Volume: " + vol + " Mode: " + currentMode).

Extron Toolbelt — Monitor Mode

Toolbelt's Monitor view shows:

  • RS-232 send/receive traffic in real time (hex and ASCII)
  • IP connection status for each configured device
  • Current GlobalScripter variable values (read via SIS)
  • IPCP Pro CPU and memory load

Monitor mode is the primary diagnostic tool for communication issues — visible send/receive traffic immediately shows whether commands are being sent and whether responses are being received.

SIS Diagnostics via Telnet

Connect to the IPCP Pro on port 23 (Telnet) using PuTTY or similar. SIS commands allow real-time inspection:

Q               → query current system status
I               → firmware and model information
W1CV            → read variable 1 current value

Common Debug Patterns

  • Command sent but no response: Check RS-232 cable wiring (null modem vs. straight-through), verify baud/parity settings in GCP match the device manual
  • Response received but parsing fails: Add print("Raw RX: [" + data + "]") to see exact bytes including terminators — often CR vs LF vs CRLF issues
  • Button press fires but device doesn't respond: Add print("Button " + button + " pressed on page " + page) to confirm the handler is firing

Common Pitfalls

  • Event handler blocking the main thread. GlobalScripter event handlers run synchronously on the IPCP Pro's single execution thread. A handler that loops, delays with sleep(), or performs blocking I/O (waiting for a TCP response) prevents all other events from processing — touchpanel buttons become unresponsive, RS-232 receive events queue up, timers miss their intervals. Keep event handlers short: set state, send a command, start a timer, return. Move multi-step sequences to state machines driven by timer callbacks.

  • RS-232 receive buffer not flushed correctly. Device responses often arrive in multiple RS-232_Receive callbacks if the data spans multiple serial frames. A common mistake is processing data directly without buffering — partial responses are parsed as complete messages, causing spurious state changes. Always accumulate into a buffer variable and parse only when a complete delimiter (CR, LF, ETX, or device-specific terminator) is found.

  • GCP device module version mismatch after firmware update. GCP device modules are firmware-version specific. After updating any connected device's firmware, open the System tab, check for module updates for that device, and update before pushing a new program. A mismatched module sends commands that the updated firmware no longer recognizes — the device appears unresponsive despite the control system sending commands correctly.

  • IP device not reconnecting after network interruption. GlobalScripter TCP connections do not auto-reconnect after disconnection. If IP_Disconnect fires and no reconnect logic is implemented, the IPCP Pro stops communicating with the device permanently until the program is restarted. Always implement a reconnect timer in the IP_Disconnect handler.

  • Touchpanel button feedback not updating. Forgetting to call SetButtonState() after a command is sent leaves buttons visually inconsistent — the operator presses "Display On" and the button stays inactive. Implement a poll timer that queries device status and updates feedback rather than assuming commands succeeded. Display RS-232 responses drive feedback, not the act of sending commands.

  • GCP project not saved before upload. GCP does not auto-save. Uploading an unsaved project uploads the last saved version, not the current working state — changes made in the current session are silently skipped. Save (Ctrl+S) before every upload. Enable GCP's auto-save option in Preferences to reduce risk.

We use optional analytics cookies to understand site usage and improve the experience. You can accept or reject.