Cheap chinese RS 485 boards will not work, for me anyway ?

Go To Last Post
29 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi everyone

 

I have been drive mad over the last few weeks now by a problem I really do need to overcome for a model railway project I am working on.,

 

I just want to have RS485 comms (NOT DUPLEX) fromn a single master to about 6 slaves. Nothing difficult you may say ?  Well, I have tried everything, including about 7 or 8 of these boards, and cannot get them to communicate a single byte.  I am setting the TxEnablepin high before transmitting and thhen LOW afterwards so I can receive the slavers response, NOTHING.  IO have treiud reversinbg th e~A & B leads (twisted pair), I havtriedit with Manos , Unos and now a pair of Megas using the hardware ports. still NOTHING.

 

If anyone can help me on this I would be Ecstatic !

Ian Turner
Early stage Arduino developer

Last Edited: Tue. Apr 24, 2018 - 01:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Let’s have a picture of the board you are talking about. A schematic of your setup would be helpful also.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sure thing link to Amazon, where I bought them...

 

https://www.amazon.co.uk/TOOGOO-MAX485-Module-Converter-Arduino/dp/B00ORLD92O/ref=sr_1_4?ie=UTF8&qid=1524570293&sr=8-4&keywords=rs485

 

I can post my test code if you need it, it is not very long.

 

I just put an led across the enable pin on sender, and it is flashing happily as it sets enable High/Low.....  Receiver enable is set to LOW.

Ian Turner
Early stage Arduino developer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think posting your code will help. A sketch of how your connecting these things together will also help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

chopperaddict wrote:
I havtriedit with Manos , Unos and now a pair of Megas
  I guess that "Manos" are also some variant of an "arduino" board, just like the other 2.

 

On "arduino" boards usually the serial port is connected to a simple USB <==> UART device (such as CH340). and the UART can not be used (at least the RxD pin) for other communications, because that creates a short circuit with the "USB <==> UART" chip without modifying the boards.

 

There are some "arduino's" in which the USB <==> UART connection is handled by another AVR. This 2nd AVR may put the UART pins to a high impedance state if the serial connection is not in use, but these boards are rare and I'm not sure if it works.

 

So get a bunch of cheap "arduino nano" clones frome Ebay / Ali and disable (or completely remove) the CH340 chip. and solder in an ISP header for normal ISP programming.

Then you can connect the RS485 transceivers to these boards.

 

And get yourself a (or some) USD 5 Logic Analysers. (Search Ali / Ebay for "24m 8ch") These cheap devices turn a lot of guesswork into knowing. I have found a USD 5 LA more usefull for uC work than my USD 300 Rigol Oscilloscope.

Paul van der Hoeven.
Bunch of old projects with AVR's:
http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For successful half duplex comms, you must wait by polling the TXC (xmit complete) before changing directions by dropping the tx enable pin!  

 

So, the master sets the data direction (tx enable), sends all data polling the UDRE bit for each byte,

then the master polls the TXC bit waiting for all data to be sent, then drops the tx enable line.....

 

Oh one more item, rs-485 must have terminating resistors across the A/B lines at each end of the line, usually a 120 ohm resistor is used.

Image result for rs-485 wiring

 

Note: the resistors at each end of the line!

 

Hope that helps.

 

Jim

 

 

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

Last Edited: Tue. Apr 24, 2018 - 01:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the feedback guys.

 

A couple of points are raised, my boards are TTL to 485, not USB to 485.

Here is a sketch of my wiring :

 

For completeness, here are the 2 sketches for master (Sender) and Slave (receiver)

 

This particular cut is using 2 separate  UART outputs as suggested by a friend of mine to try to get something to work, somay seem a littleweird, but just check out the Seria1 and Seria2 commands and you  willsee what I am doing by trying to isolate each part of the process wherever possible.

 

Master code :

 


///////////////
//RS485 Master
///////////////
/*
 *    UNO
 */
//#include <RS485.h>
#define RS485RECEIVEPIN    18 // Rx   
#define RS485TRANSMITPIN   17 // Tx
// next 2 are linked together physically
#define RS485TXENABLE      4  // Receive Control pin

#define RS485LOW        LOW
#define RS485HIGH       HIGH

#define MASTERID  '1'   // our board ID on the network
#define SLAVEID1  '5'   // right hand point board ID on the network

double y=0;
bool rs485Data = false;
// receive any available message
char buf[12] = "";
// general messages buffer
char gbuff[128]="";
char Message[3] = "51"; // dummy output data foir testing only
char replyData[15] = "";   // buffer for Slaves reply data

