Configuring SICK CLV630 PROFINET with S7-1500 in TIA Portal V15.1

David Krause19 min read
Sensor IntegrationSiemensTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

System Overview

This reference documents the integration of a SICK CLV630-6120 fixed-mount barcode scanner with a Siemens SIMATIC S7-1515-2 programmable logic controller over PROFINET IO using TIA Portal V15.1. The scanner appears in the PROFINET topology as a standard IO device, exchanges cyclic I/O with the CPU, and exposes the decoded barcode string, status flags, and diagnostics over the fieldbus. The application scenario covered here is one of the most common in discrete-manufacturing and material-handling lines: a PLC triggers a scan, captures the decoded barcode from the input process image, and forwards the result to a higher-level IT system (MES, ERP, or warehouse server).

The behavior observed during commissioning is straightforward: setting a single output bit to TRUE arms the reading gate, the scanner fires its laser line, decodes whatever code is in the field of view, and writes the ASCII result plus status flags into the input process image. A typical working mapping uses Q1.0 as the trigger source and a 32-byte slice from IB2 to IB33 for the barcode payload. The two leading bytes (IB0-IB1) carry the scanner status word and are used by the application logic to confirm valid result availability before the data block is consumed.

The complete CLV63x/CLV64x/CLV65x device family is described in the SICK CLV63x/CLV64x/CLV65x Operating Instructions (PDF, IM0071081), which covers hardware installation, optical setup, the PROFINET GSDML-based integration, and the bit-level meaning of the cyclic I/O data. The function-block approach for the SICK PLB (Product Logistics Bridge) is documented separately in the SICK Support Portal article KA-08392, which provides a sample Siemens function block for TCP/IP communication between a SICK PLB and a SIMATIC PLC.

Hardware and Software Requirements

Component Specification Notes
PLC CPU SIMATIC S7-1515-2 (6ES7515-2AM02-0AB0 or newer) Two PROFINET interfaces; supports PROFINET IO Controller and IO Device on X1, separate PROFINET on X2
Barcode scanner SICK CLV630-6120 Fixed-mount line scanner with integrated PROFINET IO interface (variant suffix 6120 = PROFINET)
Reading range Variant-dependent; CLV630 typical 50 mm to 380 mm See optical data sheet; configured via SOPAS or web-based SOPASair
Scan rate Up to 1200 scans/s Adjustable; faster scan rate reduces depth of field
Protection class IP65 M12 PROFINET connectors; suitable for conveyor-side mounting
PROFINET cable Cat 5e or higher, shielded, M12 D-coded Standard PROFINET copper cabling, max 100 m segment length
Engineering tool Siemens TIA Portal V15.1 Update TIA Portal to the most recent V15.1 Hotfix for the CLV630 GSDML import
GSDML file GSDML-Vx.x-SICK-CLV630-yyyymmdd.xml Download from the SICK product page for the CLV630-6120
Firmware CLV630 firmware current as of integration date Verify in SOPAS under Device Information; some PROFINET slot features require FW ≥ V2.10
Note on the SICK part number. The CLV630-6120 designation identifies the line-scanner variant with PROFINET IO interface and standard density. Other suffixes in the family (CLV630-0000, -1000, -3000, -6120, -6320, etc.) describe the optical engine and fieldbus. Confirm the variant on the device nameplate before proceeding with the GSDML installation.

PROFINET I/O Slot Configuration

Once the GSDML is imported into TIA Portal, the CLV630-6120 appears in the hardware catalog under Other field devices > PROFINET IO > Sensors > SICK > CLV630. During device insertion the IO Controller automatically negotiates the cyclic slot configuration. The default slot layout used by the CLV630-6120 places the result data in input bytes and the trigger control in output bytes.

Slot Sub-slot Direction Length Process Image Address Content
0 1 Input 2 bytes IB0-IB1 Status word (ResultAvailable, Error, NoRead, DeviceReady, Quality bits)
1 1 Input 32 bytes IB2-IB33 Decoded barcode data, ASCII, left-justified, blank-padded
1 1 Output 1 byte QBx (mapped to Q1.0 trigger in the observed project) Control byte (bit 0 = Reading Trigger, bit 1 = Reset, bit 2-7 = application-dependent)
0 0 (port diagnostics) Input Per port Diagnostic data block Port-level link diagnostics (acquired via Record-Data read)

