Your Test System Passes the Part. Does It Know If It Looks Right?
You've got a LabVIEW test system doing everything right — functional testing, data logging, sequences firing in order. But somewhere downstream, quality is catching cosmetic defects, missing components, or wrong labels that your electrical tests can't see. So the question becomes: can the test station catch those too?
The answer is yes — and Cognex makes it easier than most people expect. Cognex In-Sight vision systems support Modbus TCP natively, and LabVIEW has a free NI Modbus library that handles the client side. Connect them over standard Ethernet, map your inspection results to registers, and your test sequence can trigger the camera, read pass/fail, and pull measurement data — all without writing a single line of socket code.
In this architecture, LabVIEW is the Modbus Client (Master) and the Cognex In-Sight camera is the Modbus Server (Slave). In Modbus, the Client is the device that initiates all communication and requests data, while the Server waits for requests and serves the data back. LabVIEW is the Client because it controls the flow: it decides when to trigger the camera, when to poll for results, and when to pull measurements. The Cognex camera stores inspection data, status bits, and pass/fail results in its internal memory registers — LabVIEW reads those registers on demand. To start an inspection via software, LabVIEW writes a value to the camera's trigger coil (register 0). The camera processes the image and makes results available in its registers for LabVIEW to read.
I've used this architecture on several production lines where the customer wanted a single test station that validated both electrical function and visual quality. This is how it works.
Why Modbus TCP?
Cognex In-Sight cameras support several communication protocols — EtherNet/IP, PROFINET, FTP, and TCP string output among them. So why reach for Modbus TCP?
No licensing cost
Modbus TCP is an open standard. No EDS files, no additional licenses, no Cognex SDK required — just the camera firmware you already have.
Native NI support
NI's free Modbus library gives you clean, high-level VIs. Read registers, write coils — it reads like plain English compared to raw TCP socket frames.
Deterministic register map
Your inspection results live at fixed addresses. No parsing XML strings, no regex on ASCII output — just read register 40001 and you get your measurement.
Works on any NI target
Windows PC, cRIO Real-Time, PXI — Modbus TCP runs over standard Ethernet on any NI platform that supports TCP/IP. No OS-specific dependencies.
Modbus TCP isn't glamorous. It's a 1970s industrial protocol running over a 1990s network stack. That's exactly why it still works on everything — and why it'll still work on your test station in 15 years.
Step 1 — Configure the Cognex Camera
Everything starts in In-Sight Vision Suite, Cognex's desktop configuration software. You don't need to write code on the camera side — you configure the Modbus TCP mapping through the GUI.
Enable Modbus TCP on the Camera
In In-Sight Vision Suite, navigate to Sensor → Communications → Industrial Protocols. Enable Modbus/TCP and set the port (default is 502). The camera will reboot — after that it's listening as a Modbus TCP Server (Slave) on that IP, ready to receive commands from LabVIEW acting as the Client (Master).
Map Job Results to Registers
In the In-Sight spreadsheet view, every cell output can be mapped to a Modbus register address. Right-click a cell containing an inspection result and select Cell Properties → Industrial Protocols → Modbus. Assign it a register number. Common mappings look like this:
| Register | Type | Description | Direction |
|---|---|---|---|
| Coil 0 | Bit | Trigger / Acquire (LabVIEW writes HIGH to fire camera) | LabVIEW → Cognex |
| Coil 1 | Bit | Soft Event 1 — job change or reset (optional) | LabVIEW → Cognex |
| IR 0 | Bit | Inspection Complete — HIGH when result is ready | Cognex → LabVIEW |
| IR 1 | Bit | Overall Pass (1) / Fail (0) | Cognex → LabVIEW |
| HR 0 | 16-bit Int | Scaled measurement value #1 (e.g. diameter × 1000) | Cognex → LabVIEW |
| HR 1 | 16-bit Int | Scaled measurement value #2 (e.g. position offset × 1000) | Cognex → LabVIEW |
| HR 2 | 16-bit Int | Fault code / error register (0 = no error) | Cognex → LabVIEW |
| HR 10 | 16-bit Int | Active job number (write to change jobs) | Both |
IR = Input Register (read-only from LabVIEW, set by the camera). HR = Holding Register (readable and writable by both sides). Coils are single-bit outputs that LabVIEW writes to control the camera.
Keep your register map in a spreadsheet alongside your LabVIEW project documentation. When someone modifies the Cognex job 18 months from now, the register assignments survive the tribal knowledge problem.
Step 2 — Implement the LabVIEW Modbus Client
Download the NI Modbus Library from ni.com — it's free and installs into LabVIEW's function palette under Data Communication → Protocols → Modbus. The API is straightforward:
1 — Create the Modbus Client (Master)
Call Modbus Client API - Create.vi (labeled Modbus Master API - Create.vi in the NI library) with the camera IP address and port 502. This returns a refnum you'll pass to every subsequent VI. Create it once at test startup — not inside a loop.
2 — Write the Trigger Coil
Call Modbus Master API - Write Single Coil.vi (Client write), targeting Coil address 0, value TRUE. This fires the Cognex acquisition. Some setups use a rising edge — write TRUE, wait one scan, write FALSE.
3 — Poll for Inspection Complete
In a timed loop, call Modbus Master API - Read Discrete Inputs.vi (Client read) on Input Register bit 0. When it goes HIGH, the inspection result is ready. Add a timeout so a camera failure doesn't hang your test.
4 — Read Pass/Fail and Measurements
Call Modbus Master API - Read Input Registers.vi (Client read) to read IR bit 1 (Pass/Fail) and Modbus Master API - Read Holding Registers.vi for your measurement values. Convert integer registers back to engineering units by dividing by your scale factor (e.g., ÷ 1000 for mm).
5 — Reset and Close
Write Coil 0 back to FALSE to reset the trigger. At test shutdown, call Modbus Master API - Close.vi (Client close) to release the TCP connection cleanly.
A typical inspection sequence completes in under 200 ms — well within the cycle time of any LabVIEW test sequence, without blocking your other test logic in any meaningful way.
LabVIEW Example: Connecting and Reading the Payload
The screenshot below shows a working LabVIEW block diagram for communicating with a Cognex In-Sight camera over Modbus TCP. It demonstrates the core sequence you'll build for any vision integration: establish the connection, set the camera online, read the status register, and pull the payload.
Online / Offline Control — Bit 7, Address 0
Before you can trigger an inspection, the camera must be set to Online mode. This is done by writing to Coil address 0, bit 7. Writing a 1 brings the camera online (ready to inspect); writing a 0 takes it offline. You'll typically set the camera online once at test startup and take it offline on shutdown — not between every inspection.
Reading the Status Register
After triggering an acquisition, the example reads the status register to determine when the camera has completed its inspection. Each bit in the status register carries specific meaning (inspection complete, pass/fail, error flags, and others), but the full bit-by-bit interpretation is outside the scope of this screenshot — refer to the Cognex In-Sight Vision Suite industrial protocols reference for your firmware version.
Reading the Holding Registers — 125-Register Payload
The example reads 125 holding registers in a single Modbus read request — the maximum allowed per Modbus TCP frame. This block of registers is the payload: the user-defined variables you configure in In-Sight Vision Suite as part of your machine vision inspection job. When you develop your job in Vision Suite, you define which inspection outputs (measurements, scores, counts, presence/absence results) get mapped to which holding register addresses. LabVIEW reads the entire payload at once and then indexes into the array for the specific values it needs.
While this example reads the payload, the same pattern can be modified to write values — allowing your LabVIEW application to pass parameters to the inspection job. For example, you could write tolerance limits, recipe numbers, or part-specific thresholds to holding registers that In-Sight Vision Suite reads during job execution. This makes the vision system dynamically configurable from LabVIEW without changing the job on the camera.
Keep your payload register map documented in your LabVIEW project. Every register offset only has meaning relative to the Vision Suite job that defined it — if the job changes, the offsets change.
Dealing With 16-Bit Integer Registers
This is where engineers hit their first snag. Modbus registers are 16-bit unsigned integers — they hold values from 0 to 65,535. A measurement in millimeters with three decimal places of precision doesn't fit in that naturally.
Cognex handles this with a scale factor. You configure the scale in In-Sight Vision Suite when you map the cell to a register. A scale of 1000 means the camera stores 12.345 mm as integer 12345. In LabVIEW you divide by 1000.0 to recover the floating-point value.
// LabVIEW pseudo-logic for reading a scaled measurement:
rawRegister = ModbusClient_ReadHoldingRegister(refnum, address: 0) // NI VI: Modbus Master API - Read Holding Registers.vi
// rawRegister = 12345 (integer)
measurement_mm = rawRegister / 1000.0
// measurement_mm = 12.345 (DBL)
// Compare against your test limits:
pass = (measurement_mm >= lowerLimit) AND (measurement_mm <= upperLimit)What About Negative Values?
If your measurement can go negative (a position offset, for example), Cognex uses a signed 16-bit integer (range −32,768 to 32,767). LabVIEW's Read Holding Registers returns U16 by default — you'll need to cast to I16 first before dividing by your scale factor. Miss that cast and a −1.5 mm offset comes back as 64,035.
Floating-Point Registers (Two-Register IEEE 754)
Some Cognex firmware versions support transmitting floating-point values as two consecutive 16-bit registers in IEEE 754 format. If your job is configured this way, read registers N and N+1, concatenate the two U16 values into a U32, then use LabVIEW's Type Cast function to reinterpret as SGL. No scaling math needed.
Fitting It Into Your Test System Architecture
The cleanest pattern is a dedicated Vision Loop running in parallel with your main test sequence. The Vision Loop owns the Modbus TCP connection and exposes a simple functional API to the rest of your test system:
LabVIEW Test Sequence
Calls "Trigger Vision" and "Get Vision Result" as steps. Doesn't know or care about Modbus, registers, or IP addresses. Just gets back pass/fail and measurements.
Vision Manager Loop (LabVIEW)
Owns the Modbus refnum. Handles trigger, polling, timeout, error recovery, and register parsing. Communicates with the sequence via queues or a functional global.
Cognex In-Sight Camera
Runs the inspection job. Returns results as Modbus TCP register values. Completely standalone — can also operate independently of LabVIEW if needed.
Multiple Cameras
Need more than one camera? Create multiple Modbus Client (Master) instances — one per camera IP. Each gets its own Vision Manager loop, or you can run them in sequence from a single loop if cycle time allows. The register maps can be identical across cameras since each connection is independent.
Changing Cognex Jobs from LabVIEW
If your test station runs multiple part configurations, you can change the active Cognex job by writing to Holding Register 10 (or whatever register you've mapped to Job ID in Explorer). Write the job number, wait for the camera to acknowledge in a status register, then proceed with testing. No operator intervention required — the part configuration drives the vision setup automatically.
Build your register address assignments as LabVIEW constants or an enum — never hardcode raw numbers in your logic. When the Cognex job gets rearranged, you change one place, not twenty.
Error Handling You Actually Need
The Modbus connection will drop. The camera will reboot. The inspection will time out. None of these should crash your test station — plan for them explicitly.
Camera not reachable at startup
Attempt Modbus Client (Master) Create with a short timeout. If it fails, surface a clear operator message: "Vision system offline — check camera power and network." Don't let a missing camera silently skip vision checks.
Inspection Complete never goes HIGH
Set a hard timeout — 2 seconds is generous for most inspections. On timeout, log an error code, report the vision step as inconclusive, and optionally attempt one retry. Never hang waiting indefinitely.
TCP connection dropped mid-test
The NI Modbus VIs will return an error cluster. Catch it, attempt one reconnect (Close + re-Create), and if that fails, abort the test sequence gracefully. Log the Modbus error code — it tells you whether it was a timeout, refused connection, or network reset.
Fault code register shows non-zero
Read HR 2 (or your fault register) after every inspection. A non-zero value means the Cognex job itself flagged an internal error — wrong exposure, missing calibration, or a job runtime fault. Treat this as a test error, not a part failure.
The Bottom Line
Cognex and LabVIEW over Modbus TCP is one of the cleanest integrations in industrial test automation. The protocol is simple, the NI library does the heavy lifting, and the Cognex side is configured entirely in Explorer without touching code. You get a fully integrated test station — electrical and visual — with a communication layer that a new engineer can understand in an afternoon.
The tricky parts are all in the details: signed vs. unsigned register interpretation, scale factors, timeout logic, and keeping your register map documented. Get those right and the integration is rock-solid.
If you're adding Cognex to an existing LabVIEW system or building a new test station that needs integrated vision — we've done it. Reach out and we can talk through the architecture for your application.
