You put a device into standby, disconnect, reconnect and call Start(): it returns true, the callback never fires and no preview image arrives. This hits serial-attached cameras, packaged code readers and integrated vision units that expose a low-power mode over their control link. The disconnect is the red herring — the device kept the state your last session left it in, and reopening a connection never touches it. This guide ranks the causes, gives a test for each and lays out a wake sequence with a worked timing budget, so you replace sleep-and-retry with a deterministic startup. The short version: wake the device, confirm it reports active, then start the stream.
The symptom: Start() succeeds and nothing streams
The signature is a start call that reports success while the image path stays silent: no frames, no callback, no error. The boolean you got back says the control channel accepted the request. That channel is alive — it is how you sent the command — so acceptance tells you nothing about the image pipeline. On a device still in standby the sensor is parked and the pipeline never runs, yet nothing on the host side raises an error.
The confirming detail: a throwaway transaction on the same control channel — a login or authentication call — makes the preview work immediately afterwards. That transaction is the wake-up. The device was asleep, not faulty, and Start() was simply the wrong first move.
Why a reconnect never clears standby
Power state lives in the device, not in your connection. Connect and disconnect open and close a transport: a serial session, a USB enumeration, a TCP link to a camera. None of that resets the electronics. Exactly two things clear standby — the wake command, or removing power — and a reopen does neither. Reopening rebuilds your host-side session and nothing more; restart a live camera preview without reopening the device covers what a reopen can and cannot recover on the stream side.
Standby is deliberate engineering on the device side: small controllers stop the core clock, keep only a wake interrupt alive, and need their clocks settled before they parse anything. Some designs react to line activity — the reconnect traffic itself — but while the clocks settle they can swallow the first command they receive, which looks exactly like no wake at all. Close order matters for the same reason: park the stream before you park the link, as stopping acquisition before you close shows from the timeout side.
Causes in order of probability
Work down this table. Row 1 explains most of these field cases; row 2 most of the rest.
| # | Cause | The tell | The test | The fix |
|---|---|---|---|---|
| 1 | Device still in standby after the reconnect | A login or wake transaction makes the stream work | Read the power state after connecting; send the wake and watch for active | Wake, poll to active, then start |
| 2 | Stream object went out of scope | The device streams and byte counters climb, but no callback fires | Move the stream handle from a local variable to a field | Hold the reference for the stream's lifetime |
| 3 | Wrong camera index | Another camera responds; index 0 selects a different unit | Enumerate the cameras and match serial numbers | Select by device identifier, not position |
| 4 | Link degraded after the reconnect | Enumeration is intermittent or the status is not Ok | Swap the port and cable; read the link error counters | Fix the physical layer first |
The quiet second cause: the stream object left scope
A stream or preview handle created inside an if block becomes unreachable the moment the block exits. The garbage collector reclaims it, the event subscription dies with it and your callback is never invoked — with no error anywhere in the log. Keep the handle as a field on the class that owns the session, and attach the callback before Start(). When a demonstrably streaming device delivers no callbacks, read multi-camera acquisition freezes: callbacks and buffer queues: unreachable handlers and starved buffer queues look identical from the outside.
Tests that separate the causes
Run one pass, not four theories:
- After the reconnect, read the device's reported power state. Standby or unknown points at row 1.
- Send the wake transaction, poll until the state is active, then start. Frames inside the deadline close the case: it was standby.
- Device reports active and streaming but callbacks stay silent: inspect object lifetimes — row 2.
- Enumerate the cameras and match the serial number of the unit you aimed at — row 3. An index convention you cannot find in writing is not something to build a station on.
- Connect status not Ok, or enumeration itself flaky: physical layer — row 4. USB link checks after a cable swap is the systematic version of that pass.
The wake sequence that works
- Connect and require an Ok status before anything else.
- Read the reported power state. Treat unknown as standby; a reconnect leaves you no basis for optimism.
- If it is not active, send the documented wake — the transaction your login path performs counts, because that is exactly what made the preview work in the reported case.
- Poll the state every 50 ms and cap the wait at 3 s. A bounded loop, never an open one.
- Create the stream as a field, attach the callback, then call Start().
- Demand a first frame inside a deadline: 30 frame periods or 2 s, whichever is smaller.
- On timeout, stop and move to row 2 of the table. Do not resend Start() and hope.
Configuration belongs before the start call on any camera; setting the GigE camera packet size before starting acquisition is the same ordering rule on the network side.
// Illustrative class and method names: substitute your SDK's real ones.
DeviceLink link = new DeviceLink(portName: "COM2"); // serial control link
link.Connect(); // require Ok
if (link.DeviceState() != PowerState.Active)
{
link.Wake(); // the documented wake transaction
int waitedMs = 0; // bounded poll: 50 ms steps, 3 s cap
while (link.DeviceState() != PowerState.Active && waitedMs < 3000)
{
Thread.Sleep(50);
waitedMs += 50;
}
}
StreamHandle stream = new StreamHandle(cameraIndex: 0); // hold this as a field, not a local
stream.OnFrame += FrameReceived; // callback attached before start
bool accepted = stream.Start(); // transport acknowledgement only
// Pass condition: FrameReceived fires within 1000 ms at 30 fps — 30 frame periods.
Worked example: the wake-to-first-frame budget
Numbers for a representative station. The LS-CRD-0028 is a 2560 x 2048 fixed code reader that runs at 30 fps and reads up to 60 codes/s with an 8 mm lens. At 30 fps a frame is due every 33 ms (1 ÷ 30 = 0.033 s); 60 codes/s is one decode every 17 ms (1 ÷ 60 = 0.017 s).
Now the control side. Assume a 16-byte wake command on a 115200 bit/s serial link, 10 bits per byte (start, eight data, stop):
| Step | Time | Where it comes from |
|---|---|---|
| Wake command on the wire | 1.4 ms | 16 × 10 = 160 bits at 115200 bit/s |
| Controller restarts its clocks | 200 ms | worst-case wake latency of a small controller |
| Poll sees the active state | 50 ms | one 50 ms poll interval |
| Start call | 10 ms | control round trip |
| First frame | 33 ms | 1 ÷ 30 fps |
| Total | 294 ms | sum of the rows above |
Check the arithmetic: 1.4 + 200 + 50 + 10 + 33 = 294.4 ms, which rounds to the 294 ms in the table — call it 0.3 s. The tempting fix, a 3-second wait after the disconnect and another after the reconnect, costs 3000 + 3000 = 6000 ms, about twenty times the deterministic path (6000 ÷ 294 ≈ 20), and it never changes the device state. On a line rated 60 codes/s, 6 s of dead time is 6 × 60 = 360 codes of lost capacity; the wake path costs 0.294 × 60 ≈ 18 codes. And the 1 s first-frame deadline at 30 fps is 1000 ÷ 33 = 30 frame periods, so a stream that misses it is not slow — it is not running.
What not to do
- Do not treat the return value of Start() as proof of frames. It is a transport acknowledgement; gate success on the first frame.
- Do not stack sleeps. They mask row 1 and burn cycle time — 6 s against 0.3 s in the budget above.
- Do not resend Start() in a loop. Without a state check you are adding commands to a pipeline that has not been switched on.
- Do keep the login transaction as the wake if that is what the interface documents — but name it as a wake in your code, and still poll for active.
- Reach for the power cycle last. Removing power always clears standby, but it also drops everything held in volatile memory: a camera losing its settings after a power cycle is that failure seen from the other side, and GigE Vision image corruption after a camera power cycle is its neighbour on the same bench.
Parts and wiring that make the fix clean
A hardware fallback needs wire you can land on a PLC output — a wake line or switched power — brought out through power and I/O cables. The LS-CBL-0300 is an M8 8-pin power and I/O cable, 7 m, built for drag-chain use.
- Type
- Power and I/O cables
- Length
- 6-8 m
On the reader side, serial-attached units are where standby and wake commands live. Two ends of the fixed code readers range:
- Interface
- Serial
- Resolution
- 16-25 MP
- Interface
- Fast Ethernet
- Resolution
- 5 MP
The MV-ID6200PM-00C-NNG is a 20 MP logistics code reader with a serial interface; the LS-CRD-0028 carries the numbers used in the budget above. For area scan cameras on Ethernet, many GigE units take power over the network port, which makes a switch-port cycle a clean remote reset — check whether your camera supports PoE before designing recovery around it. A compact GigE color camera like the MV-CU020-90GC is the class of unit this applies to.
- Sensor format
- 1/1.7"
- Lens mount
- C-mount
- Interface
- GigE
- Resolution
- Up to 3 MP
Checklist: startup handling that ships
On connect
- Require an Ok status; log the connect timestamp.
- Read the power state; treat unknown as standby.
- Match the camera by serial number, not by index.
Before start
- Wake sent, state polled to active: 50 ms steps, 3 s cap.
- Stream handle held in a field; callback attached before Start().
- First-frame deadline armed: 30 frame periods or 2 s, whichever is smaller.
On disconnect
- Stop the stream, then send the standby, then close the link — in that order.
- Record the state you left the device in, so the next connect knows what to expect.
The decision for each case
- Reported state is standby or unknown after the reconnect: wake, poll to active, then start. Delete the sleeps.
- Device active and streaming, callbacks silent: the stream object is unreachable — hold it in a field for its lifetime.
- Enumeration intermittent or status not Ok: fix the physical layer before touching code.
- No wake command anywhere in the interface: use the login transaction as the wake, or wire switched power and cycle it. Take the wake path first — 0.3 s against several seconds, every cycle.
If you are specifying the station rather than debugging it, the camera finder filters by interface and mount, the system configurator walks camera, lens and light in order, and the accessories finder lists the I/O cable for a wake line. For a device whose standby behavior is unclear, send the model and its control documentation through the contact page and we will map the wake path with you.
Questions
Does removing power clear standby when nothing else works?
Yes. Cutting power returns the device to its power-on default, which is the active state on industrial cameras and code readers, so it always works as a fallback. It also drops everything held in volatile memory and takes longer than a wake: hundreds of milliseconds against seconds. On a camera powered over Ethernet you can cycle the switch port instead of unplugging the connector.
Why does Start return true when no frames will arrive?
Because the value reports that the control channel accepted and queued the request, not that the image pipeline is running. On a device still in standby the link is alive — that is how you sent the command — so the call succeeds while the sensor stays parked. Report the mismatch to the vendor as an interface defect, but design around it: gate success on a first frame, never on the return value.
How long should I wait for the first frame before declaring failure?
Set the deadline at 30 frame periods or 2 seconds, whichever is smaller. At 30 fps that is 1 s: 1000 ÷ 33 = 30 frames. The basis: a streaming device delivers continuously, so 30 missed periods mean nothing is coming, while normal exposure and transfer variation sits inside one or two periods. Fail fast into the cause tests instead of waiting longer.
Do GigE and USB3 machine vision cameras have standby modes?
Most industrial area scan cameras do not ship one: they idle between AcquisitionStart and AcquisitionStop but hold full power. The failure that looks identical is TriggerMode left on with no trigger pulse arriving, or lighting that never fires, so read AcquisitionMode and TriggerMode before assuming a power state. Packaged units — code readers, vision sensors, integrated devices — are where standby and wake commands are common.
Can the wake command itself get lost?
Yes. Controllers that sleep by stopping the core clock wake on line activity, then need their clocks settled before they parse anything — the first bytes after wake can be swallowed. That is why the sequence polls the reported state instead of trusting a single shot. The poll loop is what makes it reliable; the timeout is what keeps it safe.



