Obsidean_VM/04-SIDEL/09 - SAE452 - Diet as Regul.../Maselli Sensor to Siemens P...

10 KiB

Introduction

This document provides an implementation guide for establishing communication between a Maselli sensor (which uses the ADAM protocol over RS485) and a Siemens S7-315 DP/PN PLC using a Waveshare RS232/485 TO WIFI ETH (B) gateway. This implementation handles the unidirectional communication where data flows from the sensor to the PLC.

Maselli Protocol with ADAM Overview

As per the provided documentation, the Maselli sensor communicates with the following characteristics:

  • Maselli UR29: RS485 with 115200 baud, 8N1 settings

  • Maselli UR62: RS485 with 19200 baud, 8N1 settings

  • Communication Type: Unidirectional (sensor sends data to PLC)

  • Data Format: String with specific format:

    # XX XX.YYY CkCk Cr
    

    Where:

    • # is the start character
    • XX is the ADAM address (2 chars)
    • XX.YYY is the Brix or Temperature value in mA (6 chars)
    • CkCk is the checksum (2 chars)
    • Cr is the carriage return
  • Value Range Example:

    • 4 mA corresponds to Low Brix value (e.g., 0 Brix)
    • 20 mA corresponds to High Brix value (e.g., 80 Brix)

SCL Implementation

The following SCL code provides a complete implementation for handling this communication. The implementation consists of multiple parts:

  1. A function block for managing TCP/IP communication with the gateway
  2. Functions for parsing the Maselli protocol string
  3. Functions for scaling the mA value to the appropriate Brix value
  4. Configuration functions for the TCP connection

Main Function Block

FUNCTION_BLOCK "FB_Maselli_Communications"
VAR_INPUT
    xExecute : BOOL;                    // Trigger to initiate connection
    tConnectionID : TCON_IP_v4;         // TCP connection parameters
END_VAR

VAR_OUTPUT
    xConnected : BOOL;                  // Connection status
    xError : BOOL;                      // Communication error
    wErrorID : WORD;                    // Error code
    rBrixValue : REAL;                  // Calculated Brix value
    rTempValue : REAL;                  // Calculated Temperature value (if applicable)
    rCurrentmA : REAL;                  // Received mA value
END_VAR

VAR
    // TCP communication variables
    fbTCON : TCON;                      // FB for TCP connection
    fbTRCV : TRCV;                      // FB for TCP reception
    xTCONExecute : BOOL;
    xTRCVExecute : BOOL;
    wTCONID : WORD := 1;                // Connection ID
    
    // Buffer and processing variables
    aRxBuffer : ARRAY[0..255] OF BYTE;  // Reception buffer
    iRxLength : INT;                    // Received length
    sRxString : STRING[255];            // Reception string
    sParsedValue : STRING[6];           // Extracted value as string (XX.YYY)
    
    // Parsing variables
    iState : INT := 0;                  // Parsing state
    xNewDataReceived : BOOL := FALSE;   // New data flag
    
    // Scaling variables
    rLowBrix : REAL := 0.0;             // Low Brix value (4mA)
    rHighBrix : REAL := 80.0;           // High Brix value (20mA)
END_VAR

VAR CONSTANT
    START_CHAR : BYTE := 16#23;         // '#' in ASCII
END_VAR

BEGIN
    // ---- TCP Connection Management ----
    IF xExecute AND NOT xConnected THEN
        xTCONExecute := TRUE;
    END_IF;
    
    // Establish connection
    fbTCON(
        EN := TRUE,
        ENO => ,
        REQ := xTCONExecute,
        ID := wTCONID,
        CONNECT := tConnectionID,
        DONE => xConnected,
        BUSY => ,
        ERROR => xError,
        STATUS => wErrorID
    );
    
    // Reset connection trigger
    IF xConnected OR xError THEN
        xTCONExecute := FALSE;
    END_IF;
    
    // ---- Data Reception ----
    IF xConnected THEN
        xTRCVExecute := TRUE;
        
        // Receive data
        fbTRCV(
            EN := TRUE,
            ENO => ,
            REQ := xTRCVExecute,
            ID := wTCONID,
            LEN := 0,                  // Adhoc mode (receives whatever is available)
            DATA := aRxBuffer,
            RCVD_LEN => iRxLength,
            DONE => xNewDataReceived,
            BUSY => ,
            ERROR => xError,
            STATUS => wErrorID
        );
        
        // Process received data
        IF xNewDataReceived AND iRxLength > 0 THEN
            // Convert data to string for processing
            sRxString := '';
            FOR i := 0 TO iRxLength-1 DO
                sRxString := CONCAT(IN1 := sRxString, 
                                   IN2 := CHR(IN := aRxBuffer[i]));
            END_FOR;
            
            // Process Maselli/ADAM protocol
            ParseMaselliString(sRxString);
            
            // Calculate Brix value based on mA value (linear scale)
            rBrixValue := LinearScale(rCurrentmA, 4.0, 20.0, rLowBrix, rHighBrix);
            
            // Reset flag
            xNewDataReceived := FALSE;
        END_IF;
    END_IF;
END_FUNCTION_BLOCK

Parsing Function

// Function to process the received Maselli/ADAM string
FUNCTION "ParseMaselliString" : VOID
VAR_INPUT
    sInputString : STRING;
END_VAR
VAR_TEMP
    sCurrentChar : STRING(1);
    iPos : INT := 0;
    iParseState : INT := 0;  // 0:Waiting for #, 1:Reading addr, 2:Reading value, 3:Reading checksum
    sAddrStr : STRING(2);
    sValueStr : STRING(6);
    sChecksumStr : STRING(2);
