-
You're already using hardware serial. Serial3 is one of the hardware serial ports on a MEGA. The #include at the top can be removed with no adverse effects.
-
Don't use a while() here. You will get stuck waiting for the end character to arrive. Just follow Robin's examples which add characters to the buffer when they arrive and then send the buffer out to be processed after the end is detected.
-
Up until a year or two ago, the description for serialEvent() used to say that it worked like an interrupt. It doesn't. It never did. It was planned to eventually work that way but it turned out to be unnecessary. It really makes no difference if you use it or not.
Try this...
#define SSerialTxControl 3 // Pin for MAX485 - HIGH send, LOW receive
const int RXBuffLength = 64; //expect all incoming messages to be shorter than this
int byteReceived;
int rx_buff[RXBuffLength];
int rx_length = 0;
boolean stop_byte = false;
void setup()
{
Serial.begin(57600); //Serial communication for USB.
Serial3.begin(57600); //Serial communication for RS48 - 14 pin as Tx and 13 pin as Rx.
pinMode(SSerialTxControl, OUTPUT);
digitalWrite(SSerialTxControl, LOW); //Just receive data from RS485
}
void loop()
{
if (Serial3.available()) //When you receive some data save it into the rx_buff[] variable
{
rx_buff[rx_length] = Serial3.read();
if (rx_buff[rx_length] == 0xDD) stop_byte = true; //if the last byte received is equal to 0xDD then we know we have a finished message
rx_length++;
if (rx_length > RXBuffLength) rx_length = 0; //if we ran off the end of the buffer, reset back to the start (discard the data already collected)
}
if (stop_byte)
{
//we have received a valid message with a terminating character
stop_byte = false;
if (rx_buff[0] != 0x00)
{
assertSerial3Tx();
for (int i = 0; i < rx_length; i++)
{
Serial.write(rx_buff[i]); //Then just send it one by one through USB to the PC
Serial3.write(rx_buff[i]); //And also send the data through RS485 to "Amap99"
}
}
rx_length = 0;
}
deAssertSerial3Tx();
}
unsigned long lastSerial3Transmit;
void assertSerial3Tx() {
digitalWrite(SSerialTxControl, HIGH); // Get ready for sending data
lastSerial3Transmit = millis();
}
void deAssertSerial3Tx() {
//check if we can de-assert the Tx control
static int highWaterMark = 0;
const unsigned long TransmitHoldTime = 3; //milliseconds - the amount of time to hold TxControl after the last byte leaves the buffer. Use 1 for 115200, 5 for 19200, 16 for 9600
if(Serial3.availableForWrite() < highWaterMark)
{
lastSerial3Transmit = millis();
}
else
{
highWaterMark = Serial3.availableForWrite();
if(millis() - lastSerial3Transmit > TransmitHoldTime)
{
//no longer transmitting
digitalWrite(SSerialTxControl, LOW);
}
}
}
The significant differences to your code are:
A) It doesn't get stuck in a while() loop forever waiting for a character which may never come.
B) It won't overrun the end of the buffer if it gets characters which are not the ones it's looking for.
C) You can't just delay(10) and hope that all the characters were sent. That won't even cover 1 character at 9600 baud. I put in a totally different system which looks at the outgoing buffer and turns off the Tx control a few milliseconds after the last character is sent.