Modbus/include/ModbusClientCommon.cin
fixed decoding bits in OnModbusReceiveBits() Modbus/ModbusClientUDP.can Enhanced client Timer that automatically refreshes the status Save received data in sysvars
This commit is contained in:
parent
dde6cef26f
commit
df4813e33d
2 changed files with 98 additions and 164 deletions
|
@ -8,14 +8,7 @@ includes
|
||||||
|
|
||||||
variables
|
variables
|
||||||
{
|
{
|
||||||
char gNodeName[10] = "ClientUDP";
|
|
||||||
|
|
||||||
msTimer muster, clock;
|
|
||||||
msTimer gtRead;
|
msTimer gtRead;
|
||||||
byte gX[2] = {1, 0};
|
|
||||||
|
|
||||||
enum MbClientState {INIT, ConfWago1, ConfWago2, ConfWago3, ConfWago4, ConfWago5, ConfWago6, DATA};
|
|
||||||
enum MbClientState gState = INIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get information of local network interface such like ip address
|
// Get information of local network interface such like ip address
|
||||||
|
@ -32,7 +25,6 @@ on start
|
||||||
|
|
||||||
|
|
||||||
// Read serial code, additional stuff is done in OnModbusReceiveRegisters
|
// Read serial code, additional stuff is done in OnModbusReceiveRegisters
|
||||||
gState = ConfWago1;
|
|
||||||
ModbusReadRegisters(0x2011, 1);
|
ModbusReadRegisters(0x2011, 1);
|
||||||
ModbusReadRegisters(0x2012, 1);
|
ModbusReadRegisters(0x2012, 1);
|
||||||
ModbusReadRegisters(0x2030, 65);
|
ModbusReadRegisters(0x2030, 65);
|
||||||
|
@ -55,12 +47,6 @@ void OnModbusWriteBitFailed(enum ModbusRequestError error, enum ModbusException
|
||||||
void OnModbusWriteRegisterFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
|
void OnModbusWriteRegisterFailed(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 OnModbusWriteMasksFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
|
void OnModbusWriteMasksFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -68,14 +54,74 @@ void OnModbusReadWriteRegistersFailed(enum ModbusRequestError error, enum Modbus
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnModbusWriteBitsFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
|
||||||
|
{
|
||||||
|
byte bitStatus[100], i;
|
||||||
|
|
||||||
|
switch (error)
|
||||||
|
{
|
||||||
|
case Exception:
|
||||||
|
writeLineEx(0, 3, "Error: Received Exception 0x%X while reading Bits", ex);
|
||||||
|
break;
|
||||||
|
case Timeout:
|
||||||
|
writeLineEx(0, 2, "Warning: Reading Bits timed out! Retrying...");
|
||||||
|
break;
|
||||||
|
case FinalTimeout:
|
||||||
|
for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputBits; i++)
|
||||||
|
bitStatus[i] = 255;
|
||||||
|
|
||||||
|
sysSetVariableData("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits", bitStatus, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputBits);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnModbusWriteRegistersFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
|
||||||
|
{
|
||||||
|
byte bitStatus[100], i;
|
||||||
|
|
||||||
|
|
||||||
|
switch (error)
|
||||||
|
{
|
||||||
|
case Exception:
|
||||||
|
writeLineEx(0, 3, "Error: Received Exception 0x%X while reading Registers", ex);
|
||||||
|
break;
|
||||||
|
case Timeout:
|
||||||
|
writeLineEx(0, 2, "Warning: Reading Registers timed out! Retrying...");
|
||||||
|
break;
|
||||||
|
case FinalTimeout:
|
||||||
|
for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters; i++)
|
||||||
|
bitStatus[i] = 255;
|
||||||
|
|
||||||
|
sysSetVariableData("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters", bitStatus, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void OnModbusReadBitsSuccess(struct ModbusResReceiveBits mbr, byte bitStatus[], word numBits)
|
void OnModbusReadBitsSuccess(struct ModbusResReceiveBits mbr, byte bitStatus[], word numBits)
|
||||||
{
|
{
|
||||||
char str[20*2];
|
byte bitStatusOld[1968];
|
||||||
|
word i;
|
||||||
|
long numBitsOld;
|
||||||
|
|
||||||
hbin_to_strhex(mbr.Data, str);
|
sysGetVariableData("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits", bitStatusOld, numBitsOld);
|
||||||
writeLineEx(0, 1, "<%NODE_NAME%> OnModbusReceiveBits: Received %d bits (in %d bytes): %s", numBits, mbr.ByteCount, str);
|
|
||||||
|
if (numBitsOld != numBits)
|
||||||
|
{
|
||||||
|
sysSetVariableData("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits", bitStatus, numBits);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < numBits; i++)
|
||||||
|
{
|
||||||
|
if (bitStatusOld[i] != bitStatus[i])
|
||||||
|
{
|
||||||
|
sysSetVariableData("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits", bitStatus, numBits);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbr, word numRegs)
|
void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbr, word numRegs)
|
||||||
{
|
{
|
||||||
char str[20*5];
|
char str[20*5];
|
||||||
|
@ -103,35 +149,32 @@ void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbr, word num
|
||||||
for (i = 0; i < 65; i++)
|
for (i = 0; i < 65; i++)
|
||||||
{
|
{
|
||||||
if (mbr.Data[i] == 0x0000)
|
if (mbr.Data[i] == 0x0000)
|
||||||
{
|
|
||||||
gState = DATA;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
ParseDeviceCode(mbr.Data[i]);
|
ParseDeviceCode(mbr.Data[i]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 0x0000:
|
||||||
|
// ///////////////////////////////////////////////////////////////sysSetVariableData("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters", mbr.Data, numRegs);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// Do everything else here
|
// Not recognized
|
||||||
dbin_to_strhex(mbr.Data, str);
|
dbin_to_strhex(mbr.Data, str);
|
||||||
writeLineEx(0, 1, "<%NODE_NAME%> OnModbusReceiveRegisters: Received %d bytes at 0x%04X: %s", mbr.ByteCount, mbrq.Address, str);
|
writeLineEx(0, 1, "<%NODE_NAME%> OnModbusReceiveRegisters: Received %d bytes at 0x%04X: %s", mbr.ByteCount, mbrq.Address, str);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnModbusWriteBitSuccess(struct ModbusResConfirmSingle mbc)
|
void OnModbusWriteBitSuccess(struct ModbusResConfirmSingle mbc)
|
||||||
{
|
{
|
||||||
writeLineEx(0, 1, "<%NODE_NAME%> OnModbusConfirmBit: Set bit 0x%X to %d", mbc.Address, (mbc.Value > 0 ? 1 : 0));
|
|
||||||
}
|
}
|
||||||
void OnModbusWriteRegisterSuccess(struct ModbusResConfirmSingle mbc)
|
void OnModbusWriteRegisterSuccess(struct ModbusResConfirmSingle mbc)
|
||||||
{
|
{
|
||||||
writeLineEx(0, 1, "<%NODE_NAME%> OnModbusConfirmRegister: Set register 0x%X to %d", mbc.Address, mbc.Value);
|
|
||||||
}
|
}
|
||||||
void OnModbusWriteBitsSuccess(struct ModbusResConfirmMultiple mbc)
|
void OnModbusWriteBitsSuccess(struct ModbusResConfirmMultiple mbc)
|
||||||
{
|
{
|
||||||
writeLineEx(0, 1, "<%NODE_NAME%> OnModbusConfirmBits: Set %d bits beginning with 0x%X", mbc.Count, mbc.Address);
|
|
||||||
}
|
}
|
||||||
void OnModbusWriteRegistersSuccess(struct ModbusResConfirmMultiple mbc)
|
void OnModbusWriteRegistersSuccess(struct ModbusResConfirmMultiple mbc)
|
||||||
{
|
{
|
||||||
writeLineEx(0, 1, "<%NODE_NAME%> OnModbusConfirmRegisters: Set %d registers beginning with 0x%X", mbc.Count, mbc.Address);
|
|
||||||
}
|
}
|
||||||
void OnModbusWriteMasksSuccess(struct ModbusResConfirmMasks mbc)
|
void OnModbusWriteMasksSuccess(struct ModbusResConfirmMasks mbc)
|
||||||
{
|
{
|
||||||
|
@ -152,136 +195,28 @@ on timer gtRead
|
||||||
ModbusReadBits(@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters * 2, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputBits);
|
ModbusReadBits(@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters * 2, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
on key 'r' // read the first bits
|
on sysvar %BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputBits
|
||||||
{
|
{
|
||||||
ModbusReadBits(0, 51);
|
byte bitStatus[1968];
|
||||||
|
long numBytes;
|
||||||
|
sysGetVariableData("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits", bitStatus, numBytes);
|
||||||
|
ModbusWriteBitsB(@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters * 2, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits, bitStatus);
|
||||||
}
|
}
|
||||||
on key 'R' // read constant registers
|
on sysvar %BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputRegisters
|
||||||
{
|
{
|
||||||
ModbusReadRegisters(0x2000, 8);
|
/******************************************************word regValues[1968];
|
||||||
|
long numRegs;
|
||||||
|
sysGetVariableData("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits", regValues, numRegs);
|
||||||
|
ModbusWriteRegisters(0, numRegs, regValues);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
on key 'a' // set left bar
|
on key '+'
|
||||||
{
|
{
|
||||||
byte x[16] = {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0};
|
byte bla[16] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
|
||||||
ModbusWriteBitsB(0, 16, x);
|
sysSetVariableData("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits", bla, 16);
|
||||||
}
|
}
|
||||||
on key 'A' // read the output bits
|
on key '-'
|
||||||
{
|
{
|
||||||
ModbusReadBits(0x200, 16);
|
byte bla[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||||
}
|
sysSetVariableData("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits", bla, 16);
|
||||||
|
|
||||||
on key 's' // set right bar
|
|
||||||
{
|
|
||||||
byte x[16] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1};
|
|
||||||
ModbusWriteBitsB(0, 16, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
on key 'e' // write register
|
|
||||||
{
|
|
||||||
ModbusWriteRegister(0, 0x5555);
|
|
||||||
}
|
|
||||||
on key 'E' // read register
|
|
||||||
{
|
|
||||||
ModbusWriteRegister(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
on key 'Y' // write bit on
|
|
||||||
{
|
|
||||||
ModbusWriteBit(0, 0);
|
|
||||||
}
|
|
||||||
on key 'y' // write bit off
|
|
||||||
{
|
|
||||||
ModbusWriteBit(0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
on key 'X'
|
|
||||||
{
|
|
||||||
ModbusWriteBit(1, 0);
|
|
||||||
}
|
|
||||||
on key 'x'
|
|
||||||
{
|
|
||||||
ModbusWriteBit(1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
on key 'C'
|
|
||||||
{
|
|
||||||
ModbusWriteBit(2, 0);
|
|
||||||
}
|
|
||||||
on key 'c'
|
|
||||||
{
|
|
||||||
ModbusWriteBit(2, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
on key 'V'
|
|
||||||
{
|
|
||||||
ModbusWriteBit(3, 0);
|
|
||||||
}
|
|
||||||
on key 'v'
|
|
||||||
{
|
|
||||||
ModbusWriteBit(3, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
on key '+' // set all bits on
|
|
||||||
{
|
|
||||||
byte x[2] = {0xFF, 0xFF};
|
|
||||||
ModbusWriteBits(0, 16, x);
|
|
||||||
}
|
|
||||||
on key '-' // set all bits off
|
|
||||||
{
|
|
||||||
byte x[2] = {0x00, 0x00};
|
|
||||||
ModbusWriteBits(0, 16, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
on key 'z' // start timer muster
|
|
||||||
{
|
|
||||||
setTimerCyclic(muster, 100);
|
|
||||||
}
|
|
||||||
on key 'Z' // stop timer muster
|
|
||||||
{
|
|
||||||
cancelTimer(muster);
|
|
||||||
}
|
|
||||||
|
|
||||||
on timer muster
|
|
||||||
{
|
|
||||||
if (gX[0] != 0)
|
|
||||||
{
|
|
||||||
if (gX[0] == 0x80)
|
|
||||||
{
|
|
||||||
gX[0] = 0x00;
|
|
||||||
gX[1] = 0x01;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
gX[0] <<= 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (gX[1] == 0x80)
|
|
||||||
{
|
|
||||||
gX[0] = 0x01;
|
|
||||||
gX[1] = 0x00;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
gX[1] <<= 1;
|
|
||||||
}
|
|
||||||
ModbusWriteBits(0, 16, gX);
|
|
||||||
//ModbusReadBits(0, 512);
|
|
||||||
}
|
|
||||||
|
|
||||||
on key 't' // show clock on output
|
|
||||||
{
|
|
||||||
setTimerCyclic(clock, 1000);
|
|
||||||
}
|
|
||||||
on key 'T' // show clock on output
|
|
||||||
{
|
|
||||||
clock.Cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
on timer clock
|
|
||||||
{
|
|
||||||
byte s, x[2];
|
|
||||||
s = (timeNow() / 100000) % 30;
|
|
||||||
x[0] = (s & 0x01) | (s & 0x02) | ((s & 0x04) << 1) | ((s & 0x08) << 4);
|
|
||||||
x[1] = (s & 0x10) << 3;
|
|
||||||
ModbusWriteBits(0, 16, x);
|
|
||||||
}
|
}
|
|
@ -78,7 +78,7 @@ void OnModbusReceiveBits(byte buffer[])
|
||||||
{
|
{
|
||||||
for (j = 0; j < 8; j++)
|
for (j = 0; j < 8; j++)
|
||||||
{
|
{
|
||||||
bitStatus[8*i+j] = mbr.Data[i] & (0x01 << j);
|
bitStatus[8*i+j] = (mbr.Data[i] >> j) & 0x01;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,13 +253,12 @@ void ModbusWriteBitsB(word address, word count, byte values[])
|
||||||
dword ellCount;
|
dword ellCount;
|
||||||
dword i;
|
dword i;
|
||||||
dword j;
|
dword j;
|
||||||
char str1[20*2], str2[20*3];
|
///char str1[20*2], str2[20*3];
|
||||||
|
|
||||||
ellCount = elCount(values);
|
length = (word)_ceil(count / 8.0);
|
||||||
length = (word)_ceil(ellCount / 8.0);
|
///writeLineEx(0, 3, "count: %d; length: %d", count, length);
|
||||||
//writeLineEx(0, 3, "ellCount: %d; length: %d", ellCount, length);
|
|
||||||
|
|
||||||
if (ellCount % 8 != 0)
|
if (count % 8 != 0)
|
||||||
length--;
|
length--;
|
||||||
|
|
||||||
for (i = 0; i < length; i++)
|
for (i = 0; i < length; i++)
|
||||||
|
@ -268,20 +267,20 @@ void ModbusWriteBitsB(word address, word count, byte values[])
|
||||||
for (j = 0; j < 8; j++)
|
for (j = 0; j < 8; j++)
|
||||||
{
|
{
|
||||||
buffer[i] |= (values[i*8 + j] & 0x01) << j;
|
buffer[i] |= (values[i*8 + j] & 0x01) << j;
|
||||||
//writeLineEx(0, 3, "j: %d; indx: %d; value: %d; mask: %X", j, i*8 + j, values[i*8 + j], (0x01 << j));
|
///writeLineEx(0, 3, "j: %d; indx: %d; value: %d; mask: %X", j, i*8 + j, values[i*8 + j], (0x01 << j));
|
||||||
}
|
}
|
||||||
//writeLineEx(0, 3, "%d: %X", i, buffer[i]);
|
///writeLineEx(0, 3, "%d: %X", i, buffer[i]);
|
||||||
}
|
}
|
||||||
for (j = 0; j < ellCount % 8; j++) // wont be executed if there is no remainder
|
for (j = 0; j < count % 8; j++) // wont be executed if there is no remainder
|
||||||
{
|
{
|
||||||
//writeLineEx(0, 3, "j: %d; indx: %d; value: %d; mask: %X", j, (length-1)*8 + j, values[(length-1)*8 + j], (0x01 << j));
|
///writeLineEx(0, 3, "j: %d; indx: %d; value: %d; mask: %X", j, (length-1)*8 + j, values[(length-1)*8 + j], (0x01 << j));
|
||||||
buffer[length] |= (values[(length)*8 + j] & 0x01) << j;
|
buffer[length] |= (values[(length)*8 + j] & 0x01) << j;
|
||||||
}
|
}
|
||||||
//writeLineEx(0, 3, "%d: %X", length-1, buffer[length-1]);
|
///writeLineEx(0, 3, "%d: %X", length-1, buffer[length-1]);
|
||||||
|
|
||||||
hbin_to_strhex(values, str1);
|
///hbin_to_strhex(values, str1);
|
||||||
bin_to_strhex(buffer, str2);
|
///bin_to_strhex(buffer, str2);
|
||||||
writeLineEx(0, 1, "<%NODE_NAME%> ModbusWriteBitsB: Encoded %s to %s", str1, str2);
|
///writeLineEx(0, 1, "<%NODE_NAME%> ModbusWriteBitsB: Encoded %s to %s", str1, str2);
|
||||||
ModbusWriteBits(address, count, buffer);
|
ModbusWriteBits(address, count, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,7 +307,7 @@ void OnModbusConfirmBitsException(struct ModbusApHeader mbap, enum ModbusExcepti
|
||||||
|
|
||||||
// REGION: ModbusWriteRegisters -------------------------------------------------------
|
// REGION: ModbusWriteRegisters -------------------------------------------------------
|
||||||
/// <ModbusWriteRegisters>
|
/// <ModbusWriteRegisters>
|
||||||
void ModbusWriteRegisters(word address, word count, int values[])
|
void ModbusWriteRegisters(word address, word count, word values[])
|
||||||
{
|
{
|
||||||
const word maxLength = __size_of(struct ModbusReqWriteRegisters);
|
const word maxLength = __size_of(struct ModbusReqWriteRegisters);
|
||||||
const byte funcCode = 0x10;
|
const byte funcCode = 0x10;
|
||||||
|
|
Loading…
Reference in a new issue