Here are the essential files:
#include “WylerZerotronicSensor.h”
#include “WylerUtils.h”
#include “mbed.h”
#include 
#include 
#include 
class WylerInterface
{
public:
enum WylerCommand
{
    WriteGateTime = 0,
    ReadSensorAngle = 1,
    ReadZeroOffset = 2,
    WriteZeroOffset = 3
};
enum ZeroOffsetByte
{
    ZeroOffsetByte0 = 0,
    ZeroOffsetByte1 = 1,
    ZeroOffsetByte2 = 2,
    ZeroOffsetByte3 = 3,
    Nothing = 4
};
enum NachrichtenTyp
{
    Sensornachricht = 17,
    BestaetigungSensornachricht = 18,
    Statusabfrage = 33,
    Statusmeldung = 34,
    AktivierungTransparenteTCPVerbindung = 49,
    BestaetigungTransparenteTCPVerbindung = 50
};
bool VERBOSE;
WylerZerotronicSensor *sensor;
WylerCommand cmd_w;
//WylerUtils *wu;
void init(bool v)
{
    this->VERBOSE = v;
}
/// <summary>
/// use reduced command set and send through SendCommand to
/// get the tildes and other trappings
/// </summary>
/// <param name="devAddr"></param>
/// <param name="cmd"></param>
/// <param name="zob"></param>
/// <param name="sNewZeroOffset"></param>
/// <returns></returns>
const char *GetWylerRS485CommandExt(int devAddr, WylerCommand cmd, ZeroOffsetByte zob, float sNewZeroOffsetOrGateTime = 1000)
{
    bool verbose = VERBOSE;
    const char *strCommand = "~~~~";
    if (!(this->sensor)) // equal NULL
        this->sensor = new WylerZerotronicSensor();
    sensor->SetDeviceAddress(devAddr);
    /* #region  WylerCommands */
    switch (cmd)
    {
    case WriteGateTime:
    {
        // set measure interval <WriteGateTime> to sensor
        // assume that rs 485/sensor address 1, address range is  0...255  each addr. is unique; addr 0 & 255 are for broadcast only
        // use levelmeter 2000 to set the rs 485/sensor address
        // gate time = 1000ms = 499 = 1F3 (hex);
        // time calculation:  ((time [ms] / 2)-1) = value (dec) -> convert to hex
        //  how to set command string together:
        //
        //  section:        explaination                                example string (part)
        //  -------         ------------                                ---------------------
        //  rs 485 addr:    set in sendCommand, when no sensor is passed over, "FF" is taken
        //  subaddr:        always 1 except ZeroMATIC 1=x, 2=y          :         "1"
        //  opcode:         writegate = opcode A(hex), see manual       :          "A"
        //  data:           format depends on command, check manual
        //  "A003A0" is fixed, following of 1F3 timevalue(3 nibbles)    :           "A003A01F3"
        //  Checksum:       set in sendCommand
        int gatetime = (int)(sNewZeroOffsetOrGateTime) / 2 - 1;
        formatPrint("GetWylerRS485Command:gatetime:", gatetime, verbose);
        //convert gatetime to hexadecimal string
        char res[5]; /* two bytes of hex = 4 characters, plus NULL terminator */
        if (gatetime <= 0xFFFF)
            sprintf(&res[0], "%03x", gatetime);
        formatPrint("GetWylerRS485Command:res:", res, verbose);
        charArrayUpper(res);
        char _tmpCommand[7] = "A003A0";
        strcat(_tmpCommand, res);
        strCommand = CreateSendCommandExt(this->sensor, _tmpCommand, 1);
        formatPrint("GetWylerRS485Command:strCommand:", strCommand, verbose);
        //free(_tmpCommand);
    }
    break;
    case ReadSensorAngle:
    {
        // how to set command string together:
        //
        //  rs 485 addr:    set in sendCommand
        //  subaddr:        always 1 except ZeroMATIC 1=x, 2=y          :         "1"
        //  opcode:         ReadAngle = opcode D(hex), see manual       :          "D"
        //  data:           format depends on command, check manual
        //                  "D00000000" is fixed                        :           "00000000"
        //  Checksum:       set in sendCommand
        const char tmpCommand_ReadSensorAngle[10] = "D00000000"; // command without checksum
        strCommand = CreateSendCommandExt(this->sensor, tmpCommand_ReadSensorAngle, 0);
        formatPrint("GetWylerRS485Command:strCommand:", strCommand, verbose);
    }
    break;
    case ReadZeroOffset:
    {
        switch (zob)
        {
        case ZeroOffsetByte0:
        {
            const char tmpCommand_ZeroOffsetByte0[10] = "200000200"; // EEPROM addr 2 (hex) -> ReadEEProm EEPROM[2] = ZeroOffset.Byte0
            strCommand = CreateSendCommandExt(this->sensor, tmpCommand_ZeroOffsetByte0, 0);
        }
        break;
        case ZeroOffsetByte1:
        {
            const char tmpCommand_ZeroOffsetByte1[10] = "200000300"; // EEPROM addr 3 (hex) -> ReadEEProm EEPROM[3] = ZeroOffset.Byte1
            strCommand = CreateSendCommandExt(this->sensor, tmpCommand_ZeroOffsetByte1, 0);
        }
        break;
        case ZeroOffsetByte2:
        {
            const char tmpCommand_ZeroOffsetByte2[10] = "200000400"; // EEPROM addr 4 (hex) -> ReadEEProm EEPROM[4] = ZeroOffset.Byte2
            strCommand = CreateSendCommandExt(this->sensor, tmpCommand_ZeroOffsetByte2, 0);
        }
        break;
        case ZeroOffsetByte3:
        {
            const char tmpCommand_ZeroOffsetByte3[10] = "200000500"; // EEPROM addr 5 (hex) -> ReadEEProm EEPROM[5] = ZeroOffset.Byte3
            strCommand = CreateSendCommandExt(this->sensor, tmpCommand_ZeroOffsetByte3, 0);
        }
        break;
        case Nothing:
        {
            strCommand = "";
        }
        break;
        }
    }
    break;
    case WriteZeroOffset:
    {
        sensor->uZeroOffset.nF32 = sNewZeroOffsetOrGateTime;
        switch (zob)
        {
        case ZeroOffsetByte0:
        {
            char *strDataByte_ZeroOffsetByte0 = byte9ToChars(sensor->uZeroOffset.nU8_0); // convert sum to hex string ( format 2 letters)
            char tmpCommand_ZeroOffsetByte0[8];
            strcpy(tmpCommand_ZeroOffsetByte0, "C005002");
            strcat(tmpCommand_ZeroOffsetByte0, strDataByte_ZeroOffsetByte0);
            strCommand = CreateSendCommandExt(this->sensor, tmpCommand_ZeroOffsetByte0, 0);
            free(strDataByte_ZeroOffsetByte0);
        }
        break;
        case ZeroOffsetByte1:
        {
            char *strDataByte_ZeroOffsetByte1 = byte9ToChars(sensor->uZeroOffset.nU8_1); // convert sum to hex string ( format 2 letters)
            char tmpCommand_ZeroOffsetByte1[8];
            strcpy(tmpCommand_ZeroOffsetByte1, "C005003");
            strcat(tmpCommand_ZeroOffsetByte1, strDataByte_ZeroOffsetByte1);
            strCommand = CreateSendCommandExt(this->sensor, tmpCommand_ZeroOffsetByte1, 0);
            free(strDataByte_ZeroOffsetByte1);
        }
        break;
        case ZeroOffsetByte2:
        {
            char *strDataByte_ZeroOffsetByte2 = byte9ToChars(sensor->uZeroOffset.nU8_2); // convert sum to hex string ( format 2 letters)
            char tmpCommand_ZeroOffsetByte2[8];
            strcpy(tmpCommand_ZeroOffsetByte2, "C005004");
            strcat(tmpCommand_ZeroOffsetByte2, strDataByte_ZeroOffsetByte2);
            strCommand = CreateSendCommandExt(this->sensor, tmpCommand_ZeroOffsetByte2, 0);
            free(strDataByte_ZeroOffsetByte2);
        }
        break;
        case ZeroOffsetByte3:
        {
            char *strDataByte_ZeroOffsetByte3 = byte9ToChars(sensor->uZeroOffset.nU8_3); // convert sum to hex string ( format 2 letters)
            char tmpCommand_ZeroOffsetByte3[8];
            strcpy(tmpCommand_ZeroOffsetByte3, "C005005");
            strcat(tmpCommand_ZeroOffsetByte3, strDataByte_ZeroOffsetByte3);
            strCommand = CreateSendCommandExt(this->sensor, tmpCommand_ZeroOffsetByte3, 0);
            free(strDataByte_ZeroOffsetByte3);
        }
        break;
        case Nothing:
        {
            strCommand = "";
        }
        break;
        }
    }
    break;
    }
    /* #endregion */
    formatPrint("GetWylerRS485CommandExt:strCommand:", strCommand, VERBOSE);
    return strCommand;
}
////////////////////////////////////////////////////////////////////////////////
// string sendCommand(string _command)
//
// put together the complete command and send it to the serial IO
//
// param: command to send
// return: void
char *CreateSendCommandExt(WylerZerotronicSensor *sensor, const char *_command, bool verbose)
{
    formatPrint("CreateSendCommandExt:_command:", _command, verbose);
    char strCommandToSend[1024] = "";
    char hexbuffer[5];
    char sCommand[1024] = "";
    if (sensor != NULL) // NOT equal NULL //&sensor
    {
        strcat(sCommand, sensor->sDeviceAddressAsChararray); // sensor->sDeviceAddress);
        formatPrint("CreateSendCommandExt:sCommand[sensor->sDeviceAddressAsChar()]:", sCommand, verbose);
        strcat(sCommand, "1");
        formatPrint("CreateSendCommandExt:sCommand[1]:", sCommand, verbose);
        strcat(sCommand, _command);
        formatPrint("CreateSendCommandExt:sCommand[_command]:", sCommand, verbose);
    }
    else
    {
        strcat(sCommand, "00");
        strcat(sCommand, _command);
    }
    calcCommandChecksumExt(sCommand, hexbuffer, verbose);
    formatPrint("CreateSendCommandExt:hexbuffer:", hexbuffer, verbose);
    //char checkSumCmd[14] = "011AA003A01F3";
    char nibbles[9] = "~~~~~~~~";
    strcat(strCommandToSend, nibbles);
    formatPrint("CreateSendCommandExt:strCommandToSend[nibbles]:", strCommandToSend, verbose);
    strcat(strCommandToSend, sCommand);
    formatPrint("CreateSendCommandExt:strCommandToSend[sCommand]:", strCommandToSend, verbose);
    strcat(strCommandToSend, hexbuffer);
    strcat(strCommandToSend, "\r");
    formatPrint("CreateSendCommandExt:strCommandToSend:", strCommandToSend, verbose);
    char *dup = (char *)malloc(strlen(strCommandToSend) + 1);
    return dup ? strcpy(dup, strCommandToSend) : dup;
}
};
WlyerZerotronicSensor:
/*
- 
WylerZerotronicSensor.h 
- 
- 
Created on: Jun 6, 2020 
- 
 Author: p26953
 
*/
#ifndef WYLERZEROTRONICSENSOR_H_
#define WYLERZEROTRONICSENSOR_H_
#pragma once
#include “mbed.h”
//#include “main.h”
#include “WylerUtils.h”
#include 
/////////
//NOT SUPPORTED YET
////////
//#include <Arduino.h>
// This union is used to convert 4 Bytes (UInt8) into a Single, a UInt32 or a UInt16.
struct WyBusUNION32
{
public:
//[FieldOffset(0)]
BYTE nU8_0;
//[FieldOffset(1)]
BYTE nU8_1;
//[FieldOffset(2)]
BYTE nU8_2;
//[FieldOffset(3)]
BYTE nU8_3;
//[FieldOffset(0)]
uint16_t nU16;
//[FieldOffset(0)]
uint32_t nU32;
//[FieldOffset(0)]
float nF32;
};
class WylerZerotronicSensor
{
public:
bool VERBOSE;
int nDeviceAddress = -1;
//String sDeviceAddressString;
char sDeviceAddressAsChararray[5];
WyBusUNION32 uZeroOffset;
int nSequenceNumber;
float fAngle;
union {
    int source;
    char tgt[sizeof(int)];
} converter;
void init(bool v)
{
    VERBOSE = v;
}
void SetDeviceAddress(int nDevAddress)
{
    //lets be sure our integer is in desired range
 int maxAdress = std::max(nDevAddress, 0);
    nDeviceAddress = std::min(maxAdress, 65535);
    //buffer big enough for 4 hex digits + terminating null
    //char hexbuffer[5];
    //sprintf(hexbuffer, "%02x", nDeviceAddress);
    //sDeviceAddressString = hexbuffer; //.ToString("X2");
    formatPrint("SetDeviceAddress:nDevAddress:", nDevAddress, VERBOSE);
    //formatPrint("SetDeviceAddress:hexbuffer:", hexbuffer, VERBOSE);
    //sDeviceAddressAsChararray[0] = '0';
    sprintf(sDeviceAddressAsChararray, "%02x", nDeviceAddress);
    charArrayUpper(sDeviceAddressAsChararray);
    formatPrint("SetDeviceAddress:sDeviceAddressAsChararray:", sDeviceAddressAsChararray, VERBOSE);
}
};
#endif /* WYLERZEROTRONICSENSOR1_H_ */