5
\$\begingroup\$

I've been stuck on this issue for quite some time. I am trying to use an arduino to communicate with another device using RS485. The problem is that I can see the data being sent but, the device does not reply at all. Here's the break down so far:

  • I am using a hardware serial port and a Max487 rs485 transceiver which is attached to a custom sheild.

  • I am able to get the device working over RS232 the same library on a different Serial port so, I don't believe its a software issue.

  • I have also been able to communicate with the device using a usb to rs485 converter. This wasn't attached to my Arduino, I sent the data using realterm. So, i don't think its a problem with the device.

  • I am using a shielded cable with 2 twisted pairs. One pair I am using for ground, the other for the Non-inverting/inverting signals. The cable has an impedance of 120Ω. My cable is about 11m long.

  • I have a 120Ω terminating resistor on my pcb and have enabled the biasing termination on the device. (The inverting line is 5V biased, the non inverting is at 0v).

  • When I look at the traces, I can see that all the data is being sent, along with the parity and stop bits. You can see image below. It's a picture of the 2 traces and the result of (non inverting line - inverting line). The scale is 1x

  • I am writing !(Receiver Enable) and Driver Enable pins high when transmitting, and low as soon as the transmission is complete.

  • When I couldn't get it working with my first shield, I made another. Unfortunately, I am still having trouble.

  • The voltage levels for the device are:

    • logic 0: transmitter: 1.5 - 5V receiver: >0.3V
    • logic 1: transmitter: -1.5 - -5V receiver: <=-0.3V

In summary, I don't think its a software issue. I've done a lot of reading but, haven't managed to find anything that helped. Does anyone have any suggestions for what could be preventing the device from responding?

UPDATE Thanks for all the help everyone.

The device is a pump with a controller, which can be found here. I spent some time today using the usb->rs485 converter.

I used it to successfully send data between the computer and the arduino in both directions. I found and fixed 2 software bugs but, it didn't help when I tried it with the pump again. When I looked at the arduino/computer trace, I noticed that (ignoring the horrendous wobbles) the voltage levels were different to what I get when I had the arduino hooked up to the pump. I've added an image. When using the arduino/computer, the voltage level switches about zero and when no signal is being sent, the voltage is about -2V. When using the arduino/pump, the voltage level switches about zero and when no signal is being sent, the voltage is about -1V. Also, when I was using the arduino+computer, I was receiving unexpected NULL characters at the begining and end of the message. I read about a possible cause being a lack of biasing but, I am using biasing resistors on the pump end.

I also, had a quick look at the traces when I connect the computer to the pump via the converter. I had no success in establishing communication. The traces looked horrible though so, perhaps I hooked it up wrong. I'll double check this and post another update.

I have also checked ifthe last bit is being sent properly. I'm using an interrupt triggered when the TX buffer is empty. This drives the !(Receiver Enable) and Driver Enable pins low as soon as the last high/low bit is over.

Does anyone have any thoughts on these results?

UPDATE 2 Sory for the delayed response.

I've had a bit more of a play around and have managed to get the computer communicating with the pump via the usb->rs485 converter. To do so, I had to remove the terminating resistor on the usb->rs485 converter end but left the termination and biasing at the pump end. You can see the trace below (the third picture). Note that the voltage level the signal oscillates about is approx 2V as @davidcary said he gets. Compare this with the voltage levels of the second picture (same set up but with the terminating resistor in place) of approx 0V. You'll also notice that the signal levels of the arduino to pump (picture 1) are about 0.5V lower than that of picture 3 but the oscillations are much smaller. How could I go about increasing the voltage swing? I am converting 24V to 9V using one of these and using it to power my arduino and rs485 chip, if that helps at all.

I'e been playing around with the termination resistors but haven't had any luck yet. I am also trying to use a USB->TTL cable I have to send data to the shield, through the MAX487 and to the pump. I haven't had any success with this yet.

Thanks again for all your help

Signal when I have the arduino connected to the pump controller

Signal when I have the arduino connected to a computer via a usb to rs485 converter

Successful communication between computer and pump

\$\endgroup\$
3
  • 1
    \$\begingroup\$ How about connecting the usb/rs-485 converter to your rs-485 shield and testing transmission/reception? \$\endgroup\$
    – Thorn
    Commented Jan 3, 2013 at 11:30
  • \$\begingroup\$ If you drive the TE/RE# line low and transmit data from the other side, do you see logic-level serial data on the receive pin of the Arduino? \$\endgroup\$
    – akohlsmith
    Commented Jan 3, 2013 at 13:12
  • 1
    \$\begingroup\$ Agree with Thorn about testing the Arduino against the USB converter. Also make sure you are allowing the final byte to be completely clocked out on the line before disabling the driver; serial routines typically wait until the UART peripheral can accept a new byte, but that status flag typically goes active well before the different status flag indicating that the old byte has been completed. Finally, you might leave your receiver enabled so you hear your own transmissions as a debug check. \$\endgroup\$ Commented Jan 3, 2013 at 15:33

2 Answers 2

3
\$\begingroup\$

This sounds like it should be easy to diagnose. You say the signals on the RS-485 bus look OK, so check the next point. Keep following the signal until you find it not right somewhere.

