To monitor data from RS485 on serial monitor of Arduino Uno.

Hello,
I have some data coming from RJ45 connector (RS485). I want to visualise the same data on serial monitor of Arduino IDE. I am using Arduino Uno for this particular case. How can I do the same? Do I need some protocol or Voltage level conversion before connecting to Arduino? And what should I do to again post the data on GSM?(a module with SIM900A)

Hi,
Learn more about RS-485 and Signal levels HERE.

Thanks for the suggestion. It is a great help.
But now, i am getting ⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮ this as output in serial monitor. I have set baud rate as 9600. And tried all standard baud rates too. Is that an issue? what else should I try?

It might help to know what hardware you are using, how it is wired and what code runs on the Arduino.

What's the device on the other end of the RS-485?

Please find the attached block diagram. I hope it is sufficient to explain all the connections I made.
The code I am using is as follows. The data coming is in MODBUS RTU protocol. It's specified in the drive's manual.

#include<SoftwareSerial.h>
#define DirectionControl 3
#define Pin13LED 13
int RX;

SoftwareSerial RS485(8,9);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("configuring serial:\n");
  RS485.begin(9600);
  Serial.println("configuring RS485" );
  Serial.println("set up done!!");

  pinMode(Pin13LED, OUTPUT);   
  pinMode(DirectionControl, OUTPUT);  
  
  digitalWrite(DirectionControl, LOW); //preparing for receiption
}

void loop() {
  // put your main code here, to run repeatedly:
 if (RS485.available()) 
  {
  RX = RS485.read();   // Read the byte 
    
    digitalWrite(Pin13LED, HIGH);  // Show activity
    delay(1000);              
    digitalWrite(Pin13LED, LOW);   
    delay(1000);
    Serial.println(RX, HEX);
   // Serial.write(RX);   
    }
  else {Serial.println("Oops!!!");  // print this if serial is not available
  delay(1000);}
}

conn_diagram.PNG

It's specified in the drive's manual.

May we ask a link to that manual?

The data coming is in MODBUS RTU protocol.

The ModBus RTU protocol specifies that either 8E1 or 8O1 has to be used. That would mean you cannot use SoftwareSerial to connect to that device. As some device manufacturers specifies ModBus but don't care if they follow the standard there are implementations where ModBus is in the manual but 81N has to be used. Without the manual mentioned above we cannot tell.

Even if 81N has to be used in your case, don't use SoftwareSerial but AltSoftSerial if the used pins are 8 and 9. SoftwareSerial is a cripple that might be used only if there absolutely no other chance.

Remove the delay() calls from your loop it would let you receive only one character or less per second, not enough for your case I guess.

Thanks for the reply and information.

Here is the link for manual.

You can have a look at Page no. 2-25 and 5-10 for information regarding RS485. I have this only manual for reference from the manufacturer.(nothing more!)

About the delay statements: I have removed the delay statements. Now I am getting 64 bytes of data continuous and after that "OOPS"(referring to the code) statement followed by 2 more bytes.

As I am new into these things, Can I request you the link to some information about 8E1 and 8O1?

The manual says the device defaults to 8N2, so again, you cannot use SoftwareSerial to access that device with that configuration.

Can I request you the link to some information about 8E1 and 8O1?

That's short for 8 data bits, even parity, one stop bit (8E1) or 8 data bits, odd parity, one stop bit (8O1). Your device defaults to 8N2, so 8 data bits, no parity but 2 stop bits.

So either connect the RS-485 adapter to the hardware serial interface and debug with p.e. AltSoftSerial or use an Arduino with more than one serial interface (p.e. Mega2560).

hello again,

Thanks for the support.

I have the same connection diagram with single modification with RE and DE pins to pin 2 and pin 3 respectively. But Now, with a good insight of MODBUS RTU protocol and ModbusMaster library, i have edited one of the examples as following :

#include<ModbusMaster.h>
#include<SoftwareSerial.h>


