Crimson 3: Reference Page Properties and Log Startup Events

Tom Garrett9 min read
HMI ProgrammingRed LionTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Overview

Red Lion's Crimson 3 configuration software programs the Graphite®, G3, G3 Kadet, and legacy Data Station families (DS, DSP, DSC) of operator panels and protocol-conversion controllers. Crimson treats every page on the operator interface as an object that exposes a fixed set of read-only string properties at runtime. The most commonly referenced properties are page.label and page.desc. They can be embedded into any expression or text field that expects a string, allowing the programmer to display the active page name, a longer descriptive caption, or to drive logic that reacts to which page is currently in view.

This reference covers two closely related Crimson programming tasks:

  1. How to embed page metadata (label, description) into expressions, dynamic text, and data fields without the compiler prompting you to "create a tag."
  2. How to log a single, reliable power-up event from the Data Station/Graphite controller using page-global actions, the Sleep() function, and edge-triggered alarms.

Both patterns rely on the same Crimson expression evaluator and the same rule: an object property is referenced with the literal object name (the page as configured in the Pages tree) followed by a period and the property identifier. The reserved word page alone is not a valid Crimson identifier and will raise the "cannot find an identifier…" prompt if used unqualified.

Prerequisites

  • Crimson 3.2 (or current 3.x release) installed on the engineering workstation. The build is available from the HMS Networks software portal at https://www.hms-networks.com/sw/crimson/32.
  • A working Crimson 3 database (.cdb) targeting a Red Lion HMI or Data Station that supports runtime expressions (Graphite G3, G3 Kadet, DS/DSP/DSC series, or equivalent).
  • Familiarity with the Crimson workspace: Navigation Tree on the left (Database, Comm, Display, Logic), Properties grid on the right, and Systems tab (lower-right) where functions such as Sleep() are listed.
  • The Crimson 3 User Manual for reference on function signatures and alarm/event configuration, available as CRIMSON 3 USER MANUAL (PDF).
  • If you plan to verify expression behavior without a physical panel, install the Crimson emulator so projects can be run on the engineering PC.

Crimson Page Object Model

Every page created under the Display → Pages branch is a compiled object in the runtime database. Crimson exposes two string properties on each page object by default:

Property Type Source Purpose
page.label String Page → Label field in Properties Short caption shown in tab strips, navigation buttons, and dynamic text.
page.desc String Page → Description field in Properties Longer human-readable description, typically used for help text and audit logs.

The property must be qualified with the actual page name as it appears in the Pages tree. The literal token page is a reserved keyword in Crimson and is not a valid object reference. Crimson 3 treats any unresolved identifier as a tag name and will offer to create one — that prompt is the diagnostic symptom of using an unqualified or misspelled page name.

Referencing Page Properties in Expressions

Any Crimson text or data expression that resolves to a string can read page properties. The leading = character is required so Crimson treats the token as an expression instead of a literal text constant.

Step-by-step

  1. Open the target page in the Display editor.
  2. Drop a Text or Data field onto the canvas.
  3. In the field's Source property, select Expression.
  4. Enter the page reference with the leading equals sign:
    =Main.label — returns the label of the page named Main.
    =Overview.desc — returns the description of the page named Overview.
  5. Build the project and run it (or simulate in the emulator). The field now reflects the live string property of the named page.
Use the exact page name from the Pages tree, including case. Crimson identifiers are case-sensitive. If the editor offers to "create a tag" when you press Enter, the name does not resolve to an existing page object.

Expression Examples

Goal Expression Notes
Show label of page named "Main" =Main.label Reads the Label property verbatim.
Show description of "Overview" page =Overview.desc Use when you need more than the short label.
Concatenate a static prefix and a page label =("Active Screen: " + Main.label) Standard string concatenation.
Conditional label based on current page =(GetActivePage()=="Main" ? Main.label : Other.label) Returns the label of whichever page matches the active page name.
Trigger an action when page becomes active (GetActivePage()=="Alarms") ? 1 : 0 Boolean-style 1/0 expression commonly used to enable a write or an event.

The GetActivePage() function returns the name string of the page currently displayed, which makes it possible to build logic keyed off the page name without referencing each page object directly.

Logging a Startup Event in Crimson 3

A common commissioning task is to log one event every time the Data Station or Graphite panel boots. The naive approach — incrementing a tag inside an On-Start action and letting an edge-triggered alarm fire on the mismatch — usually fails because the runtime evaluates the alarm condition before the action body has had time to update the tag value, so the alarm never sees a transition.

Why the Alarm Never Fires

  1. On power-up, Crimson initializes all tag values from retentive storage (or zero for non-retentive tags).
  2. The On-Start action attached to a page (or the Global On-Start action) is queued.
  3. The alarm engine compares the current tag value to the alarm's stored "last value" reference.
  4. If the action that increments the tag has not executed yet, the current and last values match, and the edge-triggered alarm sees no transition — no event is logged.

Manually clicking Increment in the emulator later works because the action executes immediately while the alarm engine is already armed.

Reliable Startup Event Pattern

