Most CNC and HMI screen editors ship no video control, so the Windows camera app cannot be dropped onto the operator screen you build in the editor. The working answer is a companion app: a small window of your own that opens the camera, renders a live preview beside or over the machine screen, and sends jog commands to the machine application. This guide covers the architecture, the one-number fault that stops most first builds, the bandwidth arithmetic with the sums shown, and the camera, card and cable that make a station you can leave running.
What the screen editor can and cannot do
Do not try to host another program's window inside the screen editor. Operator-screen editors expose buttons, labels, DROs and static graphics, and almost none of them has a video control; the built-in Windows camera app cannot be parented into another window either. Write the preview as a companion app instead — one executable, one window, placed beside the machine screen, talking to the machine application when the operator jogs.
One controller package ships a fiducial-measure example built exactly this way: it opens its own window, reads the video device from a plain-text settings file beside the executable, and sends jog requests as messages to the main screen. The main screen has to be running for anything to move.
If your HMI platform does provide a camera view object that accepts a stream from a network camera, use it and skip the custom code — streaming IP camera live video to HMI panels covers that route. Most packages have nothing of the kind. For the rendering side once frames arrive — cursors, zoom, a coordinate readout — see how to embed a camera image in an HMI panel with cursors and zoom.
DirectShow or GenTL: pick the capture path
A Windows app gets camera frames two ways. DirectShow enumerates the video devices Windows already knows: UVC webcams, USB machine cameras, and frame grabbers that expose a DirectShow driver. A GenTL producer enumerates GigE Vision and USB3 Vision cameras and hands you exposure, trigger and pixel-format control. Why a camera shows in one app and not the other is covered in camera listed in one app but not another: DirectShow vs GenTL.
| Situation | Path | Why |
|---|---|---|
| USB webcam or UVC camera, preview only | DirectShow | Windows enumerates it; least code |
| Frame grabber with a DirectShow driver | DirectShow | The card appears as a video device |
| GigE Vision or USB3 Vision camera | GenTL producer | Exposure, trigger and format control |
| The preview doubles as measurement | GenTL producer | Full-resolution frames with a known format |
Commit like this: preview only from a USB device, take DirectShow. Any camera from the area scan cameras range that must also measure, take GenTL, and validate the CTI first — validate a GenTL CTI file before you enumerate shows why. On the DirectShow path, set the capture format at open time; the reference page on configuring the video output format spells out the call.
The device index: 0 is the first camera
The fault that stops most first builds is one number. Windows numbers video devices from 0: device 0 is the first camera found, device 1 the second. The fiducial example above reads its device from a settings file whose default is 1 — the second device — so with one camera attached the preview window stays black and the buttons click with no effect. Setting the number to 0 brought the picture up at once. That one-line change is the whole fix, and it is the first thing to check on any black preview.
Build the companion preview app
- Enumerate video devices at startup and log every name with its index — that log is your map when the picture goes black.
- Read the device index from the settings file and default it to 0, so a single-camera station works on first run.
- Open the device and set the format explicitly: resolution, frame rate, pixel format. A format left at its default is how you get a frame grabber stuck at low resolution.
- Capture on a worker thread, never the UI thread, and keep one frame in flight — isolate capture from rendering so a slow panel cannot stall the camera.
- Scale once to panel size, then render. If most grabs come back black, the snap-versus-grab behaviour is the suspect: USB camera returning black images on most grabs breaks down the difference.
- Draw the crosshair, fiducial marks and any moving ROI in panel coordinates, after scaling, so they track the image at any window size.
- Send jog and move commands as messages to the machine screen application, and start that application before the preview.
- On errors, restart the live preview without reopening the device — re-enumerating on every hiccup can move the index under you.
For the wider architecture — buffers, pacing, paint events — read camera live preview in GUI applications alongside these steps.
Worked example: 12 MP USB3 camera into an 800 × 600 panel
Inputs, with where each comes from:
- Camera: LS-CMR-0166, a 12 MP USB3 camera with a 4000 × 3000 sensor running at 30 fps (its data sheet).
- Stream: 8-bit mono, one byte per pixel — the usual preview format.
- Links: USB3 moves roughly 400 MB/s of image payload (5 Gb/s signalling after encoding and protocol overhead); a 1 Gb/s GigE link moves roughly 110 MB/s.
- Panel: 800 × 600 pixels — an illustrative input; substitute your panel's numbers.
Full frames: 4000 × 3000 = 12,000,000 pixels, and at one byte each that is 12 MB per frame. At 30 fps the camera produces 12 MB × 30 = 360 MB/s, which fits the USB3 payload with about 10% headroom (360 / 400 = 0.90).
Preview side: the scale factor is 4000 / 800 = 5 horizontally and 3000 / 600 = 5 vertically — an exact 5:1 reduction. The rendered frame is 800 × 600 = 480,000 pixels, about 0.48 MB, and at 15 renders per second that is 0.48 MB × 15 = 7.2 MB/s of drawing — nothing an operator panel notices.
Over GigE, the same full frames cap at 110 / 12 = 9.2, so 9 fps. The catalog agrees: LS-CMR-0053 puts the same 12 MP IMX226 sensor on GigE at 9 fps. The decision: 9 to 15 fps is plenty for aiming a part under a spindle, so a GigE preview station gives up nothing that matters; take USB3 when you want true 30 fps motion. Whenever the payload exceeds the link, cap the frame rate or preview a cropped ROI — never render at sensor resolution. Link budgets across interfaces and cable lengths are worked through in 5GBASE-T camera interface: bandwidth, cables and distance, and sharing a USB controller is covered in acquiring from multiple USB cameras: bandwidth and sync.
Camera, card and cable for the station
The station is three parts. The camera: the two 12 MP models above bracket the interface choice — USB3 when you want full-rate motion, GigE when one cable to the switch matters more.
- Sensor format
- 1/1.7"
- Interface
- USB3
- Sensor format
- 1/1.7"
- Lens mount
- C-mount
For GigE, a dual-port PoE NIC powers the camera over its data cable and leaves a port spare:
- Interface
- GigE
- Ports
- 2 ports
When the camera rides a moving axis, specify a drag-chain cable with locking connectors. The LS-CBL-0199 is a 3 m high-flex GigE camera cable built for drag-chain use:
The rest of the station — cards, connectors, lengths — is in frame grabbers and cables. To let the tooling carry lens and light as well, start at the configurator's camera step or the camera finder.
When the preview also measures
The companion app earns its keep when the same image aims fiducials. Size the camera in pixels on target — the rule of thumb is 3 to 5 pixels across the smallest feature you must locate. Covering a 100 mm field of view with the 4000-pixel sensor width (an illustrative input) gives 100 mm / 4000 = 0.025 mm per pixel, so a 0.5 mm fiducial spans 0.5 / 0.025 = 20 pixels — four times the minimum. Run your own field of view through the camera resolution calculator before ordering the lens.
Measure on the full-resolution frame and preview the scaled copy; the measurement never sees the panel-size image.
Checks before you commit
- Enumerate and log device names with indexes at startup; default the index to 0.
- Set resolution, frame rate and pixel format at open time on both capture paths.
- Compute the payload with the formula above and compare it with the link before blaming the software.
- Confirm jog messages reach the machine screen while the preview runs at full rate.
- Order the drag-chain cable when the camera moves with the axis.
- Keep overlays in panel coordinates so they track the image at any window size.
When the usual answer is wrong
- Hosting the Windows camera app inside the screen: it is a store app with no window you can parent, and a borderless overlay loses the first focus change.
- Rendering at sensor resolution: the panel cannot show more than its own pixels, and the CPU pays for the rest.
- Capturing on the UI thread: it freezes the interface, drops frames, and is a classic cause of machine vision screen tearing in live previews.
- Trusting enumeration order across reboots: a re-plugged frame grabber can take index 0 and push your camera to 1.
- Expecting jog commands to work with the machine screen closed: the messages click and nothing moves.
- Building a Windows app at all, when the operators live in a browser: embedding a live camera feed in a web dashboard is the lighter build for that case.
Next step
Assemble the station in the configurator, or send the camera, card and cable list through the contact page and we will check the bandwidth budget with you.
Questions
Why is the preview black when the camera is connected?
Nine times out of ten the app is opening the wrong device. Windows numbers video devices from 0, so an index of 1 points at the second device; with one camera attached there is nothing there, and the window stays black while the buttons still click. Open the settings file beside the app, set the video device number to 0, save, and restart the app. If the picture is still black, the format string is next: some devices open but deliver nothing until a valid resolution and frame rate are set.
Can the Windows camera app be embedded in the machine screen?
No, not as a child window. The built-in camera app is a store application with no window you can parent into an operator screen, and borderless overlays collapse the first time focus changes. Capture the device yourself in a companion app through DirectShow or a GenTL producer and render the frames into your own window; you also gain format control, overlays and machine commands, which the camera app never gives you.
How many frames per second does an operator preview need?
Ten to fifteen frames per second is enough for aiming and jam checks; thirty reads like video. Steady pacing matters more than the peak number: a preview that updates at 12 fps on a fixed interval looks better than one that bursts 30 frames and then freezes. Match the render rate to what the panel needs and leave sensor resolution to the measurement path.
DirectShow or GenTL for the preview station?
DirectShow when the device is a UVC webcam, a USB machine camera or a frame grabber with a DirectShow driver — Windows enumerates it and the code is shortest. GenTL when the camera is a GigE Vision or USB3 Vision model and you need exposure, trigger and pixel-format control, or the frames feed measurement. A camera can appear on one path and not the other, so enumerate on both before you commit.
Do the jog buttons work with the CNC screen closed?
No. The companion app sends jog and move requests as messages to the machine screen application, and that application has to be running to receive them. With it closed, the buttons click and nothing moves — a message with no listener. Start the machine screen first and the preview second, and test the message path end to end before the station ships.



