A scene variable that shows 5 on the scene display and returns 0 in your macro is not a hardware fault. The value sits in the scene's result storage, and the macro's data-access call copies it only when two conditions hold: the name string matches the registered variable exactly, and the scene has finished executing. Miss either one and the call leaves your variable at its initial 0.
This guide is for engineers writing macros on smart cameras, vision sensors and vision controllers. You will register the result under a clean name, fetch it with the right name and type, place the call after the scene writes its value, and prove the link with a printed number that matches the display.
Why a scene variable reads back as 0
The symptom is always the same: the scene runs, the judge or count step shows a non-zero value on the display, and the macro prints 0. Three causes cover almost every case.
- The name string does not match. The data-access call takes the registered name as a quoted string and matches it exactly. On the flow diagram the variable carries its scene prefix, written sc.q&, but the registered data name is the bare Q&. Passing "sc.q&", "q" or a name without its type suffix finds no variable: the call returns without an error and the target keeps its initial 0.
- The call runs too early. A scene variable is written when the scene finishes executing. A fetch placed before the trigger, or in a step that runs ahead of the measurement, copies the initial value of the target, which is 0.
- The target has the wrong type. The trailing & marks an integer (long) variable in this macro language. The scene variable Q& and the receiving variable must carry the same suffix; a declaration without it creates a different type, and the copy fails.
The macro documentation for these vision systems defines two scopes as well: SC for scene variables and SY for system variables. Reading an SC name from code bound to the wrong scope fails the same silent way.
What you need
- A camera that runs the scene and the macro on the device itself. The smart cameras category covers vision sensors and smart cameras in this role, most with an M12 or C-mount lens.
- The macro editor and the macro customization programming manual for your camera series, which lists GetSceneData and its argument order.
- A scene with one tool that writes a value you can read on the display: a defect count, a judge counter, a position output.
- A place for printed output to land: the editor console, a serial terminal, or a TCP client.
Two on-device units that fit this pattern:
- Interface
- Fast Ethernet
- Resolution
- 5 MP
- Interface
- GigE
- Resolution
- 5 MP
Register the result as a scene variable
- Open the scene and confirm the tool actually writes the value you want: the count increments, the judge result lands, the coordinate updates.
- In the scene data editor (the TDM editor in these flow tools), register a variable with an uppercase name and its type suffix, such as Q& for an integer count.
- Set the variable type to SC, scene variable. Choose SY, system variable, only when several scenes must share one value.
- Trigger once and read the display. It must show the expected number, 5 in the worked example below.
If the display itself shows 0, the problem is upstream of the macro. Fix the scene first: no fetch can retrieve a value that was never written.
Fetch the value by its exact name
The working pattern, with the names from the worked case below (GetSceneData is the documented data-access call; the variable names are illustrative):
MEASUREPROC
Dim IZA&
GetSceneData "Q&", IZA&
Print IZA&
Return
Line by line:
-
Dim IZA&declares the receiving variable as an integer through the & suffix. It starts at 0. -
GetSceneData "Q&", IZA&copies the current value of the scene variable registered as Q& into IZA&. The first argument is a string, and the string is the whole name, suffix included. -
Print IZA&writes the value where you can see it. -
MEASUREPROCandReturnwrap the block as the measurement procedure your flow calls.
Then, in order:
- Declare the target with the same type suffix as the registered variable.
- Call GetSceneData with the bare registered name as a quoted string, copied from the data editor rather than retyped.
- Print the target immediately after the call.
- Trigger once and compare the printed line with the display.
The failing version looks almost identical: the name string carries the scene prefix or loses the suffix, and nothing else changes.
Place the fetch after the scene finishes
Timing is the second half of the fix. The scene writes its result variables when execution completes, so the fetch must come after that point:
Here t_fetch is the time from trigger to fetch and T_scene is the scene's execution time. Measure T_scene once for your scene; a fetch on a fixed delay must sit above it, while a fetch inside the completion procedure satisfies the rule by construction.
- Put the fetch in the step the flow executes after scene execution, such as the completion or measurement procedure.
- Keep it out of any step that runs before the trigger or ahead of the measurement.
- If recipes switch scenes from a PLC, fetch from the scene that actually ran, not from scene 0 out of habit.
Worked example: the scene shows Q& = 5 and the macro prints 0
Inputs, and where each comes from:
- Scene variable Q&, SC type, integer suffix &, registered in the scene data editor; the display reads 5 after a trigger. This is the bench case behind the article.
- Macro target IZA&, declared with Dim IZA& as an integer, initial value 0.
- Data-access call GetSceneData "name", target, as listed in the macro customization programming manual.
- First result: Print IZA& writes 0 while the display shows 5.
The rule in words: GetSceneData copies the current value of exactly the named scene variable into the target; a name that matches nothing returns without an error, and a fetch that runs before end-of-scene copies the initial 0.
The arithmetic is the difference between display and print:
| Run | Fetch placement | Name passed | Display | Display − print | |
|---|---|---|---|---|---|
| 1 | before end-of-scene | "Q&" | 5 | 0 | 5 |
| 2 | after completion | "sc.q&" | 5 | 0 | 5 |
| 3 | after completion | "Q&" | 5 | 5 | 0 |
Run 1 gives 5 − 0 = 5: the fetch is early. Run 2 gives 5 − 0 = 5 again: the string "sc.q&" is not the registered name. Run 3, with the bare "Q&" and the call in the completion procedure, gives 5 − 5 = 0: bound.
Decision: accept the link only when display = print on consecutive triggers, three in a row as a bench rule. Any run where print < display fails, and the order of attack is the name string first, then the placement.
Verify the value end to end
A single match can be a leftover value, so move the truth:
- Add or remove parts so the count moves, from 5 to 7 for instance, and trigger again. The print must follow the display on both runs.
- Print inside the macro before the value goes anywhere. Once the print matches, hand the variable to your communications step: the trigger over TCP with ASCII commands pattern for a PLC, a VB.NET TCP client for a line-side reader, or a detection-score log entry in the robot program when a robot consumes the value.
- Keep the scene variable as the single source of truth and read it fresh every cycle, so a stale number cannot survive a stopped line.
Common mistakes that keep the value at 0
- Casing and suffix. "q", "Q" and "sc.q&" are three different strings; only the registered "Q&" binds. Copy the name out of the data editor.
- Scope mix-up. Reading an SC name where the value lives in an SY system variable, or the reverse, returns the initial 0 with no error.
- Fetch in a procedure the flow never calls. A block that never runs proves nothing; wire it into the flow and confirm it executes on every trigger.
- Edits that detach variables. Renaming or rebuilding steps can break a binding that still displays correctly; re-run the print check after any edit, before the line restarts. The general fix for steps that lose their variables on an edit is its own guide: keeping inspection-step variables wired.
- Name collisions. When several models write into one scene, the first matching result wins, so two tools sharing one registered name will fight; give each result its own name. The multiple-models guide covers the ordering.
- Recipe switches. If a PLC selects scenes over serial, the fetch must read the scene that was selected; the RS232 recipe-selection pattern keeps one command code per recipe, which makes the mapping unambiguous.
Hardware that runs scenes and macros
On-device inspection keeps the scene, the macro and the result variable inside the camera, with no PC in the loop. Mono count and presence checks run well on a compact GigE unit like this one:
- Interface
- GigE
- Resolution
- 6-10 MP
- Sensor format
- 1/2.4"
- Shutter
- Rolling
When several cameras feed one line, the scenes move to a vision controller with camera LAN ports and built-in light channels. The vision controllers category lists the range, and this model includes the vision-platform license and PCIe expansion:
- LAN ports
- 5+ LAN ports
- USB 3 ports
- 3-4 USB 3 ports
- Light outputs
- 4 built-in channels
- Memory
- 8 GB
Where this leaves you
Register the name exactly as the data editor lists it, fetch it in the procedure that runs after scene execution, and trust the print only when it tracks the display across value changes. Those three checks clear the 0 in most macro cases.
For the neighboring integration problems — command triggers, recipe selection, result logging — the systems topic page collects the guides. To size the camera side of a new cell, start in the camera finder, assemble the full set-up in the system configurator, and bring the registered variable name plus the printed line to the contact page if a value still refuses to move.
Questions
Do scene variables keep their value between triggers?
A scene variable holds the last value written into it until the next run overwrites it, so a count can survive a stopped line and look live. Read it once per cycle in the completion procedure and treat any value that arrives without a fresh trigger as suspect. Where several scenes must share one value, register it as an SY system variable, which the macro documentation defines as the machine-wide scope.
Can one GetSceneData call read several scene variables at once?
In the documented form the call copies one named value into one target, so you call it once per variable. Give each name its own matching target, Q& for a count and X& for a coordinate, and group the calls in the same completion procedure so they all read values written by the same scene run. Printing each target directly after its call keeps the trace easy to follow.
What is the difference between SC and SY variables?
SC marks a scene variable, bound to one scene's results; SY marks a system variable, shared across the machine. Use SC for values a single scene computes, such as a defect count, and SY for values that must survive scene changes, such as a running total carried across recipes. Keeping the scopes straight removes one of the silent causes of a 0.
How do I pass the fetched value to a PLC or robot controller?
Print and match it first; only then hand the variable to the communications step. Inside the macro the fetched value is ordinary integer data, so you can format it as text for a TCP command, write it to a serial port, or log it into the robot program without touching the scene. Send it from the same completion procedure that fetched it, so a new cycle cannot overwrite the value mid-transfer.
Why does the variable read 0 again after an edit to the scene?
Edits can rename, renumber or rebuild steps, and a registered variable can lose its binding while the scene still runs and displays a value. After any edit, reopen the data editor, confirm the registered name character for character, and re-run the print check before the line restarts. The same check applies after a recipe change, because switching scenes puts a different variable set behind the same macro.