The exact start address in the I/O process image depends on the address assignment selected in TIA Portal. In the working reference project the input image starts at %IB0 and the output image at %QB0, giving:

  • %IW0 – 16-bit status word
  • %IB2..%IB33 – 32-byte barcode payload (the ASCII text of the decoded code)
  • %QB0 – control byte; in the application code the active trigger bit is Q1.0, which the programmer copies to %QB0 (or wires directly to bit 0 of the output byte if the address assignment was offset).
Address assignment. If the project uses other PROFINET nodes before the CLV630, the start address of the scanner may shift. The relationship between slot layout and the observed mapping (Q1.0 trigger, IB2..IB33 data) only holds when the slot configuration shown above is preserved. To re-create the mapping exactly, manually set the IO addresses for the CLV630 to start at 0 in both input and output images.

Device Configuration in TIA Portal V15.1

  1. Download the SICK CLV630 GSDML from the SICK product page and store it locally.
  2. In TIA Portal open Options > Manage general station description files (GSD) and install the GSDML. TIA Portal will populate the hardware catalog with the CLV630 device entry.
  3. In the Devices & Networks editor, drag the SICK CLV630-6120 from the catalog onto the PROFINET subnet attached to the S7-1515-2 X1 interface.
  4. Assign a unique PROFINET device name (for example clv630-1) and a static IP address consistent with the subnet. The CLV630 can also receive its name from the PLC via DCP if PROFINET naming is enabled.
  5. In the device properties, open Device view and inspect the slot list. Verify that Slot 0 / Sub-slot 1 (Status) and Slot 1 / Sub-slot 1 (Reading Data) are present and not greyed out.
  6. If your scanner firmware supports alternate I/O sizes (for example 16-byte or 64-byte data blocks), confirm the slot length matches the data layout you want. The default 32-byte data block matches the IB2..IB33 mapping observed during commissioning.
  7. Set the IO addresses. In the Properties panel under I/O addresses assign the input start address to 0 and the output start address to 0 to reproduce the reference mapping.
  8. Configure update time. For a 1200 Hz scanner the cycle time can be as low as 1 ms. With an S7-1515-2 a 1 ms send clock for the PROFINET IO is supported; if you also have IRT motion devices on the same subnet, configure the IRT topology accordingly.
  9. Compile and download the hardware configuration to the PLC. The CLV630 will receive its PROFINET name via DCP at the next power-on or topology discovery.
  10. Once the device shows up in the online diagnostics with a green checkmark and no channel-level diagnostic alarms, the I/O exchange is live.

Trigger and Reading-Cycle Implementation

The CLV630-6120 reading gate is armed by the trigger bit in the output control byte. In the reference project the application sets Q1.0 TRUE to start a scan, waits for the ResultAvailable bit in the status word to assert, copies the 32-byte payload from IB2..IB33 into a string tag, and then clears the trigger. A clean edge-triggered implementation in SCL is shown below.

// FB_TriggerScan — Single-shot read cycle against SICK CLV630
// Inputs : i_bStart   (BOOL)  — request to fire one reading
//          i_tTimeout (TIME)  — maximum wait for ResultAvailable
// Outputs: o_sCode    (STRING) — decoded barcode, ASCII
//          o_bOK      (BOOL)  — TRUE if a valid result was captured
//          o_bTimeout (BOOL)  — TRUE if no result within timeout
//          o_bError   (BOOL)  — TRUE if scanner reports error

IF i_bStart AND NOT i_busy THEN
    i_busy := TRUE;
    o_bOK := FALSE;
    o_bTimeout := FALSE;
    o_bError := FALSE;
    o_sCode := '';
    // Set trigger bit Q1.0 (mirrors into %QB0 bit 0 of the CLV630 slot)
    Q1.0 := TRUE;
    i_tStart := CURRENT_TIME();
END_IF;

