Hi,
I'm trying to use my arduino mega ADK to communicate with a pump over RS485 but after 2 weeks of trying to get it going, it still won't respond. I can talk to it via RS232 fine but, due to limitations on the number of RX/TX pins, I need an RS485 bus. I have recently started trying to communicate with another device (compressor) over the RS485 bus but, haven't had any luck there either. The compressor and pump use different protocols so, I'm thinking that it may be a physical issue or due to the port being set up incorrectly.
I've attached a picture of the RS485 part of my schematic. Supply voltage is 5V.
The details:
- I'm using a max487 between the arduino and the devices
- My cable has 2 twisted pairs: one for ground, the other for TX/RX+, TX/RX-
- The cable has a nominal resistance of 120 ohm
- The termination resistors in the pump are used. The manual recommends 120Ohm termination at the other end, which I have.
- Pin 7 on the pumps Sub D connector is TX/RX+, pin 8 is TX/RX-
- Baud rate is 19200
- The voltage levels for the pump are as follows:
Logic 0 - transmitter: 1.5- 5 V, receiver > 0.3V
Logic 1 - transmitter: -1.5- -5 V, receiver <= 0.3V
I have attached a picture of my signal trace It shows the differential signal (Tx/RX+) - (Tx/Rx-)
The communication requires 1 start bit, 1 stop bit, and even parity.
I am initialising the Serial as follows
const unsigned long FOSC = 16000000;// Clock Speed
setup(){
RS485_Init ( 19200 );
pinMode(RTS, OUTPUT);
digitalWrite(RTS,HIGH);
}
void RS485_Init( unsigned long baud){
unsigned int ubrr;
ubrr = (unsigned int)(FOSC/16/baud - 1);
Serial.print("UBRR ");
Serial.println(ubrr);
ubrr &= 0x0FFF; // making sure that the 4 MSBs are 0
// using TX/RXD2
// set character size to 8
// asynchronous normal mode USART
// parity mode to even
UCSR2C = 0;
UCSR2C |= _BV(UPM21) | _BV(UCSZ21) | _BV(UCSZ20);
setEvenParity();
/* Set baud rate */
UBRR2H = (unsigned char)(ubrr>>8);
UBRR2L = (unsigned char)ubrr;
/* Enable receiver and transmitter */
noInterrupts();
UCSR2B = 0;
UCSR2B |= _BV(RXEN2)|_BV(TXEN2) | _BV(RXCIE2);
//UCSR2B &= 0xF8; //write the Reserved Bits in MSPI mode to zero
interrupts();
}
void tp_sendMessage(byte access_type, unsigned int parameterNum, unsigned long paramVal, byte parameterIndex){
//Serial.println("#SEND");
digitalWrite(RTS,HIGH);
setEvenParity();
tp_sentParamNum = parameterNum;
tp_sentParamIndex = parameterIndex;
byte turbopump_message[TURBOPUMP_MESSAGE_LENGTH + 1]; // need length one longer than required to store a NULL so arduino doesnt read over the end of array
tp_makePacket( access_type, parameterNum, parameterIndex, paramVal, turbopump_message);
Serial.print("#SENDING --");
for ( int t = 0; t < TURBOPUMP_MESSAGE_LENGTH; t++){
Serial.print(turbopump_message[t], HEX);
Serial.print(" ");
}
Serial.println("--");
Serial2.write(turbopump_message, TURBOPUMP_MESSAGE_LENGTH);
Serial2.flush();
}
// the turbopump needs even parity and the compressor needs no parity
void setEvenParity(){
// todo ensure nothing is being sent or received
UCSR2C &= B11001111; // clear parity bits
UCSR2C |= B00100000; // set even parity
}
When I look at the signal trace, I can see my signal being sent but, I receive no reply. The tp_makePacket(), tp_sendMessage(), tp_receiveMessage() functions all work over RS232 (with Serial2 exchanged for Serial 3) so I don't think the problem is there.
Do you have any idea what I could be doing wrong? Do you hae any general RS485 trouble shooting tips that may help?
Thanks in advance