#define MAX485_DE 3
#define MAX485_RE_NEG 2

ModbusMaster node;
SoftwareSerial RS485(8, 9);    // as I need Pin 0 and 1(RX,TX) for serial monitoring of data

void preTransmission()
{
  digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);
}

void postTransmission()
{
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
}

void setup() {
  // put your setup code here, to run once:

  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);

  // Init in receive mode
  digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);

  //My slave uses 19200 baud

  Serial.begin(19200);
  delay(10);
  Serial.println("starting arduino: ");
  Serial.println("setting up Serial ");
  RS485.begin(19200);
  Serial.println("setting up RS485 port ");
  node.begin(1, RS485);
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}

void loop() {
  // put your main code here, to run repeatedly:
  uint8_t result;

  result = node.readHoldingRegisters(42054, 1);
  
  Serial.println("reading");
  Serial.println("result :");
  Serial.println(result);

  if (result == node.ku8MBSuccess)
  {
    Serial.print("data : ");
    Serial.println(node.getResponseBuffer(1));
  }
  
}

I am getting result : 226 (E02 corresponding to response timed out error ).

Also, from the following link, i tried to modify library which did not work at all, again result was the same.

How can i ensure that at least my query is being sent?
What can possibly be wrong with this?
what am i supposed to put here : Serial.println(node.getResponseBuffer(------));?
what does it really mean by "index of response buffer array" ?

conn_diagram.PNG

As I suggested to you in a pm, it would be best to use an Arduino board with more than one hardware serial async port, such as Pylon mentions, a Mega2560.

Or, use something like an LCD to display data and then use hardware serial port to communicate via Modbus.

Using SoftwareSerial is problematic and I would not suggest to use it at all especially when using a protocol such as Modbus RTU.

Now, with a good insight of MODBUS RTU protocol and ModbusMaster library

Oh, right, I guess you have it all sorted now then.


Paul - VK7KPA

Also, from the following link, i tried to modify library which did not work at all, again result was the same.

rs485 - Arduino as Modbus client with MAX485 doesn't get any response - Electrical Engineering Stack Exchange

This code does only activate pin 3, you seem to use pin 2 (I don't know why BTW). The above answer refers to an old version of the library and as you use the pre-/postTransmission() calls this doesn't apply to your sketch.

Post the resulting library code to see if you broke some other stuff.

RS485.begin(19200);

I never saw a SoftwareSerial instance working with baud rates higher than 9600, even that rate needs a quite timing tolerant communication partner.

It seems you didn't get any answer, so you either have a problem with the SoftwareSerial flaws or your device doesn't answer correctly (might listen on another ModBus ID). I'd start by looking at the RS-485 signal with a scope.

Thanks for suggestions..

I tried following things :

  1. Changed Arduino board and RS485-TTL module, to avoid chance of problem due to false hardware.
  2. Created A slave on PC using Modsim32 just to verify established communication.
  3. Used LCD (connection diagram is attached here.)
  4. Modified my code excluding SoftwareSerial library.
  5. Reinstalled ModbusMaster libtary to clean up the mess earlier created by myself.
  6. Tried modifying Baud rate(to 9600).
  7. Interchanged Pins D+ and D- as well as DI and RO.

Still i am getting same "result : 226 ", but, this time on LCD.
I guess Something is to be done with enable pin of RS485-TTL converter.
what possibly be wrong?

#include <LiquidCrystal.h>
#include<ModbusMaster.h>
#define DirectionControl 3

ModbusMaster node;
const int rs = 12, en = 11, d4 = 6, d5 = 5, d6 = 4, d7 = 3;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {
  
  Serial.begin(9600,SERIAL_8N2);
  node.begin(1,Serial);
  lcd.begin(16, 2);
  pinMode(DirectionControl, OUTPUT);
  digitalWrite(DirectionControl, 1);
  lcd.clear();
  lcd.print("Setup done!");
  
}

void loop() {
  
static uint32_t i,data;
 uint8_t result;
i++;

node.setTransmitBuffer(0,lowWord(i));
node.setTransmitBuffer(1,highWord(i));

result= node.readHoldingRegisters(1,1);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(result);
if (result == node.ku8MBSuccess)
  {
     data = node.getResponseBuffer(0);
  }
    lcd.setCursor(0,1);
     lcd.print(data);
}

Hi again,

Is ModbusMaster library going to take care of the Receive enable pin?
Because I don't see any pulse on DE/RE lines.
Also the signal in DI line seems ok, but nothing is there on RO line.

Here, i am attaching snippets of my DSO readings.
how should I modify my code to do the same??

regards,
Prerana.

I don't really use this ModbusMaster library produced by Doc Walker I recall, except for a bit of test code I wrote some time ago.

I believe the reason you are not seeing any change of state on the line that controls the EIA-485 data direction is because you need to register a couple of callback functions which are not in your code above.

Take for example the code below, from my test code and add the missing parts to your own code:

#define MAX485_TX_ENABLE  7  // EIA-485 transmit control pin

ModbusMaster node;

void preTransmission() {
  digitalWrite(MAX485_TX_ENABLE, true);
}

void postTransmission() {
  digitalWrite(MAX485_TX_ENABLE, false);
}

/*---------------------------------------------------------------------------------
 * void setup()
 * Configure initial states and IO ports.
 * Register Modbus callbacks allow us to configure the RS485 transceiver correctly.
 * Modbus slave ID 1.
 */
void setup() {
  pinMode(MAX485_TX_ENABLE, OUTPUT);
  digitalWrite(MAX485_TX_ENABLE, false);

  Serial.begin(9600);

  node.begin(1, Serial);
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);

}

