Cameras & sensorsHow-to

Thermal camera data via RTSP and Modbus TCP on embedded Linux

Pull image and temperature data from a fixed thermal camera with no GenICam SDK: an RTSP client for the frames, Modbus TCP registers for the readings, on a Pi.

LumaSpec Vision10 min citit Distribuie pe LinkedIn

Pe această pagină 9 secțiuni
  1. 01Decide first: Vision camera or appliance
  2. 02What you need
  3. 03Bring up the RTSP stream
  4. 04Read the temperatures from Modbus TCP registers
  5. 05Worked example: does a 640 × 512 radiometric stream fit the network?
  6. 06Verify before you trust the numbers
  7. 07Common mistakes
  8. 08When the Vision camera is the simpler build
  9. 09Questions

Fixed thermal monitoring cameras — the kind that watch switchgear, kilns or gas plumes — often ship as closed appliances. Their vendor SDK targets a desktop OS, and no build of it exists for your embedded Linux board. You do not need it. The same Ethernet port exposes two standard services: an RTSP video stream for the image, and a Modbus TCP register map for the measured temperatures. This guide gives the decision rule between SDK-driven cameras and appliances, the poll-and-decode arithmetic for the temperature word, a bandwidth check for the stream, and the checks that make the readings trustworthy — on Raspberry Pi OS 64-bit, or on Windows with the same code.

Decide first: Vision camera or appliance

Sort every thermal camera in the project into one of two classes before any code is written.

A camera whose interface list says GigE Vision or USB3 Vision is a GenICam device. An acquisition library drives it directly, one link carries the frames, and temperature or camera-state data arrives as metadata or registers in the same client — reading GigE camera registers at runtime from your control code covers that register side. If the hardware choice is still open, stop here: pick from the infrared cameras category and the rest of this guide becomes unnecessary.

An appliance-class camera — fixed-mount switchgear watch, kiln survey, gas leak imaging — is a closed box. Its setup tool runs on a desktop OS, no GenICam stack exists for an ARM board, and the maker's documentation states plainly which SDKs it supports. That is not a dead end, because the same Ethernet port speaks standards: the video comes over RTSP, the numbers come over Modbus TCP (some models add EtherNet/IP), and both are published in the camera's manuals. This is the supported integration path, not a workaround.

The rule in one line: SDK when the interface says Vision, clients when the camera is an appliance — and never guess an appliance's internals when its register map is one download away. If a single spot value would settle the process question, weigh the thermal imaging camera versus spot pyrometer trade-off first; the appliance may be more camera than the task needs.

What you need

  • The camera on the network, with a reserved IP address and two documents: the stream settings page (RTSP path, codec, target bitrate) and the Modbus register map (addresses, function codes, scaling, signedness).
  • An embedded Linux board with wired Ethernet. Raspberry Pi OS 64-bit works as it ships: Python 3 is included and both clients are plain TCP/IP, so there is no vendor build to miss. The same code runs on a Windows PC if the project lands there instead.
  • Two Python packages: an RTSP client library — several thin, video-oriented clients are published on the Python package index — and a maintained Modbus TCP client from the same index. Pick by current maintenance and your decoding backend, and pin the versions in your project.
  • A switch, with camera and board on one subnet. Use GigE ports if raw radiometric frames appear anywhere in the plan — the worked example below supplies the arithmetic behind that.

Bring up the RTSP stream

  1. Prove the link. Ping the camera, then open its RTSP URL in a desktop RTSP player — an address in the form rtsp://192.168.1.50/live, with the exact path taken from the camera's stream settings page. Frames appearing within a second confirm the network and the stream service together.
  2. Choose the stream deliberately. Most appliances offer a viewing stream of rendered 8-bit imagery, some add a radiometric stream or spot overlays. Assign purposes in the stream settings: display and snapshot triggering on the viewing stream, measurement from the registers, radiometric stream only where the camera actually offers one.
  3. Open the same URL from Python. The RTSP client handles session setup and decoding; your loop timestamps each frame with the board clock and pairs it with the register readings arriving in the same period. Keep the video loop and the register poll as two threads over one timestamp source.

