I am using two arduino pro minis. I need to get reliable MAX485 comms through them. For this I am using gammon's RS485_protocol library:
I can get reliable one way communication. I can even get half of the conversation:
Master query
Slave receipt
Slave response
Master fails to receive
I must be doing something wrong with the half-duplex. I've established that it's not hardware, all the pieces work individually; see code samples below.
Does anyone have working half-duplex comms through a MAX485 chip that I can crib? This is driving me NUTS!
Test send:
#include <AltSoftSerial.h>
#include <RS485_protocol.h>
AltSoftSerial rs485;
byte msg[3] = {'h', 'E', 'L'};
// callback routine'
void fWrite (const byte what)
{
rs485.write (what);
}
int fAvailable ()
{
return rs485.available ();
}
int fRead ()
{
return rs485.read ();
}
void setup() {
Serial.begin(9600);
Serial.println("AltSoftSerial Send Test Begin");
rs485.begin(9600);
}
void loop() {
delay(1000);
digitalWrite(13,HIGH);
delayMicroseconds(500);
sendMsg (fWrite, msg, sizeof msg);
rs485.flush();
digitalWrite(13, LOW);
}
Test receipt:
#include <AltSoftSerial.h>
#include <RS485_protocol.h>
AltSoftSerial rs485;
void fWrite (const byte what)
{
rs485.write (what);
}
int fAvailable ()
{
return rs485.available ();
}
int fRead ()
{
return rs485.read ();
}
void setup() {
Serial.begin(9600);
Serial.println("AltSoftSerial Receive Test Begin");
rs485.begin(9600);
}
void loop() {
char c;
byte buf[32];
c=0;
buf [0] = 5;
int i,j;
if(i=recvMsg(fAvailable, fRead, buf, sizeof buf,900))
for (j = 0 ; j < i; j++) Serial.println(buf[j]);
else Serial.println("nnothing receivd");
}
Now put it together - first the master:
#include <AltSoftSerial.h>
#include <RS485_protocol.h>
AltSoftSerial rs485;
// callback routines
void fWrite (const byte what)
{
rs485.write (what);
// rs485.flush();
}
int fAvailable ()
{
return rs485.available ();
}
int fRead ()
{
return rs485.read ();
}
void setup()
{
Serial.begin(9600);
rs485.begin (9600);
pinMode(rs485XmitPin, OUTPUT);
digitalWrite(rs485XmitPin, LOW);
} // end of setup
byte msg [1];
byte buf [32];
void loop()
{
byte i;
Serial.print("querying slave ");
Serial.println(i);
msg [0] = 5;
digitalWrite(rs485XmitPin, HIGH);
delayMicroseconds(500);
sendMsg (fWrite, msg, 1);
rs485.flush();
digitalWrite(rs485XmitPin, LOW);
//**********************************
// this never succeeds
//**********************************
// there is never any data in the serial buffer
//**********************************
if (!recvMsg (fAvailable, fRead, buf, sizeof buf, 1000)) {
Serial.print("no response from Slave ");
Serial.println(i);
}
}
}
The slave does send out the data; I can receive it with the simpler test above. It's only when the master sends the query that the subsequent read fails.
Slave
#include <AltSoftSerial.h>
#include <RS485_protocol.h>
AltSoftSerial rs485;
// callback routines
void fWrite (const byte what)
{
rs485.write (what);
}
int fAvailable ()
{
return rs485.available ();
}
int fRead ()
{
return rs485.read ();
}
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
rs485.begin(9600);
pinMode(rs485XmitPin, OUTPUT);
digitalWrite(rs485XmitPin, LOW);
address = 5;
}
byte buf [32];
void loop() {
// this succeeds
if (recvMsg (fAvailable, fRead, buf, 19))
{
if (buf [0] != address) {
Serial.print(buf[0]);
Serial.println(" not mine, skipping.");
}
else {
Serial.println("got a query");
digitalWrite(rs485XmitPin, HIGH);
delayMicroseconds(500);
buf[0]=23;
sendMsg (fWrite, buf, 1);
rs485.flush();
digitalWrite(rs485XmitPin, LOW);
Serial.println("Sent response");
}
}
else {
Serial.println("No query received");
};
} // end if something received