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!
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?
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!
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
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);
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
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.
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.
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:
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
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);
}
}
}