I want to use a BOB-10124 RS-485 to let my Arduino Mega 2560 communicate with a peripheral (industrial) RS-485 device. But no matter what I do though, the resulting RS-485 output is gibberish.
Below is a minimal working code to reproduce the error. The board is connect to an RS485-to-USB (FTDI) hub. I’ve verified that the hub works well, same with the Serial ports on the Arduino.
The output that I receive with this code is gibberish: <0>^HIIO¤S^ž (or in HEX: 00 5E 48 49 49 4F A4 53 5E 9E).
Since it is always the same string, it feels like a timing error. The baud rate is correct though and altering it does not result in a readable string. Adding a 1 ms delay after Serial1.flush() to allow the chip’s buffer to empty before pulling the RTS low again, made no difference. I also tried a 10k resistor on the RTS-pin (as suggested elsewhere on the forum), also no solution.
Both a used BOB-10124 and a brand-new one show this strange behaviour. I have used this code previously with an ADM485 chip and that worked flawlessly. It must be something with this particular SP3485 chip that I’m missing.
Any thoughts on this? Thanks!
Edit: and now some really weird behaviour… I played around with the delays and switching the RTS-pin.
Without the delay after Serial1.flush() my terminal software continuously indicates a frame error. With this delay, the message is still corrupted though.
Altering the first delay - between setting the RTS-pin and writing the message - does not change the string I receive either. But when I remove this delay altogether, the received message is different.
Can anyone still make sense of this?
#include<Arduino.h>
const uint16_t buffersize = 1024;
const uint8_t RTS = 2;
uint32_t currTime;
uint32_t prevTime;
char data[buffersize];
char cmd[65];
//The setup function is called once at startup of the sketch
void setup()
{
Serial1.begin(115200);
pinMode(RTS, OUTPUT);
digitalWrite(RTS, LOW);
prevTime = millis();
}
// The loop function is called in an endless loop
void loop()
{
currTime = millis();
// Send data once per second
if (currTime - prevTime >= 1000) {
prevTime = currTime;
// Send command
strcpy(cmd, "Command\r");
Send(cmd, data);
}
}
void Send(const char *cmd, char *ret) {
// use default send function
sendCommand(cmd);
// receive answer
size_t bytes = Serial1.readBytesUntil('\r', ret, buffersize-1);
// NULL-terminate to convert to string
ret[bytes] = '\0';
// debug: can be accessed from caller
//strcpy(debugString, ret);
}
/*sendCommand(...)******************************************************************************
* General function that sends command to RS485 peripheral device
* <CR> is added to all commands
* For RS485 communication, RTS pin has to be HIGH to allow writing to peripheral
**********************************************************************************************/
void sendCommand(const char *cmd) {
char tmp[32] = "";
strcat(tmp, cmd);
strcat(tmp, "\r"); // Add <CR>
digitalWrite(RTS, HIGH); // set RTS to HIGH to allow writing to MAX485
delay(1);
Serial1.print(tmp); // send command
Serial1.flush(); // Make sure message is fully transferred
//delay(1);
digitalWrite(RTS, LOW); // set RTS to LOW to receive answer
}