IF i_busy THEN
    // Wait for status word bit 0 (ResultAvailable) — sits in %IB0
    IF "Status_CLV630".ResultAvailable THEN
        // Copy 32 bytes from IB2..IB33 into a STRING tag
        o_sCode := CHAR_TO_STRING(STRING_FROM_BYTES("Data_CLV630".Barcode));
        Q1.0 := FALSE;
        i_busy := FALSE;
        o_bOK := TRUE;
    ELSIF (CURRENT_TIME() - i_tStart) > i_tTimeout THEN
        Q1.0 := FALSE;
        i_busy := FALSE;
        o_bTimeout := TRUE;
    END_IF;
END_IF;

The data block Data_CLV630 is a 32-byte AT-view over the process image:

DATA_BLOCK "Data_CLV630"
  STRUCT
    Barcode : ARRAY[0..31] OF BYTE;   // AT %IB2 : ARRAY[0..31] OF BYTE;
  END_STRUCT;
END_DATA_BLOCK

DATA_BLOCK "Status_CLV630"
  STRUCT
    ResultAvailable : BOOL;           // %I0.0
    NoRead          : BOOL;           // %I0.1
    Error           : BOOL;           // %I0.2
    QualityGood     : BOOL;           // %I0.3
    DeviceReady     : BOOL;           // %I0.4
    Reserved        : ARRAY[0..10] OF BOOL; // %I0.5 .. %I1.7
  END_STRUCT;
END_DATA_BLOCK

For ladder programmers the same logic collapses to an S_ODT timer driving the trigger bit, a contact on the ResultAvailable bit, and a BLKMOV (or READ_DBL) from the input area into a string tag. In either language the important rule is to never read the barcode bytes before ResultAvailable asserts; otherwise you may capture residual data from the previous reading or the uninitialised power-on state.

Reading Result Data Structure and Parsing

The 32 bytes in IB2..IB33 contain the ASCII representation of the decoded barcode. SICK uses a left-justified, space-padded layout: the leading bytes are printable characters, the trailing bytes are ASCII $20 (space) when the code is shorter than 32 characters. A typical Code-128 result for a 14-character shipping container code looks like:

Byte offset IB index ASCII Hex Comment
0 IB2 '1' 0x31 First character of code
1 IB3 'A' 0x41
... ... ... ... ...
13 IB15 '4' 0x34 Last character of code
14 IB16 ' ' 0x20 Pad byte
... ... ' ' 0x20 Pad bytes
31 IB33 ' ' 0x20 Pad byte

To turn the byte array into a usable STRING tag, strip trailing $20 bytes (and any other pad character your application configured in SOPAS). The SCL snippet below produces a clean, trimmed result and also flags when the scanner reported NoRead.

// FB_ParseResult — Trim trailing pad bytes from the result buffer
// Input : i_bResultAvailable (BOOL), i_bNoRead (BOOL)
//         i_bRaw : ARRAY[0..31] OF BYTE
// Output: o_sCode (STRING[64]), o_bNoRead (BOOL)

IF i_bNoRead THEN
    o_sCode := '';
    o_bNoRead := TRUE;
    RETURN;
END_IF;

o_bNoRead := FALSE;
// Copy bytes into a temporary STRING[32]
"tmp".s32 := '';
FOR i := 0 TO 31 DO
    "tmp".s32 := CONCAT("tmp".s32, CHAR_TO_STRING(BYTE_TO_CHAR(i_bRaw[i])));
END_FOR;
// Trim right whitespace and NULs
o_sCode := LTRIM_IMPL("tmp".s32, ' ');
o_sCode := LTRIM_IMPL(o_sCode, '$00');
Empty-read handling. When the scanner fires but no code is present in the read range, the NoRead bit in the status word asserts and the data bytes remain at their previous value (often the last successful read, or blank after power-on). Always branch on the status word before forwarding the data block to a downstream consumer — never assume that the absence of a barcode resets the buffer automatically.

Server Communication Architecture

Once the PLC owns a clean barcode string, the next problem is to push it to a server. The S7-1515-2 supports several transport options natively; the most common are listed below.

S7-1500CPU 1515-2SICK CLV630-6120PROFINET IOTIA OPC UA Serverbuilt-in, port 4840TCP/UDP via TSEND_Cor SICK PLB FBQ1.0 / IB2..IB33StatusBarcode
Channel Use case Effort Notes
OPC UA server on the S7-1500 SCADA / MES pulls the tag on demand Low No PLC code beyond declaring the tag as an OPC UA variable; built into the S7-1500 firmware
Open User Communication (TSEND_C / TRCV_C) PLC pushes each scan to a TCP/IP endpoint (Python script, Node-RED, warehouse server) Low–Medium Uses the standard TIA Portal TSEND_C / TRCV_C instructions; supports partner IP and port
S7 PUT/GET Other Siemens PLCs or WinCC read the scan from the 1515-2 Low Activate Permit access with PUT/GET on the CPU properties
SICK PLB TCP/IP bridge Direct integration with SICK Product Logistics Bridge or telematics server Medium Use the reference FB in the SICK Support article KA-08392
MQTT (via library or external gateway) Publish to an MQTT broker for IIoT pipelines Medium Requires a TIA Portal MQTT library or a telematics gateway such as the SICK Telematics Service Box

OPC UA Server Publication

The S7-1500 firmware ships with a built-in OPC UA server. Enabling it requires three configuration steps in TIA Portal.

  1. Open the CPU properties and select OPC UA Server > General. Tick Activate OPC UA Server.
  2. Define the server port (default 4840) and the security policy. For a closed manufacturing cell, leave None enabled. For factory-wide deployments, enable Sign + SignAndEncrypt with X.509 certificates.
  3. Under OPC UA Server > Runtime licenses confirm that the CPU has an OPC UA license (S7-1515-2 includes OPC UA server capability without an additional license up to a session count defined by the firmware).
  4. In the project tree, right-click the o_sCode STRING tag (the barcode string) and choose Accessible from OPC UA > Read/Write. TIA Portal will register the tag in the server address space.
  5. Compile, download, and use any OPC UA client (UaExpert, Node-RED, Ignition, Kepware, custom Python with asyncua) to subscribe to the tag. A subscription triggers a notification every time the tag changes, which is exactly the behaviour required to stream scans to an MES.

An OPC UA client poll of the form ns=1;s=BarcodeStream returns the most recent barcode. If you need per-scan history rather than last-value, push the values into a small DB queue and expose a method on the OPC UA server that returns the queue on request.

TCP/IP Socket Communication with TSEND_C

If the target is a plain TCP server (a Python listener, a Node-RED flow, an industrial gateway), use TSEND_C from the TIA Portal instruction palette. The instruction handles connection establishment, data transfer, and disconnection. A typical implementation sends a JSON line for each successful scan.

// FB_PushBarcode — Send barcode over TCP to a remote listener
// Partner configured in IDB "PartnerDB" (IP, port, connection ID, etc.)

// Build JSON payload
"tmp".json := CONCAT('{"timestamp":"', UINT_TO_STRING("clock".unix_ts), '",');
"tmp".json := CONCAT("tmp".json, CONCAT('"code":"', o_sCode));
"tmp".json := CONCAT("tmp".json, CONCAT('","result":"', SEL(i_bNoRead, 'OK', 'NOR'))); 
"tmp".json := CONCAT("tmp".json, '"}');
"tmp".json := CONCAT("tmp".json, '$0A'); // newline terminator for line-based parsers

// Move into a BYTE buffer
"sendBuf".len := LEN("tmp".json);
Strg_To_Chars(src := "tmp".json, dst := "sendBuf".data, len := "sendBuf".len);

// Trigger TSEND_C
TSEND_C_DB.REQ := TRUE;
TSEND_C_DB.CONT := TRUE;
TSEND_C_DB.LEN  := "sendBuf".len;
TSEND_C_DB.DATA := "sendBuf".data;

Configure the connection once at runtime start using the TCON block inside the same DB:

// One-shot connection to the server, e.g. 192.168.10.50 : 9000
TCON_DB.REQ := TRUE;
// Connect parameters
TCON_DB.ID            := 1;
TCON_DB.CONNECTION_ID := 1;
TCON_DB.ACTIVE_EST    := TRUE;        // PLC acts as TCP client
TCON_DB.REMOTE_PORT   := 9000;
TCON_DB.REMOTE_IP     := 192_168_10_50;
// TCON_DB.CONNECT will assert when the socket is up
Firewall and routing. The S7-1515-2 X1 interface is on the OT network. If the target server sits on the IT/office network, configure the IP router in TIA Portal (Devices & Networks > X1 > Properties > IP router) and ensure the cell-level firewall permits outbound TCP on the chosen port. The S7-1500 OPC UA server and TSEND_C channels both respect the same routing table.

MQTT and SICK PLB Integration

For an MQTT broker the S7-1500 firmware since V2.6 includes a lightweight MQTT client (active on CPUs with a Mqtt instruction set in the TIA Portal library). The instruction publishes a topic such as factory/line1/clv630/result with a JSON payload identical to the TSEND_C example. Broker connection details (URI, port, TLS, credentials, last-will topic) are configured once in the DB.

When the target is a SICK PLB system, the SICK Support Portal article KA-08392 provides a reference Siemens function block that wraps the TCP/IP exchange with the PLB. The block handles session establishment, cyclic data forwarding, and acknowledgement. To use it:

  1. Download the FB from the KA-08392 attachment and import it into your TIA Portal library.
  2. Drag the FB into your program and connect its inputs to the o_sCode string and to the scanner status bits.
  3. Configure the PLB IP address and TCP port in the instance DB.
  4. Call the FB in a cyclic OB (OB1) — the FB itself manages state internally.

Diagnostic Word and Error Handling

The 16-bit status word in %IW0 is the primary health channel. The bit meanings below are consistent with the CLV630-6120 PROFINET profile; always cross-check with the CLV63x/64x/65x operating instructions for the exact firmware revision you are commissioning.

Bit Name Meaning Recommended reaction
0 ResultAvailable A new decoded result is in the data block Copy data block, then acknowledge by clearing trigger
1 NoRead Trigger fired but no code was in the field of view Mark the scan as NOREAD, do not forward as a code
2 Error Device-level fault (laser, optics, configuration) Latch an alarm, page maintenance
3 QualityGood Decoded code meets the configured quality threshold Use as a quality gate before forwarding
4 DeviceReady Scanner is in operating state Gate the trigger logic on this bit
5–15 Reserved / vendor-specific Refer to SOPAS parameter mapping Ignore unless the project explicitly uses them

A robust application logic gates the trigger on DeviceReady, captures data only when ResultAvailable asserts, latches a fault on Error, and logs a NOREAD event when NoRead asserts without ResultAvailable. This four-state matrix handles every plausible scanner response without producing phantom reads.

Trigger–Read Timing

Q1.0 (Trigger)Status.ResultAvailableData Valid (IB2..IB33)t0t1t2t3Trigger pulseResult readyCapture IB2..IB33

The four reference points describe the cycle:

  • t0 – PLC raises Q1.0 and starts a watchdog timer.
  • t1 – Scanner detects the trigger and starts its internal exposure sequence.
  • t2 – Scanner has finished decoding; ResultAvailable asserts and the data block in IB2..IB33 is stable.
  • t3 – PLC has copied the data block and de-asserts Q1.0.

The total cycle time t3 - t0 is dominated by the scanner's exposure and decode time, typically 10–50 ms at default SOPAS settings. Tightening SOPAS for higher scan rates shortens t2 - t1 at the cost of depth-of-field margin.

Troubleshooting Matrix

Symptom Likely Cause Verification Fix
No PROFINET connection (yellow triangle in TIA online) PROFINET device name mismatch Online > Accessible nodes — does CLV630 appear with the configured name? Re-assign the name via PROFINET device name in the device properties, then power-cycle the scanner
I/O exchange up but ResultAvailable never asserts Trigger bit is not actually wired to the control byte, or DeviceReady is low Watch the output byte in the PLC's watch table; verify DeviceReady = TRUE Confirm that Q1.0 (or the equivalent output bit) maps to bit 0 of %QBx; check SOPAS trigger source
Data block contains only $20 (spaces) Scanner decoded a code shorter than 32 bytes; pad bytes are intentional Inspect SOPAS reading result in the SOPASair web UI Trim the byte buffer on the PLC side; verify byte length in TIA slot configuration
Data block contains stale code from the previous scan Application reads data block before ResultAvailable asserts Trace status bit transitions with a PLC watch table Gate the data copy on ResultAvailable; consider edge detection on the rising edge
TSEND_C reports BUSY indefinitely Partner firewall blocks the port; or the partner only accepts a specific source port Wireshark on the partner host; ping the partner IP from a maintenance laptop Open the firewall path; if the partner requires a source port, use TCON with explicit local port
OPC UA client cannot connect to port 4840 OPC UA server not activated, or wrong port TIA online: CPU > OPC UA Server > Status Activate the server, allow anonymous authentication, check firewall on the routing path
ResultAvailable asserts but Error bit also asserts Scanner hardware fault (laser degraded, temperature out of range) SOPAS diagnostic log Address the scanner-side fault; the data block is not valid in this state
Intermittent drops during high-throughput scans PROFINET send clock too slow for scanner scan rate Use PROFINET diagnostics to log jitter and lost frames Reduce the IO update time to 1 ms; cap scanner scan rate to a sustainable value