Read the temperatures from Modbus TCP registers

  1. Find the words. For each value the register map gives an address, a function code, a scaling and a signedness. Measured values usually sit in input registers (function code 4); settings live in holding registers (code 3). Read a block in one transaction — spot temperature, region maximum, alarm status — instead of register by register.
  2. Poll politely. Send one request and wait for the reply before the next on the same connection; the Modbus TCP protocol defines a single outstanding transaction per connection. A 250-500 ms period is ample for condition monitoring: thermal processes drift slowly, and the camera's own detection runs at its rate inside the camera no matter how hard you poll.
  3. Convert, then check. Apply the scale, handle the signed word, and reject any reading outside the camera's stated measurement range before it reaches a log or an alarm:
# Illustrative decode — scale, range and value come from your camera's
# register map; the numbers here are a worked example only.
scale_c_per_count: float = 0.1   # degC per count, from the map
raw_spot: int = 427              # counts read this poll, uint16
valid_range_c = (-20.0, 150.0)   # camera's stated spot range

def raw_to_celsius(raw: int, scale: float) -> float:
    if raw >= 32768:             # signed 16-bit word: top half is negative
        raw -= 65536
    return raw * scale

spot_c: float = raw_to_celsius(raw_spot, scale_c_per_count)
# 427 counts x 0.1 degC/count = 42.7 degC -> inside the range, log it

A converted value outside the stated range — or flipping between extremes poll to poll — means the wrong register or the wrong scale, not a real temperature. When the readings continue to a PLC rather than a log, size the register block the way the vision coordinates to PLC over Modbus TCP guide does.

Worked example: does a 640 × 512 radiometric stream fit the network?

Inputs. 640 × 512 pixels per frame and 50 frames/s are the printed figures of the LS-IRC-0044 thermal camera. Two bytes per pixel is the 16-bit radiometric worst case — the widest common raw export width, chosen so the result bounds the load from above; exporting high bitdepth grayscale from thermal cameras covers the format. Link speeds for comparison: 1,000 Mbit/s GigE and 100 Mbit/s Fast Ethernet.

Rule in words. Link load in bits per second equals pixels per frame × bytes per pixel × 8 bits per byte × frames per second.

load (bit/s) = width × height × bytes_per_pixel × 8 × fps

Arithmetic.

  • Pixels per frame: 640 × 512 = 327,680 pixels
  • Bytes per frame: 327,680 pixels × 2 B/pixel = 655,360 B
  • Data rate: 655,360 B/frame × 50 frames/s = 32,768,000 B/s
  • Line load: 32,768,000 B/s × 8 bit/B = 262,144,000 bit/s, about 262 Mbit/s

Result and decision. 262 Mbit/s takes 26% of a 1,000 Mbit/s line and leaves the rest for the RTSP viewing stream, the Modbus polls and everything else on the switch. Against a 100 Mbit/s port the same stream is 2.6 times oversubscribed, so uncompressed radiometric streaming runs on GigE only — that is the threshold: at roughly 250 Mbit/s of streaming traffic, the port is GigE or nothing. An appliance's compressed RTSP video sits an order of magnitude or more below raw, which is why a video-plus-registers integration fits even on Fast Ethernet; the exact bitrate is stated in the camera's stream settings, not assumed.

Infrared cameras640 x 512 thermal camera, 8-14 μm, 50 Hz, GigE, FOV 88.5° × 73.2°, 9-24 V DC (LS-IRC-0044)LS-IRC-0044
Lens mount
C-mount
Interface
GigE
Resolution
Up to 3 MP
Spectrum
LWIR
$5,885.00 · quotedView and quote

Verify before you trust the numbers

  • One known-source reading. Aim at freshly boiled water: about 100 °C near sea level, falling roughly 1 °C per 300 m of elevation, and water's emissivity in the thermal band sits close to 1. Register value, on-screen value and your conversion should agree within a couple of degrees; that single test confirms address, scale and sign together.
  • Rate check. Count frames and polls over 60 seconds; both must match the configured numbers exactly.
  • Failure check. Unplug the camera. The clients must time out, log the gap and reconnect — a monitor that keeps showing the last value across a dropout is reporting a lie. Alarm on data age, not only on threshold.
  • Clock check. Run NTP on the board and pair each register value with the frame closest in time. Your temperature time series is only as fine as the poll period; read no more timing resolution into it than that.

