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_ */