Hlaf-duplex - what am I doing wrong?

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

Try inserting the line

delay(1);

before this line:

      digitalWrite(rs485XmitPin, HIGH);

It's in the example code of Nick Gammon too and gives the master time to prepare for receiving.

But I don't see the reason for the delayMicroseconds(500) in your code.