Common mistakes

  • Reading the neighbouring register. Spot, box maximum, alarm flag and internal temperature often sit side by side; one address off returns a plausible but wrong value. The range check above is what catches it.
  • Skipping the sign bit. At 0.1 °C per count, the raw word 65,000 read unsigned claims 6,500.0 °C; read as a signed word it is −53.6 °C. Both fall outside a sane range, which is the tell.
  • Assuming byte order on 32-bit values. Modbus is big-endian within each 16-bit word, but a 32-bit float spread across two registers has device-specific word order — the register map's note decides, every time.
  • Polling flat out. Faster polling gains nothing when the camera's detection runs onboard at its own rate, and it can slow the camera's other responses. Set a sane period and leave it.
  • Mixing time bases. Camera-internal timestamps and the board clock rarely agree; align events through your own poll period, as in the clock check above.

When the Vision camera is the simpler build

Everything above is integration work you can buy your way out of. A thermal camera with a GigE interface and GigE Vision support is driven by one GenICam client: radiometric frames arrive in-band, temperature data travels as metadata on the same link, and the vendor's own tools handle discovery and setup. One protocol, one cable, and the 640 × 512 at 50 Hz load from the worked example rides a link that stays three quarters idle.

The catalog picks below all connect over GigE; the one line to check at ordering time is the software section of each data sheet, which names the Vision/GenICam support that makes the single-client path apply. For the measurement-quality side of a monitoring cell — NETD and lens choice — the thermal camera NETD and lens guide continues from here.

Infrared camerasHikrobot MV-CI003-GL-N25 0.3 MP LWIR Camera, GigE, EFL 25mmMV-CI003-GL-N25
Lens mount
M34x0.75
Interface
GigE
Price on requestView and quote
Infrared camerasThermal imaging camera, 0.5 MP, GigE (LS-IRC-0026)LS-IRC-0026
Interface
GigE
Resolution
Up to 3 MP
$3,999.00 · quotedView and quote
Infrared camerasGas leak imaging camera, GigE, 50 mm lens (LS-IRC-0007)LS-IRC-0007
Interface
GigE
Spectrum
MWIR
$47,000.00 · quotedView and quote

If the decision task is simpler than imaging — presence, level, one hot spot — a smart camera or vision sensor runs the inspection onboard and publishes the outcome, so the network carries conclusions instead of frames. Both hardware paths start at the camera finder, and the camera-side reading collected on the cameras topic page covers the rest of the selection. Settled on a camera and an integration style? The configurator below starts at the camera step and fills in the lens, trigger and mounting choices around it.

Build the whole station

The configurator matches a camera, lens, light, light controller and cables to each other, step by step, and lists only parts that fit what you already picked.

Start with the camera

Întrebări

Does RTSP and Modbus TCP integration work on Raspberry Pi OS 64-bit?

Yes. Both protocols are plain TCP/IP, and Python 3 client code runs unchanged on the 64-bit ARM build. You need the camera's IP, its published RTSP path and its register map — no vendor SDK, no aarch64 software build, no cross-compilation. A Windows PC runs the same two clients if the project later moves.

Which Modbus function code reads the temperatures?

Measured values usually live in input registers, read with function code 4, while settings sit in holding registers read with function code 3. Follow the camera's register map rather than convention: it names the code, address, scale and signedness per value, and lets you read spot, region maximum and alarm status in one block.

Can I read temperatures directly from the RTSP video frames?

No. An RTSP stream is a rendered 8-bit picture for viewing; its palette mapping discards the underlying values, so two pixels that look the same can sit either side of a limit. Measure from the Modbus registers — or from a radiometric stream if the camera offers one — and use the video for display and snapshots.

How fast can I poll the temperature registers?

Condition monitoring is well served at 2-4 polls per second; thermal processes drift slowly and the camera's onboard detection runs at its own rate regardless. Keep one outstanding request per Modbus TCP connection, and log the raw word with each poll so a later scale change never costs the history.

What network bandwidth does this integration need?

A compressed RTSP stream plus a register poll fits a 100 Mbit/s link with room to spare — the camera's stream settings state the video bitrate. Uncompressed radiometric frames are another scale: 640 × 512 at 50 Hz with 16-bit pixels alone moves about 262 Mbit/s, so raw streaming needs a GigE port.

When should I choose a GigE Vision thermal camera instead of this path?

Whenever the hardware choice is still open. A GigE Vision camera is driven by a single GenICam client over one cable: radiometric frames arrive in-band and temperature metadata travels with the image, so there is no second protocol and no register map to maintain. The RTSP-plus-Modbus route exists for appliance cameras already owned.