RS485

Hi

I am trying to communicate with pic micro controller throw RS485 (115200) , I am receiving and sending data but some times i am loosing data. the reason i am saying data since i monitor the bus from my pc too.

Note 7E7E is missing data (sometime it goes for 10-20 Second)

I think that we are receiving the massage but is too fast (I can not change baud rate of pic MC)

SerialRemote
 7E 5 D BF 4 77 7E
 7E 5 50 7F 4 BF 7E
 7E 5 10 BF 4 52 7E
 7E 5 10 7F 4 39 7E
 7E 5 11 BF 4 84 7E
 7E 5 11 7F 4 EF 7E
 7E 5 12 BF 4 F9 7E
 7E 5 16 7F 4 92 7E
 7E 5 13 BF 4 2F 7E
 7E 5 17 7F 4 44 7E
 7E 5 1C BF 4 3 7E
 7E 5 18 7F 4 68 7E
 7E 5 1D BF 4 D5 7E
 7E 5 1D 7F 4 BE 7E
 7E 41 F4 23 A8 7E
 7E 6 3D BF 4 C3 7E
 7E 6 3E BF 4 7E
 7E 7E
 7E 7E   
 7E 7E
 7E 7E
 7E 7E
 7E 7E
 7E 7E
 7E 7E
 7E 7E
 7E 7E
 7E 7E
 7E 7E
 7E 7E
 7E 7E
 7E 7E
 7E 7E
  .
  .
 7E 7E
 7E 7E
 7E 7E
 7E 7E
 7E 7E
 7E 7E
 7E 7E
 7E 7F 5 36 BF 4 6C 7E

my code is messy since I working on this for while and I can not figure this out.

/*-----( Import needed libraries )-----*/
#include <SoftwareSerial.h>
/*-----( Declare Constants and Pin Numbers )-----*/
#define SSerialRX        10  //Serial Receive pin
#define SSerialTX        11  //Serial Transmit pin

#define SSerialTxControl 3   //RS485 Direction control
#define RS485Transmit    HIGH
#define RS485Receive     LOW



/*-----( Declare objects )-----*/
SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX

/*-----( Declare Variables )-----*/

bool waitForFirst = true;
byte delimiter = 0x7E;
const byte maxMessage = 100;
byte message[maxMessage];
byte mPos = 0;
int timec;
int first_time = 0 ;
byte   uid1 = 0x9C;
byte   uid2 = 0x18;
byte  device_address;
int jet_on = 0;
char receivecommand  = 0;
unsigned long times;
int device_return = 0;
byte  msgOut[] = {0x7E, 0x08, 0xFE, 0xBF, 0x01, 0x00, uid1, uid2, 0x65, 0x7E};

void setup()   /****** SETUP: RUNS ONCE ******/
{
  // Start the built-in serial port, probably to Serial Monitor
  Serial.begin(115200);
  Serial.println("SerialRemote");  // Can be ignored
  pinMode(SSerialTxControl, OUTPUT);
  digitalWrite(SSerialTxControl, LOW);  // Init Transceiver
  // Start the software serial port, to another device
  RS485Serial.begin(115200);   // set the data rate
}//--(end setup )---


void loop() {

  if (Serial.available() > 0) {    // is a character available?

    receivecommand = Serial.read();
    if (receivecommand == '1'  or receivecommand == '2' ) {
      //Serial.println(receivecommand);
    } else {
      receivecommand  = 0 ;
    }
  }

  if (RS485Serial.available()) {

    byte val = RS485Serial.read();

    if (waitForFirst) {
      if (val == delimiter) {
        addToBuffer(val);
        waitForFirst = false;
      }
    } else if (val == delimiter) {

      addToBuffer(val);
      processMessage(message, mPos);
      mPos = 0;
      waitForFirst = true;
    } else {
      addToBuffer(val);
    }
  }



}

void addToBuffer(byte val) {
  if (mPos < maxMessage) {
    message[mPos++] = val;

  }
}