The next logical point to test after the RS-485 bus would be when it gets converted back to a single-ended signal that presumably gets presented to UART receive pin of the device. Does that look right? If not, there is a problem with the RS-485 receiver circuitry. If so, then either the device is not working or you have a protocol problem.

In general, it's good to keep dividing up the suspect parts of the system to isolate what is not working, or to test them in isolation. For example, you could either try to tap the UART line into the device and see if you get what is expected by looking at the bytes on a PC with a low level program, or you could try a program on the PC to inject what you think is the right sequence of bytes and see if the device responds as you expect.

Chances are that if the UART signal at the device looks OK (including the obvious issue of baud rate), then you have a protocol problem. In other words, somehow you're not sending the right data to the device. Early on in bringing up a system like this, I often use a low level test program on the PC that sends and receives individual bytes. I can type byte values in decimal, hex, and as ASCII character, and it displays everything it receives likewise. This can be very useful for verifying that you really do understand the protocol the device expects.

Do some of these experiments and tell us what you find. It would also help to provide some information on this device you are trying to talk to from the micro.

\$\endgroup\$
3
\$\begingroup\$

It's great that you have one "communicating, but not with the desired hardware" setup and another "desired hardware, but not communicating" setup.

Great job with the o'scope photos; that really helps narrow things down.

general suggestions

If I had a problem like this, I'd try to narrow down exactly where the problem was occurring by step-by-step tweaking my "communicating" setup to be more like the "desired hardware" setup (testing after each step, and undoing any changes that make it stop working), and step by step tweaking my "desired hardware" setup to make it more like the "communicating step, to somehow "meet in the middle".

You might enjoy perusing the "tag wiki" associated with our list of questions tagged with .

specific suggestions

I would try to somehow pick one physical RS485 level-converter chip, and try to switch back and forth between (a) the computer sending messages through that chip to your device and (b) the Ardiuno sending messages through that chip to your device. (Not "two identical RS485 level-converter chips with the same text printed on the top". One chip.)

That way that RS485 level-converter chip and everything "downstream" (the wiring, the bias resistors, the receiver, etc) are identical in the two setups I switch back and forth, so any differences when I switch must therefore be caused by something "upstream" (bad hardware hookup to the level-converter chip -- data, power, ground, enable, etc; bad low-level software, bad high-level software, etc).

Then I would try to make the actual bits in the packet identical, perhaps by switching back and forth between (a) sending the bits directly from the computer to the device, and (b) sending the exact same bits from the computer to the Arduino, and programming the Arduino to simply relay those bits down the RS485 cable.

common errors

The most common errors I personally make here are:

  • I've swapped the "A" and "B" wires on the bus, so all the bits look flipped to the receiver, and so the command checksums always fail and so the receiver does what it always does when the checksums fail -- ignore the message.
  • Somehow I have the transmitter GND shifted up (or down) a few volts relative to the reciever GND, enough that all the bits look like "1" (or "0") to the receiver.
  • baud rates don't match
  • "A" and "B" wires not biased far enough apart at the receiver, so tiny amounts of noise in the gaps between real message appear to be random bits, and somehow the receiver gets so busy trying to handle this firehose of bogus data that it doesn't properly handle the real messages.
  • I incorrectly write the software to "send" the message, then immediately tri-state the RS485 level converter. Instead, the software must wait until I'm sure the very last stop bit has finally worked through all the buffers and is finally out on the wire, and then tri-state the level converter. (I see Chris Stratton already mentioned this)
  • Somehow I've partially blown one chip, so some of the pins seem to work OK when I first glance at the o'scope, but those pins output a signal that is too weak or some other part of the chip is so busted that I need to throw away that chip and replace it with a fresh chip.

things that look suspicious to me

With the systems I've worked on, when I'm using a (unrealistically short) 3 foot cable on my workbench, the RS485 chips at both end of the cable have GND and a regulated +5 VDC connected to their power pins, the GND pin of both chips is practically the same, and the "A" and "B" wires have levels that switch between "low" in the GND to +1 V range, "high" in the +4 V to +5V range, and "no one transmitting" has one wire floating to roughly +2.4V and the other wire floating to roughly 2.6 V. So when I hear that you are measuring negative voltages, it makes me suspect that something has gone horribly wrong -- either the power connected to the power pins of the RS485 level shift chips is wrong, or something has been hooked to the RS485 cable that should never touch that cable.

I'm used to differences between high and low of 3V to 5V (i.e., the difference transmitting a "1" and transmitting a "0" of 6V to 10V), so when I see you have a difference half the size I am used to, it makes me suspect that either (a) something else is connected to the RS485 cable, eating up the energy that should be going to making nice big swings, or (b) the RS485 level converters have been "slightly" damaged, are too weak to produce nice big swings, and therefore should be replaced. (In theory a receiver should be able to handle differences 1/10 the size I am used to, but in practice when I see some signal that is way off what I expect, it usually means I've messed up somewhere).

\$\endgroup\$
1
  • \$\begingroup\$ New common error: wrong parity/no parity bit when needed \$\endgroup\$
    – Matt
    Commented Oct 19, 2022 at 17:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.