Jonny007-MKD
93dd56469d
Introduced loops to automatically split requests that are too large for Modbus ModbusClient.can Modified Modbus events so that the split requests (see above) will be written at the correct position in sys vars ModbusFunctions.cin DeviceInformation.cin Introduced new file that will handle most device specific things ModbusStructs.cin Introduced new constants with maximum Modbus values MakeConfig.can Increment IP address with swapDWord Moved detection stuff to DeviceInformation.cin
241 lines
7.5 KiB
Plaintext
241 lines
7.5 KiB
Plaintext
/*@!Encoding:1252*/
|
|
|
|
includes
|
|
{
|
|
#include "include\ModbusUdpClientCommon.cin"
|
|
#include "include\DeviceInformation.cin"
|
|
}
|
|
|
|
variables
|
|
{
|
|
msTimer gtRead;
|
|
}
|
|
|
|
on preStart
|
|
{
|
|
writeClear(0);
|
|
setStartdelay(10);
|
|
OutputDebugLevel = MbDebug;
|
|
}
|
|
|
|
on start
|
|
{
|
|
DeviceInit(@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::Vendor);
|
|
ModbusInit();
|
|
|
|
ModbusReadOutBits(gDevOutputBitAddr, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits);
|
|
ModbusReadOutRegisters(gDevOutputRegAddr, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputRegisters);
|
|
|
|
setTimerCyclic(gtRead, 1, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Config::Interval);
|
|
}
|
|
|
|
|
|
// Modbus events ----------------------------------------------------------------------
|
|
void OnModbusReadBitsFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
|
|
{
|
|
word i;
|
|
|
|
switch (error)
|
|
{
|
|
case Exception:
|
|
break;
|
|
case Timeout:
|
|
break;
|
|
case FinalTimeout:
|
|
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] = -1;
|
|
sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits");
|
|
break;
|
|
}
|
|
}
|
|
|
|
void OnModbusReadRegistersFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
|
|
{
|
|
byte i;
|
|
|
|
switch (error)
|
|
{
|
|
case Exception:
|
|
break;
|
|
case Timeout:
|
|
break;
|
|
case FinalTimeout:
|
|
sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters");
|
|
for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters; i++)
|
|
@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::InputRegisters[i] = -1;
|
|
sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters");
|
|
break;
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
}
|
|
|
|
|
|
void OnModbusReadBitsSuccess(struct ModbusResReceiveBits mbres, byte bitStatus[], struct ModbusReqRead mbreq)
|
|
{
|
|
word i, offset;
|
|
|
|
switch (mbres.Header.FuncCode) // We assume that we separate between 0x01 and 0x02 even though the address space may be the same
|
|
{
|
|
case 0x01: // Read output bits
|
|
sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits");
|
|
|
|
offset = mbreq.Address - gDevOutputBitAddr; // Get the offset to the base output bit address
|
|
for (i = 0; i < mbreq.Count; i++)
|
|
@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputBits[i + offset] = bitStatus[i];
|
|
|
|
sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits");
|
|
break;
|
|
|
|
|
|
case 0x02: // Read input bits
|
|
sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits");
|
|
|
|
offset = mbreq.Address - gDevInputBitAddr; // Get the offset to the base input bit address
|
|
for (i = 0; i < mbreq.Count; i++)
|
|
@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::InputBits[i + offset] = bitStatus[i];
|
|
|
|
sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits");
|
|
break;
|
|
}
|
|
}
|
|
|
|
void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbres, struct ModbusReqRead mbreq)
|
|
{
|
|
word i, offset;
|
|
|
|
switch (mbres.Header.FuncCode) // We assume that we separate between 0x03 and 0x04 even though the address space may be the same
|
|
{
|
|
case 0x03: // Read output registers
|
|
sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputRegisters");
|
|
|
|
offset = mbreq.Address - gDevOutputRegAddr; // Get the offset to the base output register address
|
|
for (i = 0; i < mbreq.Count; i++)
|
|
@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputRegisters[i + offset] = mbres.Data[i];
|
|
|
|
sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputRegisters");
|
|
break;
|
|
|
|
|
|
case 0x04: // Read input registers
|
|
sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters");
|
|
|
|
offset = mbreq.Address - gDevInputRegAddr; // Get the offset to the base input bit address
|
|
for (i = 0; i < mbreq.Count; i++)
|
|
@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::InputRegisters[i + offset] = mbres.Data[i];
|
|
|
|
sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters");
|
|
break;
|
|
}
|
|
}
|
|
|
|
void OnModbusWriteBitSuccess(struct ModbusResConfirmSingle mbc)
|
|
{
|
|
}
|
|
void OnModbusWriteRegisterSuccess(struct ModbusResConfirmSingle mbc)
|
|
{
|
|
}
|
|
void OnModbusWriteBitsSuccess(struct ModbusResConfirmMultiple mbc)
|
|
{
|
|
}
|
|
void OnModbusWriteRegistersSuccess(struct ModbusResConfirmMultiple mbc)
|
|
{
|
|
}
|
|
void OnModbusWriteMasksSuccess(struct ModbusResConfirmMasks mbc)
|
|
{
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
// Key events -------------------------------------------------------------------------
|
|
on timer gtRead
|
|
{
|
|
ModbusReadRegisters(0x0000, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters);
|
|
ModbusReadBits(0x0000, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputBits);
|
|
this.Cancel();
|
|
}
|
|
|
|
on sysvar %BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputBits
|
|
{
|
|
word count, i;
|
|
byte bitStatus[1968];
|
|
|
|
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];
|
|
|
|
ModbusWriteBitsB(0, count, bitStatus);
|
|
}
|
|
on sysvar %BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputRegisters
|
|
{
|
|
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);
|
|
}
|
|
|
|
on key '+'
|
|
{
|
|
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");
|
|
}
|
|
on key '-'
|
|
{
|
|
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");
|
|
} |