2014-05-12 10:46:53 +02:00
|
|
|
/*@!Encoding:1252*/
|
|
|
|
|
|
|
|
includes
|
|
|
|
{
|
2014-05-27 13:03:56 +02:00
|
|
|
#include "include\ModbusUdpClientCommon.cin"
|
2014-05-12 10:46:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
variables
|
|
|
|
{
|
2014-05-21 13:26:45 +02:00
|
|
|
msTimer gtRead;
|
2014-05-12 10:46:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get information of local network interface such like ip address
|
|
|
|
|
|
|
|
on preStart
|
|
|
|
{
|
|
|
|
writeClear(0);
|
2014-05-21 13:38:59 +02:00
|
|
|
setStartdelay(10);
|
2014-05-27 13:03:56 +02:00
|
|
|
OutputDebugLevel = Warning;
|
2014-05-12 10:46:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
on start
|
|
|
|
{
|
2014-05-21 13:26:45 +02:00
|
|
|
ModbusInit();
|
|
|
|
|
2014-05-26 12:07:04 +02:00
|
|
|
if (@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits > 0)
|
|
|
|
ModbusReadBits(0x200, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits);
|
|
|
|
if (@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputRegisters > 0)
|
|
|
|
ModbusReadRegisters(0x200, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputRegisters);
|
|
|
|
|
|
|
|
setTimerCyclic(gtRead, 1, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Config::Interval);
|
2014-05-12 10:46:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Modbus events ----------------------------------------------------------------------
|
|
|
|
void OnModbusReadBitsFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
|
|
|
|
{
|
2014-05-26 12:07:04 +02:00
|
|
|
word i;
|
2014-05-21 13:29:29 +02:00
|
|
|
|
|
|
|
switch (error)
|
|
|
|
{
|
|
|
|
case Exception:
|
|
|
|
break;
|
|
|
|
case Timeout:
|
|
|
|
break;
|
|
|
|
case FinalTimeout:
|
2014-05-26 12:07:04 +02:00
|
|
|
sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits");
|
2014-05-21 13:29:29 +02:00
|
|
|
for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputBits; i++)
|
2014-05-26 12:07:04 +02:00
|
|
|
@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::InputBits[i] = -1;
|
|
|
|
sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits");
|
2014-05-21 13:29:29 +02:00
|
|
|
break;
|
|
|
|
}
|
2014-05-15 14:43:52 +02:00
|
|
|
}
|
2014-05-21 13:29:29 +02:00
|
|
|
|
2014-05-26 12:07:04 +02:00
|
|
|
void OnModbusReadRegistersFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
|
2014-05-15 14:43:52 +02:00
|
|
|
{
|
2014-05-26 12:07:04 +02:00
|
|
|
byte i;
|
2014-05-21 13:29:29 +02:00
|
|
|
|
|
|
|
switch (error)
|
|
|
|
{
|
|
|
|
case Exception:
|
|
|
|
break;
|
|
|
|
case Timeout:
|
|
|
|
break;
|
|
|
|
case FinalTimeout:
|
2014-05-26 12:07:04 +02:00
|
|
|
sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters");
|
2014-05-21 13:29:29 +02:00
|
|
|
for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters; i++)
|
2014-05-26 12:07:04 +02:00
|
|
|
@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::InputRegisters[i] = -1;
|
|
|
|
sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters");
|
2014-05-21 13:29:29 +02:00
|
|
|
break;
|
|
|
|
}
|
2014-05-15 14:43:52 +02:00
|
|
|
}
|
|
|
|
|
2014-05-26 12:07:04 +02:00
|
|
|
void OnModbusWriteBitFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
void OnModbusWriteRegisterFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
void OnModbusWriteMasksFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
void OnModbusReadWriteRegistersFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
void OnModbusWriteBitsFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
void OnModbusWriteRegistersFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-05-12 10:46:53 +02:00
|
|
|
|
2014-05-27 13:03:56 +02:00
|
|
|
void OnModbusReadBitsSuccess(struct ModbusResReceiveBits mbres, byte bitStatus[], struct ModbusReqRead mbreq)
|
2014-05-12 10:46:53 +02:00
|
|
|
{
|
2014-05-21 13:29:29 +02:00
|
|
|
word i;
|
|
|
|
|
2014-05-27 13:03:56 +02:00
|
|
|
switch(mbreq.Address)
|
2014-05-21 13:29:29 +02:00
|
|
|
{
|
2014-05-26 12:07:04 +02:00
|
|
|
case 0x200: // set output bits
|
|
|
|
sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits");
|
|
|
|
for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits; i++)
|
|
|
|
@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputBits[i] = bitStatus[i];
|
|
|
|
sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits");
|
|
|
|
break;
|
|
|
|
default: // set input bits
|
|
|
|
sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits");
|
|
|
|
for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputBits; i++)
|
|
|
|
@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::InputBits[i] = bitStatus[i];
|
|
|
|
sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits");
|
2014-05-21 13:29:29 +02:00
|
|
|
break;
|
|
|
|
}
|
2014-05-12 10:46:53 +02:00
|
|
|
}
|
2014-05-21 13:29:29 +02:00
|
|
|
|
2014-05-27 13:03:56 +02:00
|
|
|
void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbres, struct ModbusReqRead mbreq)
|
2014-05-12 10:46:53 +02:00
|
|
|
{
|
2014-05-15 14:43:52 +02:00
|
|
|
char str[20*5];
|
|
|
|
long fehler;
|
2014-05-15 18:40:08 +02:00
|
|
|
byte i;
|
2014-05-15 14:43:52 +02:00
|
|
|
|
2014-05-27 13:03:56 +02:00
|
|
|
switch (mbreq.Address)
|
2014-05-15 14:43:52 +02:00
|
|
|
{
|
2014-05-26 12:07:04 +02:00
|
|
|
case 0x200: // set output registers
|
|
|
|
sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputRegisters");
|
|
|
|
for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputRegisters; i++)
|
2014-05-27 13:03:56 +02:00
|
|
|
@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputRegisters[i] = mbres.Data[i];
|
2014-05-26 12:07:04 +02:00
|
|
|
sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputRegisters");
|
2014-05-15 14:43:52 +02:00
|
|
|
break;
|
2014-05-26 12:07:04 +02:00
|
|
|
case 0x000: // set output registers
|
|
|
|
sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters");
|
|
|
|
for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters; i++)
|
2014-05-27 13:03:56 +02:00
|
|
|
@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::InputRegisters[i] = mbres.Data[i];
|
2014-05-26 12:07:04 +02:00
|
|
|
sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters");
|
2014-05-21 13:29:29 +02:00
|
|
|
break;
|
2014-05-15 14:43:52 +02:00
|
|
|
default:
|
2014-05-21 13:29:29 +02:00
|
|
|
// Not recognized
|
2014-05-27 13:03:56 +02:00
|
|
|
dbin_to_strhex(mbres.Data, str);
|
|
|
|
writeLineEx(0, 1, "<%NODE_NAME%> OnModbusReceiveRegisters: Received %d bytes at 0x%04X: %s", mbres.ByteCount, mbreq.Address, str);
|
2014-05-15 14:43:52 +02:00
|
|
|
break;
|
|
|
|
}
|
2014-05-12 10:46:53 +02:00
|
|
|
}
|
2014-05-21 13:29:29 +02:00
|
|
|
|
2014-05-15 14:43:52 +02:00
|
|
|
void OnModbusWriteBitSuccess(struct ModbusResConfirmSingle mbc)
|
2014-05-12 10:46:53 +02:00
|
|
|
{
|
|
|
|
}
|
2014-05-15 14:43:52 +02:00
|
|
|
void OnModbusWriteRegisterSuccess(struct ModbusResConfirmSingle mbc)
|
2014-05-12 10:46:53 +02:00
|
|
|
{
|
|
|
|
}
|
2014-05-15 14:43:52 +02:00
|
|
|
void OnModbusWriteBitsSuccess(struct ModbusResConfirmMultiple mbc)
|
2014-05-12 10:46:53 +02:00
|
|
|
{
|
|
|
|
}
|
2014-05-15 14:43:52 +02:00
|
|
|
void OnModbusWriteRegistersSuccess(struct ModbusResConfirmMultiple mbc)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
void OnModbusWriteMasksSuccess(struct ModbusResConfirmMasks mbc)
|
2014-05-12 10:46:53 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-05-27 13:03:56 +02:00
|
|
|
void OnModbusClientPanics(enum FatalErrors reason)
|
|
|
|
{
|
|
|
|
writeLineEx(0, 4, "<%NODE_NAME%> FATAL! %d", reason);
|
|
|
|
switch(reason)
|
|
|
|
{
|
|
|
|
case ParsingBuffer:
|
|
|
|
case ModbusPackageWasSplit:
|
|
|
|
case DeviceCodeUnknown:
|
|
|
|
case VendorIdUnknown:
|
|
|
|
runError(1001, reason);
|
|
|
|
break;
|
|
|
|
case ConnectionError:
|
|
|
|
gtRead.Cancel();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2014-05-12 10:46:53 +02:00
|
|
|
|
|
|
|
// Key events -------------------------------------------------------------------------
|
2014-05-21 13:26:45 +02:00
|
|
|
on timer gtRead
|
|
|
|
{
|
|
|
|
if (@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters > 0)
|
|
|
|
ModbusReadRegisters(0x0000, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters);
|
|
|
|
if (@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputBits > 0)
|
2014-06-16 09:23:21 +02:00
|
|
|
ModbusReadBits(0x0000, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputBits);
|
2014-05-21 13:26:45 +02:00
|
|
|
}
|
|
|
|
|
2014-05-21 13:29:29 +02:00
|
|
|
on sysvar %BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputBits
|
2014-05-15 14:43:52 +02:00
|
|
|
{
|
2014-06-16 09:23:21 +02:00
|
|
|
word count, i;
|
2014-05-21 13:29:29 +02:00
|
|
|
byte bitStatus[1968];
|
2014-05-26 12:07:04 +02:00
|
|
|
|
|
|
|
count = @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits;
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
bitStatus[i] = @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputBits[i];
|
|
|
|
|
2014-06-16 09:23:21 +02:00
|
|
|
ModbusWriteBitsB(0, count, bitStatus);
|
2014-05-15 14:43:52 +02:00
|
|
|
}
|
2014-05-21 13:29:29 +02:00
|
|
|
on sysvar %BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputRegisters
|
2014-05-12 10:46:53 +02:00
|
|
|
{
|
2014-05-26 12:07:04 +02:00
|
|
|
word count, i;
|
|
|
|
word regValues[123];
|
|
|
|
|
|
|
|
count = @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputRegisters;
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
regValues[i] = @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputRegisters[i];
|
|
|
|
|
|
|
|
ModbusWriteRegisters(0x000, count, regValues);
|
|
|
|
}
|
|
|
|
|
|
|
|
on sysvar %BUS_TYPE%%CHANNEL%::%NODE_NAME%::Config::Interval
|
|
|
|
{
|
|
|
|
if (@this <= 0)
|
|
|
|
gtRead.Cancel();
|
|
|
|
else
|
|
|
|
setTimerCyclic(gtRead, @this);
|
2014-05-12 10:46:53 +02:00
|
|
|
}
|
|
|
|
|
2014-05-21 13:29:29 +02:00
|
|
|
on key '+'
|
2014-05-15 14:43:52 +02:00
|
|
|
{
|
2014-05-26 12:07:04 +02:00
|
|
|
word i;
|
|
|
|
|
|
|
|
sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits");
|
|
|
|
for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits; i++)
|
|
|
|
@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputBits[i] = 1;
|
|
|
|
sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits");
|
2014-05-15 14:43:52 +02:00
|
|
|
}
|
2014-05-21 13:29:29 +02:00
|
|
|
on key '-'
|
2014-05-15 14:43:52 +02:00
|
|
|
{
|
2014-05-26 12:07:04 +02:00
|
|
|
word i;
|
|
|
|
|
|
|
|
sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits");
|
|
|
|
for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits; i++)
|
|
|
|
@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputBits[i] = 0;
|
|
|
|
sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits");
|
2014-05-21 13:26:45 +02:00
|
|
|
}
|