void setup()
{
  Serial.begin(9600);
  pinMode(RS485RECEIVEPIN, INPUT);
  pinMode(RS485TRANSMITPIN, OUTPUT);
  pinMode(RS485TXENABLE, OUTPUT);
  pinResetConfig();  // set all relevant pins to LOW
  Serial1.begin(28800); // begin RS485 comms
  Serial2.begin(28800); // begin RS485 comms
  Serial.println("Master sender setup completed...");
}

void loop()
{
   String  inBuff="";

   digitalWrite(RS485TXENABLE, RS485HIGH);  // set transmit enabled to send data
   
   // show what we are sending in monitor
   Serial.print("\nSending: ");
   Serial.print(Message);
   Serial.println(" through RS485 adaptor boards");
   delayMicroseconds(800);
   Serial2.write((char *)Message);    // Send message down line
   Serial2.flush();
   // Now lets check for any incoming from slave
   // if y > 0 we have y characters to download
   digitalWrite(RS485TXENABLE, RS485LOW);  // set transmit disabled to allow receive
   y = Serial1.available();
   Serial.println(y);
   if (y > 0){
      // yes, grab it into a String object
      inBuff.setCharAt(0, 0);
      digitalWrite(RS485TXENABLE, RS485LOW);    // Set receive enable pin LOW      
      for (byte x = 0; x < y; x++){
         inBuff.concat((char)Serial1.read());// (char) converts to ASCII characters
      }
      sprintf(gbuff, "RS485 Data [%s] received from Slave...\n", (char *)inBuff.c_str());   // Convert String object to ASCII char string
      Serial.println(gbuff);
      // grab data into a C String so check function can manipulate and use it
      strcpy(replyData, (char *)inBuff.c_str());
      
   }else{
      Serial.println("No data received from Slave...\n");
   }
   delay(500);
}

Slave Code :

 

// RECEIVE
/*
UNO
*/
// required for RS485 communications

#include <RS485.h>

#define RS485RECEIVEPIN    18  
#define RS485TRANSMITPIN   17
// next 2 are linked together physically
#define RS485TXENABLE      4   //Transmit Control pin


#define RS485LOW     LOW
#define RS485HIGH    HIGH

#define MASTERID  1  // Thisis the network MASTERS id
#define SLAVEID_1  '5'  // this is **this** Arduinos ID for 2 way serial communications, and/or RS485

double y = 0, z= 0;
char  gbuff[128] = "";  // GENERAL MESSAGES BUFFER
char buf[] = "734";  // dummy data to send for testing only
char d, e;


void setup(){
  Serial.begin(9600);
  pinMode(RS485TXENABLE, OUTPUT);
  pinMode(RS485TRANSMITPIN, OUTPUT);
  pinMode(RS485RECEIVEPIN, INPUT);
  Serial1.begin (28800);
  Serial2.begin (28800);
//  pinResetConfig();  // Reset all relevant pins to LOW
  Serial.println("Slave Receiver setup completed...");
}

void loop(){
   String  inBuff ="";
   digitalWrite(RS485TXENABLE, RS485LOW);  // disable RS485TXOUTPUT on Serial driver 
   delay(500);
   Serial.println("\nSlave waiting for data VIA rs485 HARDWARE");

   // check for any data coming in
   z = Serial2.available();
   Serial.println(z);
   y = Serial2.read();
   Serial.println(y);
   if (z > 0){
      // yes, grab it into a String object
     inBuff.setCharAt(0, 0);
     for (byte x = 0; x < y; x++){
         inBuff.concat((char)Serial1.read());// (char) converts to ASCII 
      }
      sprintf(gbuff, "RS485 Data [%s] received as ASCII...", (char *)inBuff.c_str());   // Convert String object to ASCII char string
      Serial.println(gbuff);

      // respond to master
      Serial.println("Sending \"734\" to master");
      digitalWrite(RS485TXENABLE, RS485HIGH);  // enable RS485TXOUTPUT on Serial driver 
      Serial1.write(buf);
      delayMicroseconds(800);
      digitalWrite(RS485TXENABLE, RS485LOW);    // Set receive enable pin LOW
   }
   else{
      Serial.println("No data received from Master...");
   }
}

 

Ian Turner
Early stage Arduino developer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your missing termination resistors!

 

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The picture as shown in post #6 is incomplete and misleading.

RS485 drivers only work propperly if the A and B lines have a common mode offset between -5V and +12V and this has to be guaranteed somehow. A common ground wire is the simplest way to do this.

This GND connection is often ommited when drawing logical chips on a single schematic for a single PCB, but it does need to be there, and because RS485 networks often have long wires and multiple PCB's the GND (and Power supply) connections are an important part to also draw on the schematic.

 

When the master switches from sending to receiving there is a time that the A and B wires are floating, this can (and often does) lead to false start bits and therefore it is very common to add a "biasing" network.

 

