Pages: [1] 2 3   Go Down
Author Topic: Practical Limits of Serial communications?  (Read 1919 times)
0 Members and 1 Guest are viewing this topic.
Peoples Republic of Cantabrigia
Offline Offline
God Member
*****
Karma: 6
Posts: 722
Arduino happiness
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi everyone,
As you may have read elsewhere, I am grappling with implementing RS485 on the Arduino platform using the hardware serial ports on the 1284P and the 328P. I am now wondering if I was over-complicating matters... whether it doesn't make more sense to just stick to serial communications between Arduinos and drop RS485 altogether. The folk at the Openenergy project are showing something akin, i.e. using  74AHC125 driver chips to isolate Arduinos from the serial line until needed - not unlike RS485 chips, mind you.

What other options should I be considering for line sets shorter than 50' and multiple arduinos?
Logged

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 212
Posts: 13085
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
line sets shorter than 50' and multiple arduinos

Entire books can be (and have been) written on the subject when there are so few constraints.  Your question is not unlike this one: "How can I best travel 5 miles?  I will need to make 3 stops."  If the route is through suburban neighborhoods then foot, bicycle, scooter, motorcycle, and car are all reasonable choices.  If the route is through rugged mountainous terrain, none of those choices are reasonable.

Start with these constraints: Will the communications cable pass through electrically noisy areas?  Any large motors or fluorescent lights along the path?

Will the communications cable pass between buildings?  Will the cable need to be electrically isolated?  Protected from lighting?
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 227
Posts: 14048
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


in general the longer the lines the lower the baudrate that works.

googled baud rate cable length => http://www.chipkin.com/articles/cable-lengths-and-baud-rates-fro-rs485-or-bacnet-mstp -
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Peoples Republic of Cantabrigia
Offline Offline
God Member
*****
Karma: 6
Posts: 722
Arduino happiness
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Coding Badly,

Indoor application only. Unlikely to be hit by large EMI sources as described above. Just a link between various dataloggers running on Arduinos to share power and a communications bus. My preferred implementation would be to use Ethernet wiring, thanks to to the abundance of cables at different pre-confectioned lengths, twisted pairs, and 8 conductors, where I'm proposing to use two pairs for power, one pair for interrupt signaling, and one pair for the serial / RS485 communications.

Communication / power sharing is happening among a master unit (1284p processor) and various modules that are using 328Ps.

Reading up more on the travails by others re: RS485 a couple of things have become apparent. For one, there are some considerations that have to be made regarding the hardware serial buffer, since those are the pins I am using right now. I also wonder if it would make sense for me to not use the hardware serial pins on the 328Ps and go with the SoftSerial library instead - I have spare pins.

Additionally, I neglected to use resistors as described here to give the FTDI header on the 328P boards priority whenever it is connected. But that shouldn't be a big concern on the 1284p since it has two serial ports. On the 328P boards, I worry if the FTDI cable may be causing some trouble, but I kind of doubt it - it just sits there on the bus, listening.
Logged

Peoples Republic of Cantabrigia
Offline Offline
God Member
*****
Karma: 6
Posts: 722
Arduino happiness
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

No need for super-fast comms. The RS485 chips are rated for 5+MBits/s and I'm going to use maybe 250kbit/s...
Logged

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 212
Posts: 13085
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


How many nodes will be connected?
Logged

Peoples Republic of Cantabrigia
Offline Offline
God Member
*****
Karma: 6
Posts: 722
Arduino happiness
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Typically 1 node. Max probably around 5.

I'm starting to wonder if I shouldn't just sacrifice one of the power pairs and go with full-duplex 485... allegedly 'transparent' as far as the UARTs go?
« Last Edit: April 11, 2012, 05:12:18 pm by Constantin » Logged

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 212
Posts: 13085
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


Is it a master-slave network or peer-to-peer?
Logged

Peoples Republic of Cantabrigia
Offline Offline
God Member
*****
Karma: 6
Posts: 722
Arduino happiness
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Master / Slave. The 1284p is the master, all other modules are slaves and only respond when addressed by the master.

I was hoping to keep it to half-duplex to minimize the number of lines necessary. However, I keep having trouble with getting anything intelligible across the divide.

As for other implementations, I wonder if the 74AHC125 chip from NXP might make sense. The openenergymonitor crew built a network around it that could transmit significant distances while maintaining simple TTL signalling. Not as robust perhaps as RS485 with its differential signalling, but unlikely a problem given the above parameters, I hope. Plus, a lot easier to troubleshoot since any FTDI cable and understand what is being sent.
« Last Edit: April 11, 2012, 07:08:41 pm by Constantin » Logged

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 212
Posts: 13085
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I wonder if the 74AHC125 chip from NXP might make sense

You still have the problem of disabling a slave's transmitter# (line driver) when the slave is not transmitting.  With the new interrupt driven Serial (and lack of buffer management methods) that will be difficult.

How are you handling that now with RS-485?  Or are you?


# The other three points (slave's receiver, master's transmitter, master's receiver) can be left active all the time.
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 130
Posts: 8621
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