void processMessage(byte* values, byte len) {

 // if (values[2] == device_address) {
    for (byte i = 0; i < len; i++) {
      Serial.write(' ');
      Serial.print(values[i], HEX);
    }
    Serial.println();

  //}


  //
  //  Serial.println(F("'"));
  //  Serial.print(F("in dec "));
  //  for (byte i = 0; i < len; i++) {
  //    Serial.write(' ');
  //    Serial.print(values[i]);
  //  }
  //  Serial.println();
  //  Serial.print(F("in hex "));
  //  for (byte i = 0; i < len; i++) {
  //    Serial.write(' ');
  //    Serial.print(values[i], HEX);
  //  }
  //  Serial.println();



  if (values[1] == 5 && values[2] == 254 && values[3] == 191 && values[4] == 0  && first_time == 0 ) {
    // if (values[4] == 0  && first_time == 0 ) {
    for (byte i = 0; i < len; i++) {
      Serial.write(' ');
      Serial.print(values[i]);
    }
    Serial.println();

    digitalWrite(SSerialTxControl, RS485Transmit);  // Enable RS485 Transmit

    for (int i = 0; i < sizeof(msgOut); i++) {
      RS485Serial.write(msgOut[i]); // Send the byte back

    }
    Serial.println("-------------------SEND---------------------------");
    RS485Serial.flush();
    digitalWrite(SSerialTxControl, RS485Receive);  // Disable RS485 Transmit

  }
  //  uid1 = 0x9C, 156
  //  uid2 = 0x18, 24

  if ( values[4] == 2   && values[6] == 156  && values[7] == 24) {
    first_time = 1;
    for (byte i = 0; i < len; i++) {
      Serial.write(' ');
      Serial.print(values[i]);
    }
    Serial.println();


    times = millis();
    Serial.println("-------------------GOT IT---------------------------");
    device_address = values[5];
    byte Address_Assignment[] = {0x7E, 0x05, device_address, 0xBF, 0x03, 0x47, 0x7E};


    digitalWrite(SSerialTxControl, RS485Transmit);  // Enable RS485 Transmit
    delay(5);

    for (int g = 0; g < sizeof(Address_Assignment); g++) {
      RS485Serial.write(Address_Assignment[g]); // Send the byte back

    }
    RS485Serial.flush();
    digitalWrite(SSerialTxControl, RS485Receive);  // Disable RS485 Transmit
    Serial.println("-------------------SEND---------------------------");
    Serial.println(device_address, HEX);

  }



  if ( values[2] == device_address && values[4] == 4  ) {
    device_return = 1;
    Serial.println("-------------------Controller Device Present Query---------------------------");
    for (byte i = 0; i < len; i++) {
      Serial.write(' ');
      Serial.print(values[i]);
    }

    Serial.println();



  }







  if (values[1] == 5 && values[2] == device_address && values[3] == 191 && values[4] == 6 ) {
    device_return = 1;

    //
    //    for (byte i = 0; i < len; i++) {
    //      //Serial.write(' ');
    //      //Serial.print(values[i]);
    //    }
    //  Serial.println();
    if (receivecommand == '1') {
      receivecommand = 0;
      byte Device_Poll_Anknowledge[] = {0x7E, 0x06, device_address, 0xBF, 0x17, 0x04, 0x67, 0x7E};
      digitalWrite(SSerialTxControl, RS485Transmit);  // Enable RS485 Transmit
      for (int c = 0;  c < sizeof(Device_Poll_Anknowledge); c++) {
        RS485Serial.write(Device_Poll_Anknowledge[c]); // Send the byte back

      }
      Serial.println("-------------------SEND Command---------------------------");
      digitalWrite(SSerialTxControl, RS485Receive);  // Disable RS485 Transmit


    } else if (receivecommand == '2') {

      digitalWrite(SSerialTxControl, RS485Transmit);  // Enable RS485 Transmit

      RS485Serial.write("Lights = Medium\r\n"); // Send the byte back

      Serial.println("-------------------SEND Command---------------------------");
      digitalWrite(SSerialTxControl, RS485Receive);  // Disable RS485 Transmit

    } else {

      byte Device_Poll_Anknowledge[] = {0x7E, 0x06, device_address, 0xBF, 0x17, 0x00, 0x7B, 0x7E};
      digitalWrite(SSerialTxControl, RS485Transmit);  // Enable RS485 Transmit
      for (int c = 0;  c < sizeof(Device_Poll_Anknowledge); c++) {
        RS485Serial.write(Device_Poll_Anknowledge[c]); // Send the byte back

      }
      Serial.println("-------------------Device POLL Nothing to Send---------------------------");
      digitalWrite(SSerialTxControl, RS485Receive);  // Disable RS485 Transmit


    }


  }








}
  1. Which Arduino?

  2. 115200 seems a bit fast for software serial. It is not going to work reliably at that speed on the slower Arduinos. Can you put the 115200 on the hardware serial and communicate with the next thing in the line at a slower speed?

  3. I’m not sure about SoftwareSerial but a hardware Serial.flush() can’t be followed immediately by the disable command for the RS485 transmitter. flush() will wait until all characters have been sent to the outgoing hardware serial buffer, which is 1 character long. So you need to call flush() and then wait for one more character transmission time. This will trip you up when you eventually move on to a more capable Arduino that has more hardware serial capabilities.