END_VAR
BEGIN
    // Reset variables
    sAddrStr := '';
    sValueStr := '';
    sChecksumStr := '';
    
    // Parse the string character by character
    FOR iPos := 0 TO LEN(sInputString) - 1 DO
        sCurrentChar := MID(IN := sInputString, L := 1, P := iPos + 1);
        
        CASE iParseState OF
            0:  // Waiting for start character '#'
                IF sCurrentChar = '#' THEN
                    iParseState := 1;
                END_IF;
                
            1:  // Reading ADAM address (2 characters)
                sAddrStr := CONCAT(IN1 := sAddrStr, IN2 := sCurrentChar);
                IF LEN(sAddrStr) = 2 THEN
                    iParseState := 2;
                END_IF;
                
            2:  // Reading mA value (6 characters, format XX.YYY)
                sValueStr := CONCAT(IN1 := sValueStr, IN2 := sCurrentChar);
                IF LEN(sValueStr) = 6 THEN
                    iParseState := 3;
                    // Convert string to real value
                    #rCurrentmA := STRING_TO_REAL(sValueStr);
                END_IF;
                
            3:  // Reading checksum (2 characters)
                sChecksumStr := CONCAT(IN1 := sChecksumStr, IN2 := sCurrentChar);
                // Checksum validation not implemented in this simplified example
        END_CASE;
    END_FOR;
END_FUNCTION

Scaling Function

// Function to linearly scale the mA value to Brix
FUNCTION "LinearScale" : REAL
VAR_INPUT
    rInput : REAL;         // Value to scale (mA)
    rInMin : REAL;         // Input minimum (4mA)
    rInMax : REAL;         // Input maximum (20mA)
    rOutMin : REAL;        // Output minimum (0 Brix)
    rOutMax : REAL;        // Output maximum (80 Brix)
END_VAR
BEGIN
    // Linear scaling formula
    #LinearScale := (rInput - rInMin) * (rOutMax - rOutMin) / (rInMax - rInMin) + rOutMin;
    
    // Ensure result is within limits
    IF #LinearScale < rOutMin THEN
        #LinearScale := rOutMin;
    ELSIF #LinearScale > rOutMax THEN
        #LinearScale := rOutMax;
    END_IF;
END_FUNCTION

Main Application Block

// Main application block
ORGANIZATION_BLOCK "OB1"
VAR_TEMP
    // Temporary variables
END_VAR
BEGIN
    // Configure TCP connection
    "ConfigureTCPConnection"();
    
    // Process Maselli data
    "FB_Maselli_Communications"(
        xExecute := TRUE,
        tConnectionID := "g_tConnection"
    );
    
    // Additional code to use Brix values can be added here
END_ORGANIZATION_BLOCK

Connection Configuration Function

// Function to configure TCP connection parameters
FUNCTION "ConfigureTCPConnection" : VOID
VAR_GLOBAL
    g_tConnection : TCON_IP_v4;    // Global variable for connection parameters
END_VAR
BEGIN
    // Configure TCP connection parameters
    g_tConnection.InterfaceId := 64;    // Ethernet interface ID (verify in hardware)
    g_tConnection.ID := 1;              // Connection ID
    g_tConnection.ConnectionType := 11; // Connection type: TCP
    g_tConnection.ActiveEstablished := TRUE; // PLC initiates connection
    
    // IP and port of Waveshare gateway
    g_tConnection.RemoteAddress.ADDR[1] := 192;    // IP Address: 192.168.x.x
    g_tConnection.RemoteAddress.ADDR[2] := 168;    // Adjust according to gateway IP
    g_tConnection.RemoteAddress.ADDR[3] := 1;      // Adjust according to gateway IP
    g_tConnection.RemoteAddress.ADDR[4] := 10;     // Adjust according to gateway IP
    g_tConnection.RemotePort := 8899;              // Default gateway port
    
    // Local port for TCP connection
    g_tConnection.LocalPort := 2000;               // Arbitrary local port
END_FUNCTION

Configuration Guide

To implement this solution, follow these steps:

1. Configure the Waveshare Gateway

Configure the Waveshare RS232/485 TO WIFI ETH (B) gateway in transparent transmission mode with these parameters:

  • For UR29 sensor:

    • RS485: 115200 baud, 8N1
    • TCP Server mode (recommended)
    • Fixed IP address on your network
  • For UR62 sensor:

    • RS485: 19200 baud, 8N1
    • TCP Server mode (recommended)
    • Fixed IP address on your network

2. PLC Configuration

  • Import the SCL code into your TIA Portal project
  • Adjust the IP address settings in the ConfigureTCPConnection function to match your gateway's IP
  • Modify the rLowBrix and rHighBrix values according to your specific application requirements
  • Configure the Ethernet port of the S7-315 PLC to be on the same subnet as the gateway

3. Verification

After implementing the code:

  • Monitor the xConnected output to verify the connection status
  • Check the rBrixValue output to see the converted Brix values
  • Use the xError and wErrorID outputs for troubleshooting if connection issues occur

Additional Notes

  • This implementation focuses on handling the reception of data in the specified Maselli/ADAM format
  • The checksum validation is not implemented in this example but could be added for improved reliability
  • For optimal performance, ensure the network connection between the PLC and the gateway is stable
  • Consider adding watchdog functionality to detect communication failures