Paul - VK7KPA

#define DirectionControl 3

const int rs = 12, en = 11, d4 = 6, d5 = 5, d6 = 4, d7 = 3;

I don't think that connecting the d7 signal of the LCD and the DE/RE signal to the same pin is a good idea.

Here, i am attaching snippets of my DSO readings.
how should I modify my code to do the same??

You should tell us what the different signals are. What's yellow and what's blue on the two pictures?

And implement the change rockwallaby suggested!

Hi,

In image TEK0003 blue : D+ and yellow : D-
In image TEK0005 blue: RO and yellow : DI

I corrected that DirectionControl pin and implemented changes suggested by rockwallaby.

I Get a Pulse on DE/RE line.
But, result is the same.

Somehow, I tried pulling down the RO pin with 1K resistor and i got this signal on RO line.(image attached here) getting 224(Invalid slave ID error) on LCD now.
blue : DI and yellow : RO

Thanks and Regards,
Prerana.

Prerana, I'm sorry that you are having such troubles, it really should not be difficult.

So, on your last DSO image, blue is the data coming out of the micro-controller into the TTL - RS485 converter, correct ?
If that is so, then you would be generating an RS485 signal at the A and B terminals.

Can you confirm the VSD is configured to use the Modbus protocol, as the default protocol for the drive is the Frenic loader protocol ?

You need to double check that the communications setting in the VSD match the setting you have in the Arduino for Modbus.
So, check again, baud, parity, data bits and stop bits are the same for both devices.

Make sure your cable to the VSD RS485 connector is correctly wired.

You can also try with the keypad removed from the VSD as this is shared on the RS485 bus.

You can also try swapping the A and B lines from the converter to the VSD.


Paul - VK7KPA

Hello,

As per your suggestions, I cross-checked my communication settings. They seem fine.
yes, blue is the data coming out of the micro-controller into the TTL - RS485 converter. RS485 signals generated are attached to previous post as TEK0003.png

As, I have created a virtual slave,i have set the parameters as 19200, 8N2, Modbus RTU.

Whenever, I use my drive, I make sure that the communication settings are correct. I am unable to figure out what is being wrong here! :frowning:

Thanks,
Prerana.