If you can't get half-duplex running with RS-485 you won't get it running with the buffers, the software will be exactly the same.

Can you post your code? My guess is that are not waiting for the bytes to go before to turn the line around.

Quote
With the new interrupt driven Serial (and lack of buffer management methods) that will be difficult.
I feel that this will cause problems with many programs, the new buffered output should have been an option I think, extra parameter, ability to 0 the buffer size or whatever.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Peoples Republic of Cantabrigia
Offline Offline
God Member
*****
Karma: 6
Posts: 722
Arduino happiness
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm not even trying to turn the line at this point... strictly one-way communication not happening.

Here is some code from the Yourduino site I adjusted for the Slave. Note the constantly-'LOW' RE/DE pin, i.e. receive mode only.

Code:
/* YourDuino RS485 Slave Node A Example
 terry@yourduino.com */

/*-----( Declare Variables )-----*/
int ledPin=13;
int EN = 6;
byte Val;

void setup()/****** SETUP: RUNS ONCE ******/
{
  pinMode(ledPin, OUTPUT );
  pinMode(EN, OUTPUT );
  Serial.begin (28800);
  Serial.println("Setup Complete.");
}//--(end setup )---

void loop()  /****** LOOP: RUNS CONSTANTLY ******/
{
  // receive Data
  digitalWrite (EN, LOW ); // enable receive
  Val = Serial.read ();
  Serial.println(Val);
  if (-1 != Val)
  {
    if ( 'A' == Val)
    {
      digitalWrite (ledPin, HIGH );
      delay (500);
      digitalWrite (ledPin, LOW );
      delay (500);
    }
 
  }
}//--(end main loop )---

And here is the master code. It is running on a 1284P, the first serial bus ends in the FTDI header, while Serial1 is attached directly to the RS485 chip inputs. I probably should simplify this to the point where the RE/DE pin is always high and see if that makes any difference.
Code:
/* YourDuino RS485 Master Node Example
 terry@yourduino.com */

/*-----( Declare Variables )-----*/
int EN = 12;
int LED_PIN =7;

void setup() /****** SETUP: RUNS ONCE ******/
{
  pinMode(EN, OUTPUT );
  pinMode(LED_PIN, OUTPUT );
  Serial.begin (28800);
  Serial1.begin (28800);
}//--(end setup )---

void loop()    /****** LOOP: RUNS CONSTANTLY ******/
{
  // Send Data
  digitalWrite(LED_PIN, HIGH ); // turn on light
  Serial.print ( 'A' ); //FTDI Header Send

  digitalWrite(EN, HIGH ); // enable send
  delay (1); //wait for RS485 chip to be active
  Serial1.print ( 'A' ); //RS485 Bus Send
  delayMicroseconds (660); ////delay recommended by Nick Gammon to deal with the serial buffer clearing before TX is complete
  digitalWrite(EN, LOW ); // disable send
 
  delay(1000); 
  digitalWrite(LED_PIN, LOW ); // turn off light
  Serial.print ( 'B' );//FTDI Header Send
 
  digitalWrite(EN, HIGH ); // enable send
  delay(1); //wait for RS485 chip to be active
  Serial1.print ( 'B' ); //RS485 Bus Send
  delayMicroseconds (660);  //delay recommended by Nick Gammon to deal with the serial buffer clearing before TX is complete
  digitalWrite(EN, LOW ); // disable send
  delay (1000);
}//--(end main loop )---
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 130
Posts: 8621
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

One problem

 Val = Serial.read ();

You're not waiting for a char for be received.

Check out Serial.available()

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Peoples Republic of Cantabrigia
Offline Offline
God Member
*****
Karma: 6
Posts: 722
Arduino happiness
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Check out Serial.available()
______
Rob
Thanks graynomad,

I had used that in the past. No change in behavior.
Code:
/* YourDuino RS485 Slave Node A Example
 terry@yourduino.com */

/*-----( Declare Variables )-----*/
int ledPin=13;
int EN = 6;
byte Val;

void setup()/****** SETUP: RUNS ONCE ******/
{
  pinMode(ledPin, OUTPUT );
  pinMode(EN, OUTPUT );
  Serial.begin (9600);
  Serial.println("Setup Complete.");
}//--(end setup )---

void loop()  /****** LOOP: RUNS CONSTANTLY ******/
{
  // receive Data
  digitalWrite (EN, LOW ); // enable receive
  if (Serial.available()>0) {
    Val = Serial.read ();
    if ( 'A' == Val)
    {
      digitalWrite (ledPin, HIGH );
      delay (500);
      digitalWrite (ledPin, LOW );
      delay (500);
    }
  else Serial.println(Val);
  }
}//--(end main loop )---

I get a "Setup complete" and then nothing on the slave. I get some chatter on the slave as I connect and disconnect the master. I re-verified electrical continuity from one RS485 to the other. Enabling / Disabling the terminators does nothing either. I'm feeling rather blue, I must say.
« Last Edit: April 12, 2012, 06:17:51 am by Constantin » Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 130
Posts: 8621
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I would just print the HEX of whatever you get without the tests.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Pages: [1] 2 3   Go Up
Jump to: