Plotting SICK S300 data in LabVIEW

This page documents two approaches to plotting SICK S300 data in LabVIEW. An example program that uses the second approach is stored in this Git repository.

Items needed

  • Hardware
    • SICK S300 sensor (any model)
    • System plug that’s compatible with your S300
    • One USB to RS422/485 converter (this one is used here)
    • 24 VDC power supply
  • Software
    • LabVIEW (base package or higher)


Wire the system plug as follows:

Figure 1 – Wire 24 VDC and USB to RS422 converter to system plug


Figure 2 – Pin 1 is 24 VDC, pin 2 is GND

RS422 communication

Figure 3 – RS422 example wiring

Configure the S300 for continuous data output

Configure the S300 sensor for “Continuous data output” and your desired baud rate. This is done from the “Measured data output” tab in the device window in CDS.

Figure 4 – Configure the “Measured data output” tab

Ensure the S300 is sending telegrams

The easiest way to verify the S300 is sending telegrams is to just read some data from the port.

Figure 5 – Configure the serial port, read any bytes at the port, and then close the port

You might find that you need a delay after opening the port to allow some data to accumulate.

Figure 6 – Add a delay after configuring the port

I think I’ll add the delay to a subVI.

Figure 7 – Add delay to subVI

After running this VI you should see some ASCII symbols in your string indicator.

Figure 8 – Data in string indicator after running the VI in Figure 7

Parsing the distance data

This page discusses two approaches to parsing S300 distance data in LabVIEW.

Approach 1 – Convert ASCII to hex

One way to parse the distance data is to first convert the data from ASCII to hexadecimal. For me the motivation behind this approach is typically data presentation. When I want to make the data human readable – for debug purposes, for example – I do it this way.

One way to convert the data to hex is to use a subVI that looks something like this:

Figure 9 – subVI to convert ASCII data to HEX

The above subVI has one input and one output. The input is first converted to a byte array, and then each byte is converted to a hex string one at a time. The argument “%02x” tells the “Format String” VI that each byte should be converted to hexadecimal and padded with two zeros. For readability and to match the formatting in SICK’s manual, I insert a space between each byte.

The subVI can be added to the block diagram as follows:

Figure 10 – Create subVI to convert ASCII data to HEX

After running the above VI, the string indicator should look more like this:

Figure 11 – S300 data converted to hexadecimal

If you’re getting a framing error

By now you might have noticed you’re sometimes getting a framing error (error – 1073807253) when you run your program.

Figure 12 – “A framing error occurred during transfer”

The error occurs because we’re sometimes closing the COM port before the read task is complete. You could ignore this issue for now, or you could put a while loop around the “VISA read” VI and use a case structure to ensure we only read from the port when the number of bytes at the port is greater than zero. The while loop ensures the “VISA read” VI stops executing before the “VISA close” VI attempts to run.

Figure 13 – True case
Figure 14 – False case

And to retain the data being written to the string indicator from one iteration to the next, I’ll add a shift register to the while loop and use the “Concatenate Strings” VI.

Figure 15 – True case
Figure 16 – False case

How to find the distance data

After converting to space delimited hex form, the data should make more sense. First look for the telegram header. From SICK’s documentation, the header is the four byte sequence “00 00 00 00”. And since the sensor is in “Continuous data output” mode, the header will be followed by the two byte sequence “00 00”.

The distance data is the large block of data that begins immediately after the four byte sequence “BB BB 11 11”. (See the first two blue blocks in Figure 17.) The CRC is sandwiched between the last byte of distance data and the next telegram’s header (yellow box).

Figure 17 – Anatomy of an S300 telegram

From Figure 17 you can see that a simple way to parse the distance data is to use the “Match Pattern” VI as follows:

Figure 18 – Rough subVI to parse distance data and CRC

Since the distance data always begins immediately after the byte sequence “BB BB 11 11”, the byte sequence “BB BB 11 11 ” is used as the “regular expression” input to the first “Match Pattern” VI. The “after substring” output is then passed to the second “Match Pattern” VI. The CRC will immediately precede the header of the next telegram, so the byte sequence “00 00 00 00” is used as the regular expression input to the second “Match Pattern” VI, and the “before substring” output is passed to the “distance data and CRC” string indicator. In addition, when the “match substring” output of the second “Match Pattern” VI matches the “regular expression” input, we set the “Stop?” Boolean to stop the while loop.

This subVI can be invoked as follows:

Figure 19 – Parse distance data and CRC and then stop

The above VI runs until it acquires the distance data and CRC from exactly one telegram – then it stops.

Figure 20 – Distance data and CRC from one telegram

In space delimited hex form, a LabVIEW string consisting of just the distance data and CRC should be of length 3252.

Figure 21 – Length should be 3252

It’s also important to realize that when the data is in the above form, the msb and lsb of each distance value are interchanged. So, for example, the first 16 bits in Figure 20 should be interpreted as follows:

Figure 22 – Data format of measured data

So the distance measurement is 512 + 128 + 32 + 2 + 1= 675 centimeters.

Angular resolution and scanning range

To check your sensor’s resolution, open the device window and view the “Resolution/scanning range” tab.

Figure 23 – Find angular resolution

The SICK S300 has a scanning range of 270° and the first beam of a scan is considered to start at -45°.

Figure 24 – Scanning range of S300 – Taken from p. 17 of S300 Operating Instructions

Since the value of 675 centimeters from Figure 22 is the first measured value after “BB BB 11 11”, its associated angle is -45°. And since the angular resolution of my S300 is 0.5°, the second distance measurement is 670 ∠ -44.5° centimeters, the third is 666 ∠ -44.0° centimeters, and so on. The last distance measurement in Figure 20 is 18 ∠ 225° centimeters.

Approach 2 – Parse without converting to hex

Approach 1 is useful for learning and/or debugging but computationally inefficient since the data can be parsed without first converting to hex.

Backslash codes display

If I run the VI in Figure 7 the string indicator should once again look something like this:

Figure 25 – Data in string indicator after running the VI in Figure 7

As before this data is not human readable. However, if I right-click on the string indicator and select \ Codes Display, I can see the data as it is actually represented in memory.

Figure 26 – Data in Figure 25 as it is represented in memory

Using backslash code display, I can rewrite the VI in Figure 18 to parse the S300 data without first converting to hex.

Figure 27 – Parse distance data without converting to hex

I can now remove the VI in Figure 9 from the VI in Figure 19 as follows:

Figure 27 – Modify the VI in Figure 19

I will also add error checking to this VI and then move it to a subVI.

Figure 29 – Front panel of VI in Figure 28

The subVI in Figures 28 and 29 can be invoked as follows:

Figure 30 – Main VI that invokes subVI in Figures 28 and 29

Plotting the data

The following subVI can be used to plot the distance data read by the main VI in Figure 30.

Figure 32 – subVI to plot distance data (front panel)

The subVI in Figures 31 and 32 is added to the main VI as follows:

Figure 33 – Add subVI to plot distance data to main VI

After configuring the COM port and baud rate with controls instead of constants, the front panel might look something like this:

Figure 34 – Front panel of VI shown in Figure 33

Git repository

The Git repository for the VI in Figure 34 can be found here.

About the author

Leave a Reply

Your email address will not be published. Required fields are marked *