How to Parse Data out of a Serial Data String Using a dataTaker

Intelligent dataTaker Data Logger for Batch Processes

Introduction:

At CAS DataLoggers we often take calls from plant technicians who want to log load cell data from serial scales. This is especially common in industrial manufacturing and batch processes where users want to weigh each component added to a mixing tank or vat for PQ purposes. For these applications, dataTaker data loggers such as the intelligent dataTaker DT80 and dataTaker DT85 can be used to parse data out of a serial data string. This technical article gives an example of this, using a serial scale outputting the larger set of measurements of a tank’s weight.

Our example is taken directly from a food processing application where our customer’s process involves mixing ingredients together in two large tanks. The PLC guiding the batch process starts up, dumps X lbs of ingredient A in, then X lbs of ingredient B, etc. The technician wanted to view and track the exact weight of each ingredient poured into each tank, as opposed to just assuming that the right amount was used which often proved inaccurate.

The plant has two large industrial serial scales used to weigh the tanks. They’re using a dataTaker DT80 data logger to measure, record and track the tanks’ weight via connection to a load cell on each tank. This provides a way to fine-tune the batch process and ensure repeatability and quality control.

The scale sends a serial data string to the DT80 whenever its weight changes as a new ingredient is poured or when its contents are emptied. Users want to read the data from each tank and log these values in the logger, so the DT80 is set to automatically trigger every time it receives the serial data string from the scale. These are non-printable characters: an example of a serial data string output from the scale is “1$”.

Recording the Variables:

The scales are wired into an intelligent serial switch (RS-232). The switch sees a string of serial data and automatically sends it to the dataTaker data logger. The dataTaker is intelligent so it’s able to parse the desired data from the string. Generated by dEX Configuration Builder Version 1.29.1924 (Firmware Version 9.08.3932), our custom program for this customer uses a schedule that is triggered by the receipt of the serial character. This string is in the serial input buffer of the data logger.

There are two parts to the data—Part A and Part B (representing the two tanks). However, characters are actually sent over a serial communications interface in numeric format, so the letter A is the ASCII value 65, while the letter B is 66, etc.. The dataTaker saves these values in a string variable and records each instance to save the part type; the code (written in dEX software) looks for the word ‘Part’ in the data. It also does this with other variables including:

  • ‘A’ (part)
  • ‘B’ (part)
  • ‘Actual’ (weight)
  • ‘Target’ (weight)

For example when looking for the variable ‘Part’, the dEX software automatically positions the pointer at the next character after the variable’s name where it appears in the serial data string. The dataTaker also reads one character (which should be a space) and discards it, uses an IF statement to read the next character (which should be ‘A’ or ‘B’), and saves the ASCII value in 1CV (channel variable). In this way the logger records the weight as being from Tank A or B. Likewise dEX also does this with each other variable.

Tracking Floating-Point Numbers:

The dataTaker is intelligent so it’s able to read a floating-point number (i.e. must contain only numbers and a decimal point, such as 8.00). Finally, we look for the text “ACTUAL:” and “TARGET:” and read the floating point values immediately after each word as the respective values and log these. The datalogger reads these numbers and saves them in a variable with a time-stamp, recording this as the tank’s Actual weight. The DT80 also replaces the value that was there before with the new value. The logger then performs a search for the word ‘Target’ and reads the floating-point number there, stores that number as the Target weight, and places the cursor a space after that as with the other variables.

In the dataTaker’s output all this looks like:

! PART A RESIN

30-JAN-2015   10:18:32

! PART A

! Units:                                 kg

! Actual:                               0.00

! Target:                           14.00

!END

!

Implementation:

Owing to the ease of programming in the dEX software, it took our technical engineering department about an hour to write this program. The user has successfully implemented it into his plant’s batch process and has already modified it to fine-tune the process.

DataTaker’s parsing technique can also be used with other types of serial data such as solar radiation, temperature, weather measurements, etc. If you have an intelligent solar inverter, dataTaker can read data from that as well, making it a powerful solution for many different applications.

The Code with Comments:

  • 1SERIAL(“m[PART]”,W) = Looks for the first occurrence of the text “PART” in the serial string and discards all characters up to and including the “T”
  • 1SERIAL(“m[PART]”,W) = Looks for the second occurrence of the text “PART” in the serial string and discards all characters up to and including the “T”
  • 1SERIAL(“m[PART]”,W) = Looks for the third occurrence of the text “PART” in the serial string and discards all characters up to and including the “T”
  • 1SERIAL(“%*1c%1c[1CV]”,W) = Reads one character (which should be a space) and discards it, reads the next character (which should be “A” or “B”), and saves the ASCII value in 1CV
  • IF(1CV==65){1$=” A”} = If the decimal value of the ASCII character in 1CV is 65, sets the string variable to the character “A”
  • IF(1CV==66){1$=” B”} = If the decimal value of the ASCII character in 1CV is 66, sets the string variable to the character “B”
  • 1$(“Part”)  = Logs the string variable to save the part type
  • 1SERIAL(“m[Actual:]”,W) = Looks for the text “Actual” in the serial string and discards all characters up to and including the “:”
  • 1SERIAL(“%f[2CV]”,W) = Reads the next number as a floating point value (must contain only numbers and the “.”) and saves it in 2CV
  • 2CV(“ActualWeight~kg”) = Logs the value in 2CV as the actual weight, and assumes that its in kg
  • 1SERIAL(“m[Target:]”,W) = Looks for the text “Target” in the serial string and discards all characters up to and including the “:”
  • 1SERIAL(“%f[3CV]e”,W) = Reads the next number as a floating point value (must contain only numbers and the “.”) and saves it in 3CV. Erases any remaining characters in the receive buffer using the “e” command
  • 3CV(“TargetWeight~kg”) = Logs the value in 3CV as the target weight, and assumes that its in kg