RS485 monitor-sniffing using arduino and MAX485

Hello,
I want to use arduino to monitor RS-485 messages on RS485 bus.
On this RS485 bus are normally connected 4 devices, arduino would be 5th. Moreover, the bus is using 12VDC.
I try to use the module described in this link.
http://jheyman.github.io/blog/pages/RS485Sniffer/
also I remove R7 as proposed.
Moreover I used a level shifter because RS485 bus is 12V and arduino 5V.
But I was not able to see any messages.
When I connect RS485 module and level shifter, then RS485 bus is totally down.
When I removed the R7 and keep level shifter again bus is totally down.
I tried to connect RS485 module and arduino on the bus, without level shifter. In that case RS485 was up, but nothing happened.
Serial.available command returns always nothing.
GND was common between arduino and RS485 bus.
Any help or any other suggestion?

RS485 is a 5 volt standard.
If you see a voltage higher than 5 volts then it is not a RS485 bus.

12v sounds like LIN bus or perhaps something proprietary such as the communications bus you might find in an alarm control panel. It could also be RS232.

Have you looked at the signal with an oscilloscope? If so do you see a pair of mirrored signals? Are they both above 0v or is one below 0v?

Moreover I used a level shifter because RS485 bus is 12V and arduino 5V.

I told us you used an RS-485 driver (max485). This is not a level shifter. Behind that chip you don’t need a level shifter, it’s outputs are 5V.

When I connect RS485 module and level shifter, then RS485 bus is totally down.

Post a complete wiring diagram of that setup!

also I remove R7 as proposed.

You should alse remove R5 and R6. These resistors are only needed once per bus, so a sniffer definitely shouldn’t have them.

Serial.available command returns always nothing.

There are other factors than just the hardware that need to be correct to show a successful sniffing. One is the baudrate, the other is the parity and stop bits. As you failed to post the code you used as well as documentation of the other devices on the bus we are not able to check if that was correct.

If you see a voltage higher than 5 volts then it is not a RS485 bus.

That’s wrong. RS-485 voltages should be in the range -7 to 12 Volt. An RS-485 driver (as the MAX485) can handle that voltage range.

Have you looked at the signal with an oscilloscope? If so do you see a pair of mirrored signals? Are they both above 0v or is one below 0v?

Obviously you never did that yourself. RS-485 A and B don’t show that picture against GND. You can only see a clear picture on the scope if you connect it’s ground to B and signal to A (or vice versa).

Here is my code

int16_t a = 0;
byte b = 0;
byte c = 0;
byte d = 0;
byte e = 0;
byte address=0;
byte parity=0;
int RT_pin=8;

void setup() {
  // put your setup code here, to run once:
  Serial.begin (9600);  // debugging prints
  Serial2.begin (9600, SERIAL_8N1, true);  // 9 bit mode pin17(RX) pin16(TX)
  Serial.println ("--- starting ---");
  pinMode(RT_pin,OUTPUT);
  digitalWrite(RT_pin, LOW);// Receive mode, put it HIGH for transmit mode or change it in case in loop function
}


void loop() {
  // put your main code here, to run repeatedly:
  if (Serial2.available () > 0) {
    a = Serial2.read();
  }
  b = highByte(a);
  c = lowByte(a);
  d=c>>1;
  e=b<<7;
  address=e+d;
  parity=bitRead(c,0);
  Serial.print("the received 9bit number is  ");
  Serial.print(a, HEX);
  Serial.print("    ");
  Serial.print(a);
  Serial.print("   ,the MSB is   ");
  Serial.print(b, HEX);
  Serial.print(",   the LSB is   ");
  Serial.print(c, HEX);
  Serial.print("    ");
  Serial.print("the adress number is   ");
  Serial.print(address, HEX);
  Serial.print("   , the parity id    ");
  Serial.print(parity, BIN);
  Serial.println("");
  delay(1);
}

My connection diagram is like picture but use of level shifter is wrong, and I don't use the same pins as picture.
I was confused because on the plug there is a 12V pin, so I thought that the RS485 was 12V.
Today I examine the pcbs of the devices and I saw that one device use MAX487 and the other uses LTC1387.
When I tried to connect the oscilloscope, without anything other connected, the bus was again down and the device shows COM error.
Later I try to remove R5 and R6 resistors and I will come back to tell you the outcomes

It sounds like you are connecting the oscilloscope probe ground to the A or B line. This will stop communication.

Normally you connect the oscilloscope probe ground to the device ground then look for a signal on the A or B line.

Remember, RS485 is designed as a 3 wire system. You need A, B and Ground to be connected for reliable data transfer.

My connection diagram is like picture but use of level shifter is wrong, and I don’t use the same pins as picture.

You must not use level shifters on the bus side. The MAX485 is a bus driver, it’s bus pins must be directly connected to the RS-485 bus!

It sounds like you are connecting the oscilloscope probe ground to the A or B line. This will stop communication.

That’s not true. Of course you must not connect the oscilloscope ground to any ground on the Arduino because that would produce a short circuit. But the RS-485 signal is just a difference in voltage between A and B, A and B doesn’t have a defined voltage to GND!

Normally you connect the oscilloscope probe ground to the device ground then look for a signal on the A or B line.

That you won’t see the signal! I tried that too and failed horribly, loosing hours and hours debugging although the signal was correctly there I just measured the wrong thing.

Remember, RS485 is designed as a 3 wire system. You need A, B and Ground to be connected for reliable data transfer.

@mikb55: Although a common ground usually helps and the cable shield is a good way to connect grounds, RS485 is designed as a 2 wire system. The signal is transferred as the voltage difference between A and B so it explicitly doesn’t need a ground potential to compare with. If you think I’m wrong, tell me what you think ground is needed for. I cannot find a reference to that in the standard and there is no such connection in the MAX485 datasheet (just one example).

pylon:
@mikb55: Although a common ground usually helps and the cable shield is a good way to connect grounds, RS485 is designed as a 2 wire system. The signal is transferred as the voltage difference between A and B so it explicitly doesn't need a ground potential to compare with. If you think I'm wrong, tell me what you think ground is needed for. I cannot find a reference to that in the standard and there is no such connection in the MAX485 datasheet (just one example).

Copied from https://www.ti.com/lit/an/snla049b/snla049b.pdf?ts=1616148375279

"Although the potential difference between the data-pair conductors determines the signal without officially
involving ground, the bus needs a ground wire to provide a return path for induced common-mode noise
and currents, such as the receivers' input current. A typical mistake is to connect two nodes with only two
wires. If you do this, the system may radiate high levels of EMI, because the common-mode return current
finds its way back to the source, regardless of where the loop takes it. An intentional ground provides a
low-impedance path in a known location, thus reducing emissions."

Interestingly there is a special case with a 2 node point to point connection where you can skip the ground providing you use failsafe bias resistors at both ends.
https://www.eevblog.com/forum/beginners/battery-powered-devices-communicating-via-rs485-and-grounds/

If you have 3 or more nodes then you need a ground. For a ground you have a choice between the devil and the deep blue sea. Using chassis ground/protective earth could result in high common mode voltages due to differences in ground potential. Depending on your earthing arrangements a dedicated ground wire between transceivers could result in a ground loop.

Also accidentally shorting a MAX485 transceiver A or B output to ground will cause the transceiver to go into thermal shutdown thus halting Rx as well as Tx for that node.