Verification Procedure

  1. In TIA Portal, open Online > Go online and confirm a green status icon on the CLV630 node. Open the Diagnostics panel and verify zero active channel diagnostics.
  2. Open a watch table bound to %IB0..%IB33 and %QBx. Force Q1.0 TRUE.
  3. Present a known barcode to the scanner. Observe the transition of %I0.0 (ResultAvailable) and the appearance of the ASCII text in %IB2..%IBxx.
  4. Compare the ASCII buffer with the printed code. Confirm that trailing space padding is the only difference if the code is shorter than 32 characters.
  5. If the server channel is OPC UA, open UaExpert, browse to the server endpoint, and subscribe to the barcode tag. Force a new scan and verify the subscription receives a notification.
  6. If the server channel is TSEND_C, run nc -lk 9000 (or a Python socket listener) on the partner host. Force a scan and verify a JSON line is received on the listener.
  7. Disable the trigger and leave the scanner idle for 60 s; verify the status word returns to its steady state and that no spurious data appears in the buffer.
  8. Document the working slot configuration, address map, server URL, and any SOPAS parameters that were changed from defaults, and store the GSDML version in the project archive.

Why does my trigger input on the CLV630 PROFINET not start a scan?

The control byte from the S7-1500 maps to the first output byte of slot 1. The reading trigger is bit 0 of that byte. In a project where the input image starts at IB0 and the output image starts at QB0, the trigger is Q0.0; in the reference mapping where the application uses Q1.0, the application code copies Q1.0 into %QB0 bit 0. Confirm the address assignment in TIA Portal, and confirm that DeviceReady in the status word is TRUE before the trigger is set.

The PLC reads 32 bytes from IB2 to IB33 but the result is all spaces — what does that mean?

It means the scanner decoded a code shorter than 32 characters and the unused bytes are filled with ASCII $20 (space). This is the SICK standard left-justified pad layout. Trim the trailing $20 bytes in your application logic; do not interpret the spaces as a fault. If NoRead also asserts, the scanner fired without seeing a code and the buffer is stale from the previous successful read.

Can I get the decoded barcode without waiting for a PLC trigger, just from PROFINET?

Yes — set the SOPAS trigger source to Auto / Continuous rather than PROFINET. The scanner will then scan continuously and push each decoded result into the same data block IB2..IB33. The ResultAvailable bit still toggles for each new read. Continuous mode is appropriate for conveyor applications where the trigger is provided by the item presence, not by the PLC.

How do I push the barcode to an MES server that only accepts HTTP POST?

The S7-1500 firmware does not provide a native HTTP POST client. The two practical paths are: (1) publish the barcode as an OPC UA tag and let the MES poll it; or (2) use a small gateway (Node-RED, Ignition Edge, or a Python script) as the HTTP client and feed it the barcode over TCP using TSEND_C. For high-throughput lines an OPC UA subscription is usually the simpler architecture.

What GSDML and firmware versions should I document in the project?

Record the GSDML file name (for example GSDML-V2.32-SICK-CLV630-20180927.xml), the scanner firmware version shown in SOPAS under Device Information > Firmware, the TIA Portal version (V15.1 with the latest Hotfix), and the CPU firmware (for example V2.6 for the S7-1515-2). These four numbers uniquely identify the integration and are required when escalating a fault to SICK or Siemens support.

Back to blog