Pages: [1]   Go Down
Author Topic: Serial send and receive - timing or coding issue?  (Read 598 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,

I've been struggling with this for quite a while, so I'm hoping for a few clues. The following is just a simplified test I'm running. I've got 2 Arduinos communicating via hardware serial, and sharing pretty much the same code (see below). In principle the master sends 111 then waits for a response (112 from slave). Yet even though the enable pins (I'm using RS485) are set low on the slave, no value seems to be getting through. I've added a delay on the slave before it sends a response, so the master has time to bring the enable pin low; 300 ms, maybe too long?

I've tested the Arduinos with two other sketches designed to just send a byte array from master to slave, and that works (the slave prints a confirmation response). It works when I reverse the roles too, so I'm guessing this has to do with the high/low timing on the enable pins.

Any help would be vastly appreciated, I'm trying to complete an art installation by the end of August. Thank you so much!

MASTER

Code:

const int pinEnable = 2;
byte hello = 111;
byte inRead = 0;
boolean received = true;

void setup ()
{
  pinMode(pinEnable,OUTPUT);
   Serial.begin(57600);
}

void check () {
  digitalWrite(pinEnable, LOW);
  inRead = Serial.read();
  if (inRead == 112) {
    received = true;
  }  
}
  
void loop() {
  check();
  if (received == true) {
    Serial.write(inRead);
    digitalWrite(pinEnable, HIGH);
    Serial.write(hello);
    digitalWrite(pinEnable, LOW);
    received = false;
  }
}


----------------------------------

SLAVE

Code:

const int pinEnable = 2;
byte helloBack = 112;
byte inRead = 0;
boolean received = true;

void setup ()
{
  pinMode(pinEnable,OUTPUT);
   Serial.begin(57600);
}

void check () {
  digitalWrite(pinEnable, LOW);
  inRead = Serial.read();
  if (inRead == 111) {
    received = true;
  }  
}
  
void loop() {
  check();
  if (received == true) {
    delay(300);
    Serial.write(inRead);
    digitalWrite(pinEnable, HIGH);
    Serial.write(helloBack);
    digitalWrite(pinEnable, LOW);
    received = false;
  }
}




« Last Edit: July 25, 2012, 04:14:02 pm by inoukdemers » Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 208
Posts: 8842
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How are the two connected?  What RS485 buffer are you using?  Are the grounds connected?
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm using two MAX485s (CPA1121) between the Arduinos, each grounded to their respective Arduino (the setup is described here: http://www.gammon.com.au/forum/?id=11428 )

With prior sketches this was working fine. I suspect it's more of a code issue. Do you see anything wrong on that end?
« Last Edit: July 25, 2012, 03:48:28 pm by inoukdemers » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Anyone?
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 208
Posts: 8842
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You should take out the lines where you send inRead before you enable the transmitters.
Code:
    Serial.write(inRead);    ///////// Get rid of this line
    digitalWrite(pinEnable, HIGH);
    Serial.write(hello);
    digitalWrite(pinEnable, LOW);

You can probably take the pinEnable line out of check() an put it in setup() since it only has to be done once.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey John,

Absolutely, I was being redundant largely out of paranoia.

In the meantime, your initial hunch was right. I added a second pair of 620 Ohm resistors on the slave-end MAX485, and it did the trick! The Gammon diagram only showed one pair. Thanks for putting the bug in my ear!

I also simplified the code. Here it is:

MASTER

Code:

const int pinEnable = 2;
byte hello = 111;

void setup()
{
  pinMode(pinEnable,OUTPUT);
   Serial.begin(57600);
}
  
void loop() {
  digitalWrite(pinEnable, LOW);
  byte inRead = Serial.read();
  if (inRead = 112) {
    Serial.write(inRead);
    delay(500);
    digitalWrite(pinEnable, HIGH);
    delay(1);
    Serial.write(hello);
    digitalWrite(pinEnable, LOW);
  }
}


SLAVE

Code:

const int pinEnable = 2;
byte helloBack = 112;

void setup()
{
  pinMode(pinEnable,OUTPUT);
   Serial.begin(57600);
   digitalWrite(pinEnable, HIGH);
   Serial.write(helloBack);
   digitalWrite(pinEnable, LOW);
}
  
void loop() {
  byte inRead = Serial.read();
  if (inRead = 111) {
    delay(500); // adjust this delay as needed
    digitalWrite(pinEnable, HIGH);
    delay(1); // give time for master to go LOW
    Serial.write(helloBack);
    digitalWrite(pinEnable, LOW);
    }
}

« Last Edit: July 25, 2012, 06:01:42 pm by inoukdemers » Logged

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

Quote
each grounded to their respective Arduino
But there also needs to be a GND connection between the two. You are probably getting away with it now because the two Arduinos are running of the same PC or something and therefore getting a similar/same GND but if your intention is to have them more independent you need the third wire.

Technically Nick's schematic is correct but for newbies I think it should show the third wire to make it obvious.

If your Arduinos are close together and/or the bit rates are slow I don't see why you needed the extra resistors, in fact they are failsafe resistors not terminating resistors . But I won't argue with success smiley

EDIT:

In the slave setup() function you have this

Code:
digitalWrite(pinEnable, HIGH);
Serial.write(helloBack);
digitalWrite(pinEnable, LOW);

As there's no delay I doubt that byte ever sees the light of day.

ANOTHER EDIT:

Code:
    digitalWrite(pinEnable, HIGH);
    delay(1);
    Serial.write(hello);
    digitalWrite(pinEnable, LOW);

Same problem, the delay should be after the write().

Are you sure this code is working smiley Have you verified that the master actually sees the return byte?

_____
Rob
« Last Edit: July 25, 2012, 07:16:48 pm by Graynomad » Logged

Rob Gray aka the GRAYnomad www.robgray.com

Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Graynomad, I'm glad you mentioned that.

Just to make sure I understand what you mean by "third wire":

I have a 2-wire + ground (threaded wire) cable at home I planned on using. I guess I would connect two of the wires to A & B on the MAX485, but then would the receive enable pin connect to GND on the Arduino, whereas the actual GND pin on MAX485 would connect back to the master via the cable?

Also, whereas with the above sketches I could easily send bytes back to the master, when I change the sketch to use analogRead() (read as an int, then converted to byte), it doesn't read correctly on the master end - it always reads 255:

SLAVE:

int sensor = analogRead(A0)/4;
Serial.write((byte)sensor);

MASTER:

byte inRead = Serial.read();
  if (inRead > 0) {
    Serial.print(inRead, DEC);
}


« Last Edit: July 25, 2012, 07:10:42 pm by inoukdemers » Logged

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

Short answer, ALL grounds should be connected together, that cable should be good, use the "third wire" to connect the grounds at both ends.

The MAX485 RE pins at both ends should be pulled low (grounded) as well.

Code:
byte inRead = Serial.read();
  if (inRead > 0) {
    Serial.print(inRead, DEC);
}

This is wrong, you should wait for a character to be available then read it. As it is the Serial.read() is returning -1 (no characters to read) which happens to be 0xFF or 255. Try

Code:
byte inRead;
  if (Serial.available() > 0) {
    inRead = Serial.read();
    Serial.print(inRead, DEC);
}

______
Rob
« Last Edit: July 25, 2012, 08:26:24 pm by Graynomad » Logged

Rob Gray aka the GRAYnomad www.robgray.com

Anaheim CA.
Offline Offline
Faraday Member
**
Karma: 47
Posts: 2891
...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The device to device grounds must be in place for a reference for the '485 serial differential data transfer, what if there were a 10 to 20 volt differential in the local grounds (Very Possible) now the question is without that ground... Referenced to what? and since the Max485 shares the same power supply as the Arduino again the ground from the '485 device is necessary so the Arduino can read/write to the device. It must also be explained that the ground is usually not explained but rather explicit. We all that use RS485 regularly Assume the ground rather that explain what is to us obvious. I hope this helps.

Doc
Logged

--> WA7EMS <--
“The solution of every problem is another problem.” -Johann Wolfgang von Goethe
I do answer technical questions PM'd to me with whatever is in my clipboard

Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Graynomad,

I just read your edit, and indeed, I'm realizing the value I'm apparently getting back on the Master is a phantom. If I try incrementing the sent value from the slave, I see on the master that it doesn't change; d'oh!

I'll set the delay so it's after the write function and see what happens.

Docedison, I don't know who this 'we that use RS485' is, but to a non-engineer artist, let me tell you, the ground issue is not obvious at all! I'm a big fan of explicit ;-) But your point is well taken.
« Last Edit: July 25, 2012, 10:45:52 pm by inoukdemers » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, the code below works, since the incremented values on the slave are being received by the master. I have to reset the slave to get the thing going, and oddly enough when I open Serial Monitor on the master the thing stops(!) But at least I know the data is coming in correctly. I also made sure the RE and GND pins from the slave MAX485 were connected to the master Arduino's GND. That tip on placing the delay after the write function was awesome! Thanks again guys.

Here's the code:

Code:
const int pinEnable = 2;
byte hello = 111;
byte inRead;

void setup()
{
  pinMode(pinEnable,OUTPUT);
   Serial.begin(57600);
}
 
void loop() {
  digitalWrite(pinEnable, LOW);
  if (Serial.available() > 0) {
    inRead = Serial.read();
  if (inRead >= 112) {
    Serial.println(inRead, DEC);
    delay(500);
    digitalWrite(pinEnable, HIGH);
    Serial.write(hello);
    delay(10); // delay should be AFTER the write
    digitalWrite(pinEnable, LOW);
  }
}
}

SLAVE

Code:
const int pinEnable = 2;
byte helloBack = 112;
byte inRead;

void setup()
{
  pinMode(pinEnable,OUTPUT);
   Serial.begin(57600);
   digitalWrite(pinEnable, HIGH);
   Serial.write(112);
   delay(10);
   digitalWrite(pinEnable, LOW);
}
 
void loop() {
  if (Serial.available() > 0) {
  inRead = Serial.read();
  if (inRead == 111) {
    helloBack += 1;
    Serial.println(inRead, DEC);
    delay(500); // adjust as needed
    digitalWrite(pinEnable, HIGH);
    Serial.write(helloBack);
    delay(10); // give time for master to go LOW
    digitalWrite(pinEnable, LOW);
    }
}
}
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 208
Posts: 8842
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

oddly enough when I open Serial Monitor on the master the thing stops(!)

Starting Serial Monitor, like starting an Upload, resets the Arduino.

Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Good to know, thanks John.
Logged

Pages: [1]   Go Up
Jump to: