Modbus Communication problems

N

Thread Starter

Nancy

I have developed a basic HMI which will communicate with a slave over Modbus (RTU binary). I currently have the program connected to COM1 of my PC, with COM2 connected to Modbus View, a master/slave simulator program.

I am using 9600 baudrate, 8 data bits, 1 stop bit, no parity, Binary/RTU settings, and am sending messages such as

[01][01][00][00][00][02][84][03]

to the Slave (located in address 1).

I am not getting any kind of response, although the ModbusView screen does indicate that my messages Are being received. No action is taken in the registers/coils of the slave, and no message, error or otherwise, is being sent back to the Master.

Any ideas as to why this is happening?

Thanks!
N
 
S

Sydney Deitch

The CRC is incorrect. The CRC bytes should be [BD] [CB] and not [84] [03].

Syd. Deitch
Calta Computer Systems Limited
 
In my experience I was tree types of problems with similar communication with modbus because some programs are in MS-DOS and don’t had some type of diagnostics by example the MBstatus that’s see the elements in the net but don’t can communicate.

The problems that I resolve was:
First the structure of the protocol, RTU, binary or ASCII, in all the elements will be the same.
Second the configuration of the port, bautrate, parity... will be the same too.
And the final was of hardwire, the modbus required additional wires, not only the TX and RX, you can check the configuration in any manual of PLCs modicon by example or in manuals of Bridges that use Modbus.

Jesus
[email protected]
 
check your Modbus View was set up properly.

1. slave mode
2. address is 1
3. bps is the same as the COM1 that you used.
4. set up the data required from COM1.
 
Try using a known working Modbus master or slave to isolate the problem to one end or the other.

You can download trial versions of Automated Solutions (www.automatedsolutions.com) Modbus Master and Slave ActiveX Controls with ready-to-run HMI applications.

The trial version will run for 30 days.
 
BAD CRC - no response should be normal

here is the good CRC:

> [01][01][00][00][00][02][8B][D0]

If you use serialtest you can setup the CRC16 with 0xFFFF seed and GP=0xA001 and then it willshow valid/invalis CRC in the analysis...but I just poked it into my buffer routine which automatically generates a CRC and I got 0xD08B.

/* CRC calculator */
#define GSEED 0xFFFF
#define GPOLY 0xA001
void CRC16(BUFFER* buf)
{
int i;

if (buf->n<=0) return;

if (buf->n==1)
{
buf->CRC16 = GSEED;
}

buf->CRC16 ^= (buf->data[buf->tail] & 0xFF);

for (i=0;i<8;i++)
{
if (buf->CRC16 & 0x01)
{
buf->CRC16 >>= 1;
buf->CRC16 ^= GPOLY;
}
else
{
buf->CRC16 >>= 1;
}
}
}


Hope this helps.

Max ([email protected])
 
S

Scott Henson

Your message:

[01][01][00][00][00][02][84][03]

has the wrong checksum. The last two bytes should be [BD][CB]. This is probably why you aren't getting a response.

I would also double check that you are actually transmitting something from your serial port by connecting another PC running a terminal emualtor (like hyperterminal) to your cross-over cable and send it some messages. You should see some garbage show up on the screen. You may need to change your slave address, starting coil, or register count to something that will show up as an ASCII character so you can make sure that the baud rate and parity are correct.

Send something like:

[31] [03] [00] [32] [00] [37] [A0] [23]

This would be a Holding Register read of slave 49 (hex 31) starting at 4x register 51 (zero based hex 0032) with a count of 55 (hex 0037). The 31, 32, 37, and 23 should show up as 1, 2, 7, and # on the Hyperterminal screen.

If you don't get anything on your terminal screen then you should check your cross-over cable. The basic cable for 9-pin RS-232 ports should be something like 2-3, 3-2, 5-5, and jumper 7 to 8 on each end.

2--------3
3--------2
5--------5
7-+ 7-+
8-+ 8-+

Regards,
Scott Henson
Niobrara R&D Corp.
[email protected]
 
Your master statement requests
- slave 01
- to read & return the output status instruction 01)
- of 3 coils, 0000 through 0002

[01][01][00][00][00][02][84][03]

I'm not clear what the 8th byte is doing (I can't recall the precision of the error check)

What have you set the slave up as? Does it have output coils it can read? Or is it an ASCII or float register?

Even if you were polling for the wrong data format, you should get an error message.

Something is wrong in the slave mode.
 
<p>Thank you everyone! your tips were Very helpful.

<p>The problem is indeed with my crc bytes, as I forced the program to send out the correct bytes, and everything worked as expected. Now my problem is figuring out what is wrong with my crc code!!

<p>I am using the lookup table that starts with
<pre>
public class CCITTcrc
{
public static final int CRCINIT = 0xffff;
public static final int CRC_OK = 0;
public static final int CRC_FAULT = -1;
static final String HEXCHARS = "0123456789ABCDEF";

static final int [] CRCTAB_CCITT =
{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, //etc. etc. ...

public int calc(byte[] buffer, int n) {
int i,x;

crcaccu=(short)CRCINIT;
for (i=0; i<n; i++) {
x=(byte)((crcaccu>>8)^buffer);
if (x<0)
x+=0x100;
crcaccu=(short)((crcaccu<<8)^CRCTAB_CCITT[x]);
}
buffer[n]=(byte)(crcaccu>>8);
buffer[n+1]=(byte)crcaccu;
return n+2;
}
}
</pre>
<p>Thanks again for your help.

<p>N
 
Are you using the lookup table for speed reasons? I find that the lookup table is a poor way to calculate a CRC --> it is a memory hog and not a whole lot faster in execution, if at all.
 
L
Modbus uses 16-bit unsigned values - ideally "unsigned short" everywhere.

The code you show has signed integers for the lookup table. This could cause your code to work differently on systems with 16-bit verse 32-bit "int"s - especially if you are using compilers for embedded systems as they are often nearly ANSI-C but not quite pure.

Try only using "unsigned short" for everything.

- LynnL, www.digi.com
 
Top