Detect connected modules and count inputs and outputs
This commit is contained in:
parent
68e41595cb
commit
2ed521dc48
4 changed files with 631 additions and 485 deletions
|
@ -3,6 +3,7 @@
|
||||||
includes
|
includes
|
||||||
{
|
{
|
||||||
#include "include\ModbusUdpClientCommon.cin"
|
#include "include\ModbusUdpClientCommon.cin"
|
||||||
|
#include "include\ModbusFunctions.cin"
|
||||||
}
|
}
|
||||||
|
|
||||||
variables
|
variables
|
||||||
|
@ -12,7 +13,7 @@ variables
|
||||||
msTimer muster, clock;
|
msTimer muster, clock;
|
||||||
byte gX[2] = {1, 0};
|
byte gX[2] = {1, 0};
|
||||||
|
|
||||||
enum MbClientState {INIT, ConfWago1, ConfWago2, ConfWago3, ConfWago4, DATA};
|
enum MbClientState {INIT, ConfWago1, ConfWago2, ConfWago3, ConfWago4, ConfWago5, ConfWago6, DATA};
|
||||||
enum MbClientState gState = INIT;
|
enum MbClientState gState = INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +27,9 @@ on preStart
|
||||||
|
|
||||||
on start
|
on start
|
||||||
{
|
{
|
||||||
ModbusInit("192.168.1.3", 502);
|
char ip[16];
|
||||||
|
sysGetVariableString("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Config", "IP", ip, elCount(ip));
|
||||||
|
ModbusInit(ip, @sysvar::Config::Modbus::Port);
|
||||||
|
|
||||||
// Read serial code, additional stuff is done in OnModbusReceiveRegisters
|
// Read serial code, additional stuff is done in OnModbusReceiveRegisters
|
||||||
gState = ConfWago1;
|
gState = ConfWago1;
|
||||||
|
@ -72,24 +75,79 @@ void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbr, word num
|
||||||
{
|
{
|
||||||
char str[20*5];
|
char str[20*5];
|
||||||
long fehler;
|
long fehler;
|
||||||
dbin_to_strhex(mbr.Data, str);
|
byte i;
|
||||||
writeLineEx(0, 1, "<%NODE_NAME%> OnModbusReceiveRegisters: Received %d bytes: %s", mbr.ByteCount, str);
|
|
||||||
|
|
||||||
switch (gState)
|
switch (gState)
|
||||||
{
|
{
|
||||||
case ConfWago1:
|
case ConfWago1:
|
||||||
//@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::SerialCode = mbr.Data[0];
|
@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::SerialCode = mbr.Data[0];
|
||||||
gState = ConfWago2;
|
gState = ConfWago2;
|
||||||
ModbusReadRegisters(0x2012, 1);
|
ModbusReadRegisters(0x2012, 1);
|
||||||
break;
|
break;
|
||||||
case ConfWago2:
|
case ConfWago2:
|
||||||
//@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::DeviceCode = mbr.Data[0];
|
@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::DeviceCode = mbr.Data[0];
|
||||||
gState = ConfWago3;
|
gState = ConfWago3;
|
||||||
ModbusReadRegisters(0x2030, 1);
|
ModbusReadRegisters(0x2030, 65);
|
||||||
break;
|
break;
|
||||||
case ConfWago3:
|
case ConfWago3:
|
||||||
|
for (i = 0; i < 65; i++)
|
||||||
|
{
|
||||||
|
if (mbr.Data[i] == 0x0000)
|
||||||
|
{
|
||||||
|
gState = DATA;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ParseDeviceCode(mbr.Data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
gState = ConfWago4;
|
||||||
|
ModbusReadRegisters(0x2031, 64);
|
||||||
|
break;
|
||||||
|
case ConfWago4:
|
||||||
|
for (i = 0; i < 64; i++)
|
||||||
|
{
|
||||||
|
if (mbr.Data[i] == 0x0000)
|
||||||
|
{
|
||||||
|
gState = DATA;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ParseDeviceCode(mbr.Data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
gState = ConfWago5;
|
||||||
|
ModbusReadRegisters(0x2032, 64);
|
||||||
|
break;
|
||||||
|
case ConfWago5:
|
||||||
|
for (i = 0; i < 64; i++)
|
||||||
|
{
|
||||||
|
if (mbr.Data[i] == 0x0000)
|
||||||
|
{
|
||||||
|
gState = DATA;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ParseDeviceCode(mbr.Data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
gState = ConfWago5;
|
||||||
|
ModbusReadRegisters(0x2033, 64);
|
||||||
|
break;
|
||||||
|
case ConfWago6:
|
||||||
|
for (i = 0; i < 64; i++)
|
||||||
|
{
|
||||||
|
if (mbr.Data[i] == 0x0000)
|
||||||
|
{
|
||||||
|
gState = DATA;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ParseDeviceCode(mbr.Data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
gState = DATA;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
// Do everything else here
|
||||||
|
dbin_to_strhex(mbr.Data, str);
|
||||||
|
writeLineEx(0, 1, "<%NODE_NAME%> OnModbusReceiveRegisters: Received %d bytes: %s", mbr.ByteCount, str);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
65
Modbus/include/ModbusFunctions.cin
Normal file
65
Modbus/include/ModbusFunctions.cin
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*@!Encoding:1252*/
|
||||||
|
|
||||||
|
void ParseDeviceCode(word dev)
|
||||||
|
{
|
||||||
|
byte input;
|
||||||
|
byte numChannels;
|
||||||
|
char modules[1024];
|
||||||
|
char module[10];
|
||||||
|
char templ[10];
|
||||||
|
|
||||||
|
sysGetVariableString("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info", "Modules", modules, elCount(modules));
|
||||||
|
|
||||||
|
if (dev & 0x8000) // Digital Module
|
||||||
|
{
|
||||||
|
numChannels = (dev >> 8) & 0x007F;
|
||||||
|
|
||||||
|
if (dev & 0x0001) // Input Module
|
||||||
|
{
|
||||||
|
input = 1;
|
||||||
|
strncpy(templ, "DI%d,", elCount(templ));
|
||||||
|
@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputBits += numChannels;
|
||||||
|
}
|
||||||
|
else if (dev & 0x0002) // Output Module
|
||||||
|
{
|
||||||
|
input = 0;
|
||||||
|
strncpy(templ, "DO%d,", elCount(templ));
|
||||||
|
@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits += numChannels;
|
||||||
|
}
|
||||||
|
else // blööd
|
||||||
|
{
|
||||||
|
writeLineEx(0, 3, "<%NODE_NAME%> Device code 0x%X cannot be decoded", dev);
|
||||||
|
runError(1003, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(module, elCount(module), templ, numChannels);
|
||||||
|
strncat(modules, module, elCount(modules));
|
||||||
|
sysSetVariableString("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info", "Modules", modules);
|
||||||
|
writeLineEx(0, 1, "<%NODE_NAME%> 0x%X - %s", dev, module);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (dev)
|
||||||
|
{
|
||||||
|
case 881: // devices that have no inputs/outputs
|
||||||
|
return;
|
||||||
|
case 477: // devices that have 2 outputs
|
||||||
|
input = 0;
|
||||||
|
numChannels = 2;
|
||||||
|
break;
|
||||||
|
default: // unknown device. Ouch!
|
||||||
|
writeLineEx(0, 2, "<%NODE_NAME%> Connected device: 750-%X", dev);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (input)
|
||||||
|
{
|
||||||
|
strncpy(templ, "AI%d,", elCount(templ));
|
||||||
|
@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters += numChannels;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strncpy(templ, "AO%d,", elCount(templ));
|
||||||
|
@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputRegisters += numChannels;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
25
Modbus/modbus.vsysvar
Normal file
25
Modbus/modbus.vsysvar
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<systemvariables version="4">
|
||||||
|
<namespace name="" comment="">
|
||||||
|
<namespace name="Ethernet1" comment="">
|
||||||
|
<namespace name="Wago_3" comment="">
|
||||||
|
<namespace name="Config" comment="">
|
||||||
|
<variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="IP" comment="comment" bitcount="8" isSigned="true" encoding="65001" type="string" startValue="192.168.1.3" />
|
||||||
|
</namespace>
|
||||||
|
<namespace name="Info" comment="">
|
||||||
|
<variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="Modules" comment="" bitcount="8" isSigned="true" encoding="65001" type="string" />
|
||||||
|
<variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="SerialCode" comment="" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="0" minValue="1" minValuePhys="1" maxValue="10000" maxValuePhys="10000" />
|
||||||
|
<variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="DeviceCode" comment="" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="0" minValue="1" minValuePhys="1" maxValue="10000" maxValuePhys="10000" />
|
||||||
|
<variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="InputBits" comment="" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="0" minValue="0" minValuePhys="0" maxValue="2000" maxValuePhys="2000" />
|
||||||
|
<variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="InputRegisters" comment="" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="0" minValue="0" minValuePhys="0" maxValue="123" maxValuePhys="123" />
|
||||||
|
<variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="OutputBits" comment="" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="0" minValue="0" minValuePhys="0" maxValue="2000" maxValuePhys="2000" />
|
||||||
|
<variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="OutputRegisters" comment="" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="0" minValue="0" minValuePhys="0" maxValue="123" maxValuePhys="123" />
|
||||||
|
</namespace>
|
||||||
|
<namespace name="Data" comment="">
|
||||||
|
<variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="Bits" comment="" bitcount="8" isSigned="true" encoding="65001" type="data" arrayLength="0" />
|
||||||
|
<variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="Registers" comment="" bitcount="8" isSigned="true" encoding="65001" type="data" arrayLength="0" />
|
||||||
|
</namespace>
|
||||||
|
</namespace>
|
||||||
|
</namespace>
|
||||||
|
</namespace>
|
||||||
|
</systemvariables>
|
Loading…
Reference in a new issue