This is my communication with ICP-DAS regarding some of the issues I've had with the M-7018 input module. If you have the time and inclination to go through it, please correct me if my information is faulty or misleading.
Thanks. ;)
Hi John,
I'll do my best to relay the information correctly....
Using a "M" series Tri-Plc and the M7017 input module.
The Tri-Plc manual shows using the following TBasic command to read the inputs on the M-7017
READMB2 ch, ID, addr, var, count {* Applicable only to M+PLC with firmware r44 or higher}
Example:
readmb2 13,3,0,DM[10],8 *ch 3 is for ASCII, and ch13 is for RTU.
I had no luck with this command. Communication Error reported between the PLC and the Module. I believe that the problem is....this command implements a Modbus RTU function 03x (read holding register) which is not supported by the M-7017. A Modbus RTU function 04x (read input register) is required.
Tech-Support recommended that I precede the above mentioned command with "setsystem 5,4" to force the PLC into using the function 04x instead of the 03x. This did not work. I don't know why...it just didn't.
Looking further, I found a sub-routine that was written by Tri-Plc's tech support guru.
' This function implements MODBUS RTU function 04 using the INCOMM and
' OUTCOMM commands.
' The address to be read is in A
' The number of channel to be read is in N
' The data are returned in DM[201] to DM[201+N]
' DM[101] to DM[200] are used by this function
DM[101] = &H02 ' node address of slave
DM[102] = &H04 ' function 04
DM[103] = A/256 ' upper 8 bit of address
DM[104] = A & &HFF ' lower 8 bit of address
DM[105] = 0 ' upper 8 bit of count
DM[106] = N ' lower 8 bit of count
X = CRC16 (DM[101],6) & &HFFFF ' compute the CRC16 of DM[101] to DM[106]
DM[107] = X / 256 ' upper 8 bit of CRC16
DM[108] = X & &HFF ' lower 8 bit of CRC16
FOR I = 1 to 8 ' send out the MODBUS RTU command in binary
OUTCOMM 3, DM[100+I]
NEXT
delay (10) ' delay for a while to wait for response
FOR I = 1 to 90 ' assuming small number of read data
DM[110+I] = INCOMM (3)
IF DM[110+I] < 0 GOTO @5: ENDIF
NEXT
@5 FOR I = 1 to N ' convert two bytes into one 16-bit word.
DM[200+I] = DM[112+I*2]*256+DM[113+I*2]
NEXT
I had some limited success with this snipet of code and further modified it as follows...
dm[101]=&h02 'address of module
dm[102]=&h04 'modbus protocol code to read modicon input register
dm[103]=&h00 'Start address high
dm[104]=&h00 'start address low
dm[105]=&h00 'Read 8 channel high
dm[106]=&h07 'Read 8 channel low
X = CRC16 (DM[101],6) & &HFFFF ' compute the CRC16 of DM[101] to DM[106]
DM[107] = X / 256 ' upper 8 bit of CRC16
DM[108] = X & &HFF ' lower 8 bit of CRC16
FOR I = 1 to 8 ' send out the MODBUS RTU command in binary
OUTCOMM 3, DM[100+I]
NEXT
delay (10) ' delay for a while to wait for response
FOR I = 1 to 30 ' assuming small number of read data
DM[110+I] = INCOMM (3)
IF DM[110+I] < 0 GOTO @5: ENDIF
NEXT
@5 FOR I = 1 to 16 ' convert two bytes into one 16-bit word.
DM[200+I] = DM[112+I*2]*256+DM[113+I*2]
NEXT
almost identical.
It's working, but it was a painfull chore to make it work. Having said that....I'm just a rookie.
Thanks,
Sean