The fix is to (a) delay the value change so the alarm engine has time to arm, and (b) force the alarm engine to see a true 0 → 1 edge after that delay.

  1. Create a tag named Startup. Mark it non-retentive so it always powers up at 0.
  2. Under Display → Pages → Global Actions → On Start, enter a program that delays before it writes:
    Sleep(1000);
    Startup = 1;
  3. Create an alarm on the Startup tag with:
    Event Mode: Data Mismatch
    Trigger: Edge-triggered (rising, 0 → 1)
    Alarm Value: Last Value (so the comparison is against the previously latched state)
    Event Text: Controller Power-Up (the literal string written to the event log when the edge is detected)
  4. Enable the alarm in the alarm configuration grid.
  5. Build, download, and cycle power. The single delayed write forces the alarm engine to observe a true transition; exactly one event is appended to the log.

Alternative: Non-Retentive Edge-Triggered Flag

If you do not need to count startups, replace the integer tag with a non-retentive Boolean flag and skip the alarm altogether. Use a Global On-Start program:

Sleep(1000);
Flag = 1;
LogEvent("Controller Power-Up");

The Sleep() call delays execution long enough for the runtime services to stabilize; LogEvent() writes a custom entry directly into the data logger without depending on the alarm engine at all.

Program Reference

Function Signature Behavior
Sleep Sleep(ms); Suspends the current action thread for the specified number of milliseconds. Use to let the alarm engine arm before mutating a tag.
GetActivePage GetActivePage(); Returns the name of the currently displayed page as a string.
LogEvent LogEvent(text); Appends a string entry to the controller's event log. Independent of the alarm subsystem.
Page.label / Page.desc =Name.label Returns the configured Label or Description string of the named page.

All function names are case-sensitive and must match the entries shown in the Crimson Systems tab. If the function is dimmed in the editor's autocomplete, it is not available on the selected target.

Verification

  1. Compile the database. A clean build means every =PageName.label reference resolved to an existing page object.
  2. Run in the emulator and click through each page. The data/text fields driven by page properties should update immediately when the page label/description is changed in the Properties grid.
  3. Cycle power on the target hardware (or use File → Reset in the emulator to simulate a cold start). Wait at least one second for the Sleep(1000) window to elapse.
  4. Inspect the event log on the panel (Main Menu → Status → Event Log) or via the Web Manager. Exactly one "Controller Power-Up" entry should appear per power cycle.
  5. Confirm non-retentive behavior: power-cycle twice. If the counter increments on every boot, the tag is retentive and the count will persist through a power loss; if it logs once per boot, the pattern is correct.

Troubleshooting Matrix

Symptom Likely Cause Resolution
Editor offers to "create a tag" when typing =page.label The literal token page is not a valid object identifier. Replace with the actual page name, e.g. =Main.label.
Field displays nothing at runtime Page name typo, or the field's Source property is set to Literal instead of Expression. Set Source to Expression, retype the page name, and rebuild.
Startup event does not appear after power-up Action incremented the tag before the alarm engine armed; no edge detected. Insert Sleep(1000); before the increment, or use LogEvent() directly.
Multiple startup events logged per boot Tag is retentive and never resets; edge retriggers on value roll-over. Mark the tag non-retentive, or add an explicit reset (Startup = 0;) inside the On-Stop action.
Function name appears dimmed in autocomplete The selected target firmware does not support that function. Update the firmware on the controller or substitute an equivalent built-in.
Property returns stale value after editing the page label Database not re-downloaded to the panel. Rebuild the project and send it to the controller.

Field-Proven Caveats

  • Do not place Sleep() calls inside actions attached to high-frequency events (periodic polling faster than 1 s). Long sleeps on fast triggers will queue action threads and starve the runtime.
  • Page property references are evaluated at render time. If you change a page label at runtime through a Dynamic Property binding, the =PageName.label expression reflects the new value on the next refresh.
  • Crimson's expression evaluator returns an empty string when a referenced property is unset. Build the project to catch unresolved identifiers at compile time rather than at commissioning.
  • For UL-listed installations, event-log retention depends on the controller's storage class; verify with the Graphite® or Data Station datasheet that the chosen log destination supports the retention period required for your audit trail.

FAQ

Can I use the reserved word page by itself in a Crimson expression?

No. page is a reserved keyword, not an object reference. You must use the exact name of the page from the Pages tree, for example =Main.label. If the editor offers to create a tag, the page name did not resolve.

Where can I use =PageName.label in Crimson 3?

Anywhere a string expression is accepted: Text and Data fields with Source set to Expression, dynamic label bindings, conditional logic that compares strings, and program-side string operations. Always prefix the reference with the equals sign so Crimson evaluates it as an expression.

Why does my edge-triggered alarm never fire on power-up?

The On-Start action runs before the alarm engine has armed, so the increment is invisible to the alarm comparator and no 0 → 1 transition is detected. Insert Sleep(1000); before the increment, or write the event directly with LogEvent("Controller Power-Up"); to bypass the alarm engine.

Do I need a retentive tag to count startups?

No. A non-retentive tag always powers up at 0, so the edge is deterministic on every boot. Use retentive storage only if you specifically need the count to survive a power loss.

Where is the Crimson 3 software and user manual obtained?

Download Crimson 3.2 from HMS Networks — Crimson 3.2, browse additional tools at HMS Networks Support — Software and Tools, and consult the Crimson 3 User Manual (PDF) for the full function reference and alarm configuration details.

Back to blog