A vision locate step is good at finding a part and silent about finding none. Most locate tools return a pose when they succeed and simply skip their own block when they fail, so a robot told to pick until the belt is empty waits on a signal that never arrives. This guide shows the standard fix: a flag variable set False before the locate and True only in the branch that runs on a detection, backed by a persistent counter for the batch. You will wire the flag around the locate step, keep the part count across program restarts, choose how many missed detections mean the belt is empty, and hand that result to the robot as an output bit or a register word. A worked example clears a four-part batch off a time-indexed conveyor.
Why a locate result is not a part-present signal
A locate tool outputs a pose and usually a score when it succeeds. When it fails, most implementations return nothing at all: no pose, no zero-count event, no dedicated output bit that says the region was empty. Absence is a state you construct, not one the tool hands you.
That gap is why run-until-empty loops hang. The program repeats locate, pick, index and has nothing to read on the cycle where the belt is clear. Some vision nodes help by behaving like an If statement: their body executes only when a part is detected. That enter-the-node behavior is the hook the flag pattern uses, because the body running is itself the found event.
Wire the flag around the locate step
Two node styles exist, and the flag goes in a different place for each.
- Create the variables with types: found_flag as a Boolean, parts_left as an integer, consecutive_misses as an integer. These names are placeholders for the pattern; keep your controller's naming conventions.
- Initialize found_flag = False at the top of every cycle, before the camera is triggered, never after the locate.
- Trigger the locate at the belt-stop position, with the same exposure every cycle, so that a miss means something.
- If the locate node runs its body only on a detection, make found_flag = True the first statement inside that body, before the pick moves.
- If the locate function returns a result, branch on the found count: in the count-greater-than-zero branch set found_flag = True and copy the pose into the pick positions.
- Read the flag after the locate block: True runs the pick sequence, False runs the belt index or the batch-end routine.
- Decrement parts_left only after grip confirmation, not at locate success. The vacuum gripper signal mapping for vision-guided picking guide shows how to wire that confirmation.
- Reset found_flag = False again at the start of the next cycle, so a skipped cycle cannot inherit a stale True.
Put together, one cycle reads as follows in plain pseudocode, not any vendor's syntax:
found_flag = False # Boolean, reset every cycle before the locate
run locate at the belt stop
if part found then
found_flag = True # set inside the found branch only
run pick
if grip confirmed then
parts_left = parts_left - 1 # integer, installation-level
consecutive_misses = 0
else
consecutive_misses = consecutive_misses + 1
end
if parts_left = 0 or consecutive_misses >= 2 then
batch_end_output = ON
stop indexing
else
index belt by time
end
Count the batch in a persistent variable
A program-scope variable is rebuilt at every program start; an installation-level or persistent variable keeps its value across starts and stops. The part count belongs in the second kind. Write parts_left = 4 from the batch-reset step, decrement it in the found branch after grip confirmation, and mirror it to a register so an HMI can show parts remaining.
Persistence is not a nicety. A mid-batch fault or an emergency stop restarts the program, and a program-scope counter would come back as zero and fire the batch-end output with parts still on the belt. This is the same family of failure as work-area index initialization errors in vision picking, where a value that should survive a restart does not.
Choose how many misses make an empty belt
A single False flag has innocent causes: a runner sliding over the part, belt creep during the exposure, a highlight at the part edge, a part half out of the field of view. None of these proves the region is empty.
Two consecutive misses at the same stop position and the same exposure are different. A part that is really there rarely fails twice in a row unless something physical hides it, so two misses is the practical threshold for declaring the belt clear. Each extra miss in the limit costs one locate cycle plus one belt index; the camera time itself is milliseconds. Raise the limit to three only when a runner can cover a part for a full index step. Where the index itself misbehaves at the end of a station, indexed work area tuning and final-item stops covers that diagnosis.
If a presence sensor later joins the cell as a second opinion, choose it for what it can actually see beside parts and runners: sensor selection for vision-based part detection walks through that choice.
Worked example: clearing four parts off a time-indexed conveyor
Inputs. parts_per_batch = 4 parts, because the cell loads four parts per runner and indexes the belt with a timed output, so every locate sees a stopped belt. miss_limit = 2 consecutive not-found locates, the threshold from the previous section. Frame period = 1/60 s ≈ 16.7 ms, taken from the example sensor below, which reads 60 fps.
Rule in words. The batch-end output fires when parts_left reaches 0, meaning every pick is confirmed, or when consecutive_misses reaches 2, meaning the region is clear and the count is stale.
Arithmetic. Nominal batch: picks confirm one after another, so parts_left = 4 − 4 = 0 and the output fires after the fourth pick with zero misses. Backstop case: the third part falls off its runner, so parts_left stops at 1 after three confirmed picks; the loop indexes twice more, miss 1 then miss 2, and the output fires at parts_left = 1, which the register shows the operator. Locate cycles used: 3 + 2 = 5. Camera exposure for the two checks: 2 × 16.7 ms ≈ 33 ms; everything else in those cycles is belt time the cell runs anyway, so the batch still takes four picks plus four indexes of robot and belt time.
The 60 fps figure comes from a sensor built for exactly this kind of stopped-belt locate. The LS-SMC-0063 smart camera reads 60 fps at 1.6 MP with a 16 mm lens and built-in white light, so the exposure light and the camera arrive as one unit.
- Interface
- GigE
- Resolution
- Up to 3 MP
Decision. Fire the batch-end output from belt_empty, never from the index timer. Keep miss_limit at 2 for parts that present cleanly at one stop, and move it to 3 only if a runner can hide a part for a whole index. At 60 fps each extra miss adds roughly 17 ms of exposure, so the safety net costs locate cycles, not cycle time.
Hand the no-part result to the robot
Three channels carry the result, cheapest first. A discrete output bit from the vision device, labelled for its meaning (no_part_found rather than vision_fault), because fault handlers and batch logic act differently on those two words. A register or fieldbus word holding found_flag and parts_left together, when the robot needs the count for skip logic. A short Ethernet string, a pose line or a plain not-found marker, when the cell already talks TCP.
Sequence the hand-off so a stale bit cannot decide a pick: the robot requests the locate, the vision side asserts a busy signal, then a done signal with the result held steady until read. Gate the robot logic on done AND batch_running, not on the raw bit alone, because most I/O blocks power up with outputs at 0, which would otherwise read as no part before the first locate ever runs.
The same flag-not-fault thinking applies upstream of the cell: trigger the feeder on a flag, not a fault covers the feeder case. On the robot side, keep the found and not-found branches small and push the result toward the motion layer, the way programs are structured around drop targets. A continuous-flow cell gates each pick on the flag exactly as it would gate picking on an upstream reject signal.
Prove the logic before the first production batch
Run five short tests. Together they take minutes and catch every failure mode above.
- Capped-lens run: cover the lens and start the loop. It must stop after exactly 2 misses with the batch-end output on and no pick motion.
- Short batch: load 3 parts against parts_left = 4. The counter path must stay silent, and the 2-miss backstop must fire with parts_left = 1 in the register.
- Full batch: run 4 parts. The output fires exactly after pick 4 and parts_left reads 0.
- Restart test: trip a stop after pick 2, restart, and confirm parts_left still reads 2. That is the persistence proof.
- Stale-flag test: single-step one cycle with a part present, remove the part, run again, and confirm no pick happens on the stale True.
Common mistakes that break the pattern
Five account for most of what goes wrong on the floor:
- Setting found_flag = True at the top of an always-running locate block instead of inside the found branch, which makes the flag permanently True.
- Reading the result before the done signal, so the robot decides on the previous cycle's data.
- Decrementing the counter at locate success instead of grip confirmation, so one missed grip desyncs the count and the batch ends early.
- Keeping parts_left in program scope, so a restart re-zeroes it mid-batch.
- Trusting the timed index to imply the count: the timer moves the belt, but it never knows how many parts are on it, which is why the flag and counter end the batch.
Hardware for the locate step
The vision side of this pattern is small: one sensor per view, or one controller when several cameras share the cell. Browse the smart cameras category or go straight to the camera finder to filter by resolution and interface.
For a locate at a fixed stop position, a compact sensor is enough. The HK-TD032-12-WBN vision sensor pairs a 1.6 MP mono global-shutter imager with an M12 mount on Fast Ethernet, and its result reaches the robot over that link or a discrete output.
- Interface
- Fast Ethernet
- Resolution
- Up to 3 MP
- Sensor format
- 1/2.9"
- Shutter
- Global
When the part occupies a small share of the frame, give the matcher more pixels to hold on to. The MV-SC3050XC-16M-ATN-H is a 5 MP color sensor with a global shutter, also on Fast Ethernet with an M12 mount.
- Interface
- Fast Ethernet
- Resolution
- 5 MP
- Sensor format
- 1/1.45"
- Shutter
- Global
Cells with several cameras, or locate logic that shares results with other stations, belong on a vision controller. The MV-VC3301H-128G66 vision controller runs on an Intel Core i3 with 8 GB of memory, offers 5+ LAN ports and 4 built-in light channels, and includes a VM6200Pro license. There is no PoE on this model, so plan a small switch if your cameras need it, and the light channels drive the exposure lights directly.
- LAN ports
- 5+ LAN ports
- USB 3 ports
- 3-4 USB 3 ports
- Light outputs
- 4 built-in channels
- Memory
- 8 GB
More systems-side patterns are collected on the vision systems topic page, and the vision controllers category lists models by LAN ports, light channels and memory if you would rather filter than read. Set the flag False, count the batch persistently, and the empty belt becomes an output your robot can act on.
Questions
Where should the no-part flag live: in the vision device or in the robot program?
Keep the flag on the side that owns the decision. If the vision device can drive a discrete part-absent output, put it there and let the robot read the bit. If the locate runs inside the robot program, the flag is a program variable next to the locate call. What matters is one owner and a defined False state before each locate, never two systems writing the same flag.
What variable type holds a part count between program runs?
A persistent or installation-level integer, not a program-scope variable. Program-scope data re-initializes at every start, so an emergency stop mid-batch would zero the count and fire the batch-end output with parts still on the belt. Set the persistent integer from the batch-reset step, decrement it only after grip confirmation, and mirror it to a register so the HMI can show parts remaining.
How many missed detections should I allow before calling the belt empty?
Two consecutive misses at the same stop position is the working default. One miss can come from a runner occluding a part, belt creep or an edge highlight; a present part failing twice points to real occlusion or a genuinely clear region. Raise the limit to three only if parts can stay hidden for a full index step. Never stop on a single miss.
Can I run the locate and the empty-belt decision entirely from a script on the robot controller?
Yes, if the controller's vision option exposes a locate call that returns a status or a found count: branch on that return, set the flag in the found branch and keep the counter persistent. When the vision node only runs its body on a detection, set the flag as the first line of that body. Use the return values your controller's vision manual documents rather than guessing them.
Does the flag pattern change if parts arrive continuously instead of in a fixed batch?
The flag logic stays the same; the countdown loses its meaning. Without a known batch size there is nothing to count down, so the stop decision rests entirely on the miss limit, and two consecutive misses remains the safe default. For continuous flow, gate each pick on the flag and let an upstream signal stop the feed instead of a counter.