Hi,
Have you got terminating resistor in the correct place?

Tom… :slight_smile:

  1. I try on both Uno and Mega same thing

  2. I can not change PIC controller Baud rate so Software serial, or Serial1 have to be at 115200 but I can change serial (viewing) baud rate to any thing else.

are you trying with longer buffer?
example maxMessage=200

Yes I even put 500 Same thing

MorganS:

  1. Which Arduino?

  2. 115200 seems a bit fast for software serial. It is not going to work reliably at that speed on the slower Arduinos. Can you put the 115200 on the hardware serial and communicate with the next thing in the line at a slower speed?

  3. I'm not sure about SoftwareSerial but a hardware Serial.flush() can't be followed immediately by the disable command for the RS485 transmitter. flush() will wait until all characters have been sent to the outgoing hardware serial buffer, which is 1 character long. So you need to call flush() and then wait for one more character transmission time. This will trip you up when you eventually move on to a more capable Arduino that has more hardware serial capabilities.

  1. Arduino Mega
  2. I tried same thing still missing data (missing Flags, or data is shorten what suppose to be)
  3. I am not sending anything, all I am doing receiving data and process it

Hi,
Answer Post #2 please.

Thanks.. Tom.. :slight_smile:

TomGeorge:
Hi,
Answer Post #2 please.

Thanks.. Tom.. :slight_smile:

I ma using Arduino Mega with MAX485 shield such as linke below, I can not change any resistance

http://yourduino.com/sunshop//index.php?l=product_detail&p=323

Also I am only trying to receive data, and analyze it.

Hi
Have you included the 120R?


Tom.. :slight_smile:

Yes I did but same thing I even change my code to hardwareserial got little better but still missing flags, or data are short

7E510BF65C7E //Raw data
 7E 5 10 BF 6 5C 7E--  //Process data
510BF65C7E7E // as you can see we are missing the 7E flag to start 

 7E 7E-- //Process data is wrong it should be 7E 5 10 BF 6 5C 7E

I dont think that we are missing in data it just we can not process it that fast look at below result with out any processing:

7EC
7E
7E510BF75B
7E
7E510BF65C
7E
7E510BF75B
7E
7E510BF65C
7E
7E510BF75B
7E
7E510BF65C
7E
7E510BF75B
7E
7E21FFAF2300
7E
7E5
7E
7E
7E
7E510BF65C
7E
7E510BF75B
7E
7E510BF65C
7E
7E510BF75B
7E
7E510BF65C
7E
7E510BF75B
7E
7E510BF65C
7E
7E510BF75B
7E
7E510BF65C
7E
7E
7E
7E
7E
7E
7E
7E
7E5
7E
7E
7E5
7E
7E
7E21
7E
7E
7E5
7E
7E
7E5
7E
7E
7E5
7E
7E
7E
7E
7E
7E
7EBF
7E
7E
7E
7E5
7E
7E
7E5
7E
7E1C
7E
7E
7E
7E5
7E
7E
7E5
7E
7E
7E5
7E
7E
7E6
7E
7E
7E10
7E
7E
7E
7E5
7E
7E
7E5
7E
7E5C
7E510BF65C
7E
7E510BF75B
7E
7E510BF65C
7E
7E510BF75B
7E
7E510BF65C
7E
7E510BF75B
7E
7E510BF65C
7E
7E510BF75B

115200 baud is 115200 bits per second. That's 11520 bytes per second.

A 16MHz Arduino can do 16,000,000 instructions per second. That's about 1388 instructions per arriving byte. That's not a whole lot but it is also not bad. Your code in the original post doesn't use this many instructions to process each byte.

MorganS:
115200 baud is 115200 bits per second. That’s 11520 bytes per second.

A 16MHz Arduino can do 16,000,000 instructions per second. That’s about 1388 instructions per arriving byte. That’s not a whole lot but it is also not bad. Your code in the original post doesn’t use this many instructions to process each byte.

I removed the process part of it since it was too large. I get data in an array then I have to check for the result. But the problem I am not able to read it correctly, as you see sometimes Flag “7E” is missing,

But Let assume all I do I print it

 for (byte i = 0; i < len; i++) {
 Serial.write(' ');
 Serial.print(values[i],HEX);
 }
Serial.println();

How does that fragment fit with the rest of your code?

What does the output look like? (Please highlight discrepancies - we don't want to look at a thousand lines of output for a subtle error.)