Rs485 ModBus communication

Hi,

I have an arduino uno with a logging shield. I try to read a modbus device through RS485 directly.

I tried my code via usb through a modbus simulator. It worked perfectly. As soon as I connected to the device it does not work. Does not return any proper message/number. I know my problem is pretty generic.

But I just would like to ask if you guys think that I need anything between the device and the arduino or there could be some other problems.

If I read the device with a computer I have a converter( rs485 to rs232) between them. I try to avoid that with the arduino.

You need a RS485 transceiver between the arduino and the modbus cable.
here are a number of them

http://www.analog.com/static/imported-files/data_sheets/ADM2482E_2487E.pdf
http://www.analog.com/static/imported-files/data_sheets/ADM485.pdf

Thank you, I thought it would not be as easy as just have the 2 wires:P...

What do I need to know to get the right type transceiver? Sorry I am just learning electronics, I much more a software guy:P

Sounds like you need an RS-485 shield. That will have the correct transceiver.


Rob

So I got some transceivers. I wired them up, it is communicating but it gives back the same message as I get without the transceiver. I used this method for wiring and this is my code:

#include <ModbusMaster.h>
ModbusMaster node(0,3);

void setup()
{
  // initialize Modbus communication baud rate
  node.begin(9600);
}

void loop()
{
  //wait a sec
  delay(1000);
  
  static uint32_t i;
  uint8_t j, result;
  uint16_t data[2];

  i++;

  // set word 0 of TX buffer to least-significant word of counter (bits 15..0)
  node.setTransmitBuffer(1, lowWord(i));

  // set word 1 of TX buffer to most-significant word of counter (bits 31..16)
  node.setTransmitBuffer(0, highWord(i));

  // slave: read (1) 16-bit registers starting at register 1002 to RX buffer
  result = node.readHoldingRegisters(1002, 2);

  delay(300);
  
  // do something with data if read is successful
  if (result == node.ku8MBSuccess)
  {
    for (j = 0; j < 2; j++)
    {
      data[j] = node.getResponseBuffer(j);
    }
  }
  
 //do what ever you want with the message(byte array)
}

I tested the code via the usb cable with a modbus simulator and it is working. In the code I do not do any handshake, I do not use pin 2 for anything. Could that be the problem?

Pin 2 is your send (or receive). Generally, serial needs a line for sending AND a line for receiving.

I thought pin 2 is just responsible for the ready to send/receive status

Rob, I'm using a data logging shield, so I thought it would be nicer to just solder the transceiver chip to that board.

Do I need 2 of those chips(and on arduino and one on the rs485 device end)? Some of the drawings suggest that I should have more, while some says one is enough, I am not entirely sure.

For debugging I connected my arduino set-up for a laptop. I receive the right message, I send back the right one as well, but It shows wrong on the arduni, so I am almost sure that I need 2 of those transceivers.

It seems that the message does not translates back, or should it be something with that pin 2 that I mentioned before?

So it does not work with 2 transceivers and after looking some diagrams I am sure I should just use one.

The question is: why I do not get back the right messages then? should I use a different transceiver ? The semantics of it looks the same like the max485 one. Or is it different?

Do I need 2 of those chips(and on arduino and one on the rs485 device end)?

Yes.

So it does not work with 2 transceivers and after looking some diagrams I am sure I should just use one.

I can't figure out what you have now, you have a remote device talking Modbus over RS-485, is that correct?

Re pin 2 on the transceiver, you can leave that tied low if you like, all that will happen is that you sill see the data you transmit, but of course the software has to know this is the case and not think the bytes are from the remote device.

Pin 3 HAS to be handled or the remote device won't be able to talk to you. DE (pin 3) should be high when you are transmitting and low at all other times. Normally you tie pins 2 and 3 together although I don't know what the Modbus library expects.


Rob

I connected RE and DE those cables goes in pin 2 on the arduino board.

On the other end of the transceiver I have the power, ground A and B.
Instead of the ModBus device I just used a laptop for easier debug. At the laptop end I have a USB to RS485 which has 2 cables coming out: A and B.

I connected the transceiver A and B with the USB to RS485 A and B.
I run a modbus simulator as a slave.
I get the message from the arduino. I send back a message, but at the ardunio end the message is something different.

I use this semantics to wire the arduino .

Are yu sure that I need 2 transceivers? Even on the arduino rs485 shield there is just one of them.

Here is some good info about RS485 Bus

Even on the arduino rs485 shield there is just one of them.

Well the Arduino shield is only one end so it only has one transceiver.

Trust me, every RS485 link ever created had a transceiver at each end (actually there was a thread about not having one on one end recently, but the practice was rightly howled down).

Your schematic looks correct and the link works one way, I suspect it's the code that is the problem. Have you printed out what you get and compared that with what you expected?


Rob

Hm, so I do have 2 transceivers because there's one in the usb converter. My code works when I am using the serial communication via the arduino's usb. But I guess it is a bit different then using pin 0,1 and 2.

I think I will just modify the modbus class that I use a bit so I can see the whole message which is returned, now I can just retrieve the modbus register data from it.

Pins 0 and 1 are connected to the Arduino's USB chip, they are "isolated" with resistors but it's been know to cause issues I think.

Better to use a board with a free serial connection.


Rob

I definitely wont use the usb port, I just used it for debugging. I guess I will update you tomorrow about the code change as I needed to lend my USB <- rs485 converter till tomorrow:P

Yeah, no I am almost 100% sure that it is with my code. It seems that it does not receive the data right. I just need to find out how to properly read ports its C++ and I should be alright:)

I was thinking a bit more about the problem over the weekend:

  • Instead of getting the message which is sent by the ModBus slave the program returns the message that have been sent to the slave
  • It is working on USB with the same code
  • So either there's something weird going on with the Arduino pin 2(send/receive) or there's something with the code(the site where I got the it from contained the hardware built as well, and it say's it its been tested on the RS485 pins)

Anyway I keep trying hopefully I will end up with some useful code and hardware build