Skip to content

Modbus Integration

FX Viewer Modbus Integration Manual

1. Overview

The Modbus TCP server feature links FX Viewer’s real-time acoustic camera data (beam power, alarm status, etc.) with external systems such as PLC, SCADA, and HMI.

With this feature, an external control device such as a PLC can monitor FX Viewer’s camera data and directly control some of its settings.

2. Basic Setup and Connection Details

Automatic Startup

When the FX Viewer application starts, the Modbus server runs automatically. No additional configuration is required.

Connection Details

  • IP Address: The IP address of the PC running FX Viewer

  • Port: 5020 (default) or 502

    • To account for environments without permission to use ports below 1024, the server binds to port 5020 first. If binding to port 5020 fails, the server tries to listen on port 502.

    • On the client side, try connecting to port 5020 first; if the connection fails, try port 502.

  • Protocol: Modbus TCP

3. Camera Setup

For the Modbus feature to work correctly, the camera nickname must be set in the expected format.

⚠️ Important: Cameras whose nickname does not follow the rules below are excluded from Modbus integration. This is the most common cause when no data appears, so check it first before integrating.

Unit IDRequired NicknameOther Accepted FormatsDevice ID
1FX_01FX01, FX-010x4601
2FX_02FX02, FX-020x4602
3FX_03FX03, FX-030x4603
  • Nicknames are not case-sensitive. (fx_01 is accepted)

  • The same rule applies to the fourth camera and beyond. Unit IDs are assigned in order, one for each camera registered in FX Viewer.

4. Register Map

  • Addressing: For PLC and other clients, we recommend using zero-based wire addresses (offsets). (Example: request address 40009 as address 8)
Modbus AddressWire AddressRegister NameData TypeR/WDescription
400010DEVICE_IDU16RUnique device ID (e.g., 0x4601)
400021DEVICE_CONNECTEDU16RCamera connection status (1: connected, 0: disconnected)
400032YEARU16RCurrent time (year)
400043MONTHU16RCurrent time (month)
400054DAYU16RCurrent time (day)
400065HOURU16RCurrent time (hour)
400076MINUTEU16RCurrent time (minute)
400087SECONDU16RCurrent time (second)
400098MAX_DBx10S16RMaximum sound pressure (dB value x 10), e.g., 45.2dB → 452
400109ALARM_FLAGU16RAlarm status (1: alarm active, 0: normal)
4001110THRESH_DBx10S16R/WThreshold (dB value x 10), e.g., 42.5dB → 425
4001211THRESH_HOLDx10S16R/WHold time (seconds x 10), e.g., 3.5 seconds → 35
40013-1412-13FREQ_LOW_HZU32R/WLower frequency limit (Hz)
40015-1614-15FREQ_HIGH_HZU32R/WUpper frequency limit (Hz)

Data Type Settings on the Client

Example settings screen in a PLC Modbus client for selecting the data type (INT, WORD, DWORD, etc.) for each register address

Example of a settings screen in a PLC Modbus client where a data type is selected for each register address. For items that use one register, follow the types in the table above: read signed integers (S16) as INT and unsigned integers (U16) as WORD. Read the two-register (32-bit) FREQ_LOW_HZ and FREQ_HIGH_HZ as a DWORD-family type.

5. Key Features and Usage Examples (Python)

Automatic Trigger Mode Activation

  • When the PLC writes a value to the threshold (40011) or hold time (40012) register, the camera’s recording mode is automatically switched to ‘Trigger Recording’ mode.

⚠️ Caution: Writing to the threshold or hold-time registers has the side effect of changing the camera’s recording mode. If you only need to monitor data, use read requests only, and send write requests only when you intend to switch to trigger recording.

Python Example Code

The example below uses the Python pymodbus library (3.x). Install the library first.

Terminal window
pip install pymodbus

💡 Note: pymodbus uses a different keyword for the Unit ID depending on the version. The slave= in the example below is for 3.x; older versions (2.x) use unit=. Use the keyword that matches your installed version.

from pymodbus.client import ModbusTcpClient
# Set the IP and port of the PC running FX Viewer
FX_VIEWER_IP = '127.0.0.1'
FX_VIEWER_PORT = 5020
client = ModbusTcpClient(FX_VIEWER_IP, port=FX_VIEWER_PORT)
client.connect()
# -- Read data example ---
# Read data from camera FX_01 (Unit ID = 1)
# Read 2 registers (sound pressure, alarm) starting at wire address 8 (MAX_DBx10)
result = client.read_holding_registers(8, count=2, slave=1)
if not result.isError():
max_db_x10 = result.registers[0]
alarm_flag = result.registers[1]
# Convert to signed 16-bit, then divide by 10
import struct
signed_max_db_x10 = struct.unpack('>h', struct.pack('>H', max_db_x10))[0]
print(f"FX_01 peak sound pressure: {signed_max_db_x10 / 10.0} dB")
print(f"FX_01 alarm state: {'ALARM' if alarm_flag == 1 else 'normal'}")
# -- Write data example ---
# Set the threshold of camera FX_02 (Unit ID = 2) to 45.5 dB
# Write the value to wire address 10 (THRESH_DBx10)
new_threshold = 45.5
threshold_to_write = int(new_threshold * 10)
client.write_register(10, threshold_to_write, slave=2)
print(f"FX_02 threshold set request submitted ({new_threshold} dB)")
client.close()

Example Output

Example output when camera FX_01 reads a maximum sound pressure of 45.2 dB (register value 452) and the alarm is in the normal state.

FX_01 peak sound pressure: 45.2 dB
FX_01 alarm state: normal
FX_02 threshold set request submitted (45.5 dB)

6. Troubleshooting

  • If you cannot connect:

    • Verify that the IP address and port (5020) of the FX Viewer PC are correct.

    • Check that Windows Firewall allows port 5020 or 502 through an inbound rule.

  • If all data reads as 0:

    • Check that the camera is active in FX Viewer and receiving real-time data.

    • Double-check that the camera’s nickname is set correctly to FX_01, FX_02, etc. (This is the most common cause.)

  • If some values (e.g., frequency) read incorrectly:

    • Check that the client’s data type settings match the types in the register map (S16/U16/U32). In particular, the two-register FREQ_LOW_HZ and FREQ_HIGH_HZ must be read as a DWORD-family type. (See the data type settings screen in Section 4.)