I like to use regular CAT5 cable for RS-485. Use one twisted pair for data, use another twisted pair for GND and +24V (with local SMPS ciruits on each PCB). Cat5 can carry up to around 1A without too much heating, but you will loose a few volts along the cable ( The GND level of a distant node will also get "lifted" by this current ! ).

The 2 spare twisted pairs can be used for other uses. For example 100Mbit/s Ethernet only needs 2 of the 4 pairs in a Cat5 cable, I've also used a pair to send digital audio (via a SPDIF/ RS485 converters). Twisted pair can also be used for analog video, etc.

Paul van der Hoeven.
Bunch of old projects with AVR's:
http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Paulvdh wrote:
A common ground wire i

Yup, your right! I forgot to show the GND wire also between all units! crying

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

These boards already have terminating resistors, and I have tried adding 680 ohms pullup/pulldown resistors as per Nick Gammons wiring diagram.They made no difference

 

QUOTE 

So, the master sets the data direction (tx enable), sends all data polling the UDRE bit for each byte,

then the master polls the TXC bit waiting for all data to be sent, then drops the tx enable line.....

ENDQUOTE

 

I fear I do not understand the above para. Casn you explain it ? I am not using any libraries at present, altohugh I have already been through trying Software serial withg no luck, and even the RS485.h

 

Oh yes, I have just ordered a logic analyzer as suggested above, and loaded the necessary "Logic" software ready for it. :-)  (Friday delivery)

 

Ian Turner
Early stage Arduino developer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

chopperaddict wrote:
hese boards already have terminating resistors

Are you sure?  IF that was true, then only two could be used, three or more on the line would overload it, or require you to remove the terminators of all the "in-between" slaves.

Is there a common ground between all units?

 

chopperaddict wrote:
I have tried adding 680 ohms pullup/pulldown resistors

That would only be done the one end, usually the master end.

 

chopperaddict wrote:
I do not understand the above para.

Ignore, I see your using the Arduino environment, you are using the correct calls, flush() will wait for the TXC flag to be set before returning!

 

Jim

 

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

With "arduino" boards the (single) uart is reserved for the PC and can not be used without hardware modification (As posted in #5).

Paul van der Hoeven.
Bunch of old projects with AVR's:
http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well the quoted packet tells you exactly what to do. In normal UART use you just wait for UDRE which says it is ready to take the next byte so you can load them in as fast as possible but in 485 everyone needs to sit in listening (rx) mode when not actually transmitting so once the sender gets to the very ladt byte of what he wants to send then instead of waiting for UDRE (which only says "buffer ready to take next byte") instead it now waits for TXC (transmission complete) which says "the very last bit of that last byte has left the AVR" abd at that point the direction can be switched from transmitting to listening.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

Remember that TX must connect to RX in a fixed system & TX mode must connect to RX mode in a bidirectional setup. This is a common error.

 

For the moment, forget about bidirectional, enabling disabling, or even working with more than 2 devices.  Concentrate on sending a message only from unit A TO unit B  (A-de/re pins =1, B-de/re=0)..does that work? Get that working.  That will help investigate wiring errors, voltage level errors & even baud rate settings.

You are using Xtals for frequency, correct?  DO NOT us the internal RC osc, it will often not be accurate enough & only add to your misery.

 

Once that works go back to your code & start adding bidirectional control, enabling, disabling, handshaking, etc.

When in the dark remember-the future looks brighter than ever.

Last Edited: Tue. Apr 24, 2018 - 04:04 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

chopperaddict wrote:
These boards already have terminating resistors

You may be correct I see R7 is a 120 ohm, but can not confirm its across the AB terminals.

If so you will need to remove R7 on all units not located at the ends of the twisted pair.

 

Your diagram of the test setup should work, use avrcandles suggestion of starting with sending in only one direction with the de/re pins using fixed levels,  and get that working.

 

Jim

 

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks again for the feedback, very encouraging.

 

I have checked R7 with my DMM, and it IS across A & B, so we can rest assured that termination is good on my two board system. (Thats atleast one issue covered.)

 

I will spend the rest of today setting it up as described by avrcandles. IO assume I am looking at simply rseting RE and Di high on the sender and reading the Ro output with a didgital or analogread ?

 

I am using Arduinos, so am using the crystal on board them.  This is not a chip on a breadboard system.

Will report back as soon as I have done the above.

 

 

Ian Turner
Early stage Arduino developer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK folks, have done some testing here, with what seem to me to be very strange results

 

My Sender Mega uses digitalWrite(,,,,,) to pull Re HIGH, my receiver Mega uses digitalWrite(,,,,,) to pull Re LOW. That should put it isn the right mode for sender to send data ?

 

I have tried Nick Gammons rs485_protocol.h system that provides sendMsg and RecvMsg, but in my testing these do not work at all  If I use digitalWrite to the transmit pin,  and digitalRead at the other end, I get a value of 1, using analogRead I get some suspicious values around 30 - 50, which I believe is just the pins floating as I see the same values when not sending anything at all.?

 

So basically, the boards I have here do not seem to send/receive anything ?  I have tried putting puldown resistors on the receiving pins (Serial1 on the Mega), but still get the same figures.

 

Am I being dumb or what ?  These  TTL to RS485 boards are all new, and I have tried lots of them.

 

Ian Turner
Early stage Arduino developer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you have any test tools such as a scope, logic analyser or ICE ?

 

A scope or LA is certainly going to help a lot to see the signals the boards are/aren't producing.

 

With an ICE you can take a more detailed look at the action of the software.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If I use digitalWrite to the transmit pin,  and digitalRead at the other end, I get a value of 1, using analogRead I get some suspicious values around 30 - 50

WHAT are you doing???? Configure uarts on both ends & send a byte via UART on the TX end & see if it comes into the UART on the RX end.....just a few lines of code.  

There is simple code in the datasheet to send a few bytes & rvc bytes.

Also how do you know what the rcv value you got is?  Do you use a display?...maybe  look for  a "Q"  and light an led when you get one & "P" turn it off

When in the dark remember-the future looks brighter than ever.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

chopperaddict wrote:
My Sender Mega uses digitalWrite(,,,,,) to pull Re HIGH, my receiver Mega uses digitalWrite(,,,,,) to pull Re LOW.

 

Backwards, DE/RE high to send, DE/RE low to receive!

 

Jim

 

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Isn't that what I have got ?  digitalWrite(xxxxx, HIGH) at the sender end, and the reverse on the receiver end ?  I have DE and RE soldered together on the boards themselves.

Ian Turner
Early stage Arduino developer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have an LA coming tomorrow (hopefully) although I have never used one before.  But hopfully it will help me to bottom this issue out.

Ian Turner
Early stage Arduino developer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

chopperaddict wrote:
Isn't that what I have got ?

Yes, my mistake, the RE reference confused me, as it is /RE or low to enable.

Anyway, you are setting the direction correctly, not sure what your doing with DigitalWrie/AnalogRead on the data lines, as they are serial data in/out!

 

Jim

 

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But hopfully it will help me to bottom this issue out.

Hook it to the AVR sides of the chip, NOT the actual RS485 data lines...since those are differential, you will rapidly confuse yourself & magnify your misery.  Just endure a "hi/lo" going in at the entry travels down the lines & comes out as  a hi/lo at the exit. 

 

Note you could do similar with a meter or led (no UART, just ports)

Set your AVT TX port pins as output, rx pins as input.    Set your RS485 enables correctly,  Force TX pin steady hi (verify with led or meter)......does the final exit point down the line at RX read high with LED or meter?

Now set TX low ...RX should be low...that checks the chain, at least for steady signals.

 

 

When in the dark remember-the future looks brighter than ever.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

AS per my SIG line, I am an early Arduino user.  I used to write software for a living, but have little hardware experience.

 

I am using the UART outputs from the Arduino Mega for this work.  Are you suggesting that I remove the RS485 adaptor boards from the equation at this point in time ?

 

If  so, I have already been there, and done various tests with RE enabled and DI HIGH and reading RO on the receiver These resulted in what appeared to be  reasonable results.  Eg 5v on the enable pin, 300 MmV on the receiver RO

 

You mention configuring the UART's ?  I set the RS485 connection up at say 9600 baud, and that is all.  I have verified that the COM ports are set to the same Baud rate

 

I am reading the values received from the Arduino monitor window, and/or a Putty window.

Ian Turner
Early stage Arduino developer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am a little confused with the terminology used here ?  You talk of "AVR side" of the chip, I am using a TTL -> RS485 aadaptor board, not just the 485 chip used on it.  AFAIK I have to set the RE HIGH to allow the sender to transmit,and then set DI high, which is done by the actual data being sent.  On the Receive end, I pull the RE LOW, which is the default setup to allow any 485 module to receive.

 

Am I wrong in my understanding ?

Ian Turner
Early stage Arduino developer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

chopperaddict wrote:
Am I wrong in my understanding ?

No, you have that right!

With the RE HIGH on the send side, and DI connected to the TX pin of the Arduino, you can send serial data like "Hello World!" and see it come out the other end, assuming the receiving end is set RE LOW and the DO line connected to RX of the other Arduino. 

 

Jim

 

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am a little confused with the terminology used here ?  You talk of "AVR side" of the chip, I am using a TTL

 

The side of your circuit connected to the AVR...should be easy to find.

 

You have a data connection to an AVR UART (SIDE ONE) that goes  to some circuitry to an RS485 side (SIDE TWO) down some long cable to some more circuitry to a data connection to another AVR UART (SIDE ONE)

 

 

When in the dark remember-the future looks brighter than ever.