Software Serial used on Arduino UNO R3 convert to Mega 2560 Hardware Serial

Hi guys,
Theses days I'm working on a project which uses two RS485 network to communicate with other equipments. (a microcontroller controlled Step Motor and a weight transmitter). I wrote the code, That works perfectly on UNO. Problem till now is just some how like this: When I use Software Serial on UNO, the two network can't through changing the listening port to get the right value. Now I've changed my board to mega 2560. I can't even get the right value from each network correctly, which worked always on UNO with Software Serial. Cause the whole project is relative huge, I just put a modified small part about reading the weight transmitter's value here:

#include <SoftwareSerial.h>
SoftwareSerial RS485_Serial(4, 5);

int SignGewicht[3];
int Gewicht[3];

int RS485_text;
int RS485_SwitchPin = 8;

long time;

int UpdateZero = 1;

int WaageID = 0;

void setup(){
    RS485_Serial.begin(38400);
    Serial.begin(19200);
    Serial.println("Start");
    time = millis();
    pinMode(RS485_SwitchPin, OUTPUT);
    digitalWrite(RS485_SwitchPin, LOW);
}


void loop(){

  if (UpdateZero == 1){
    digitalWrite(RS485_SwitchPin, HIGH); 
    RS485_Serial.write("$01ZERO03\r");
    digitalWrite(RS485_SwitchPin, LOW);
    UpdateZero = 0;
  }
  
//---Routine------------------------------------------------------
    
  if (millis()-time > 100){ 
     digitalWrite(RS485_SwitchPin, HIGH); 
     RS485_Serial.write("$01t75\r"); 
     digitalWrite(RS485_SwitchPin, LOW);
//   Serial.write("\n");
     time = millis();
  }
 
 
  if (RS485_Serial.available()){
   WaageEinlesen();
   //Serial.write(RS485_Serial.read());
  }
}




void WaageEinlesen(){
      if (RS485_Serial.available()==14){
       if (RS485_Serial.read()==38){
         WaageID = ((RS485_Serial.read()-48)*10);              //10er Stelle ID
         WaageID = WaageID + (RS485_Serial.read()-48);         // 1er Stelle ID 
         
         SignGewicht[WaageID] = RS485_Serial.read();           //"-" bei negativem Wert, "0" bei positivem
             if (SignGewicht[WaageID] == 32){
               Serial.println("Gewicht zu hoch!");
                      while (RS485_Serial.available()){
                      RS485_text = RS485_Serial.read();
                      }
               return;
               }
             else if (SignGewicht[WaageID] == 45) SignGewicht[WaageID] = -1;
             else SignGewicht[WaageID] = 1;
         
         Gewicht[WaageID] = ((RS485_Serial.read()-48)*10000);
         Gewicht[WaageID] = Gewicht[WaageID]+((RS485_Serial.read()-48)*1000);
         Gewicht[WaageID] = Gewicht[WaageID]+((RS485_Serial.read()-48)*100);
         Gewicht[WaageID] = Gewicht[WaageID]+((RS485_Serial.read()-48)*10);
         Gewicht[WaageID] = (Gewicht[WaageID]+((RS485_Serial.read()-48)))*SignGewicht[WaageID];
         Serial.println(Gewicht[WaageID]);
         }
       } 
       else{
          Serial.println("ERROR Serial Read");
          }
        
       while (RS485_Serial.available()){
       RS485_text = RS485_Serial.read();
       }
}

P.S. Yeh, the communication mode is "Ask & Answer."

How can solve the problem. Is the problem only on the code or I've to change some hardware configuration to make it works?

Thank you!

Cause the whole project is relative huge, I just put a modified small part about reading the weight transmitter's value here:

How about if I post just a small part of the answer? That wouldn't be sufficient, would it? Post ALL of your code, as an attachment, using the Additional Options... link if necessary.

Of course, if you really have a problem with two devices exchanging serial data, there is no reason to have a relatively huge program to illustrate that. Create a small sketch that illustrates the problem.

Next, if the problem is exchanging data, you need to post the code for both ends of the link. If these snippets are from the code for the Mega, you need to pay attention to the documentation for the SoftwareSerial class, especially the note about which pins can be used on the Mega.

Finally, you have 4 hardware serial ports on the Mega. Why do you need to use SoftwareSerial, too?

Paul, thank you really so much for your answer.
Last time I have a very bad mood, so I haven't give you the sufficient info about the project.
As you say, I tried to rewrite a small snippet, which have only one function - Send a command to the weight transmitter to let it reset itself to zero. If the command is correctly received, weight transmitter should answer:&&01!ckck(the from XOR calculated value)\r, if the command is not correctly received, it will answer: &&01?ckck\r
The result: Through the code I can't set Zero, and I can't get a normal answer through Serial1 port.
And I attach a screen shot from the Serial monitor and the whole code of the project. Hope if someone can tell me where is the problem.

Thanks.

/*Purpose: Small example show how to use Serial1 on Arduino Mega 2560 to send command to 
 *the weight transmitter.
 *Board: Arduino Mega 2560 R3
 *RS-485 chip: TI SN75176BP (working on 4.85V)
 *weight transmitter: Laumas WTB Analog (communicate through RS-485, addressee:01,
 *Speed:19200, delay:0, stop:1, Parity:no)
 *Connection: Mega's PIN19 to RS-485's PIN1, M's 18 to R's 4, M's 8 to R's 2&3
 *RS-485's PIN6 to weight Transmitter's +RS-485, R's PIN7 to W's -RS-485
 *RS-485's PIN5 to GND, RS-485's PIN8 to VCC(Arduino 5V)
 */

int chipDriver = 8; //This PIN drives the RS-485 chip's mode. HIGH=="send" LOW=="Recieve" 

void setup()
{
	Serial.begin(19200);
	Serial1.begin(19200); //This is the Serial port connected to the weight transmitter.
	pinMode(chipDriver,OUTPUT);
	digitalWrite(chipDriver,LOW);
}

void loop()
{
	digitalWrite(chipDriver, HIGH); //Set RS-485 chip's mode to "send"
	//'

Juni25a_TwoSoftwareSerial.rar (21.9 KB)

Serial Monitor.png-Start of the message, "01"-weight transmitter's address,
//"ZERO"-command to set transmitter to Zero, "03" the XOR result from
//"01ZERO", "\r"-Carriadge return to end the command.
Serial1.write("$01ZERO03\r"); //send command through Serial1 port
digitalWrite(chipDriver, LOW); //Set RS-485 chip's mode to "receive"

//if some thing is available from Serial1, write it on Serial port.
while(Serial1.available() > 0){
	Serial.write(Serial1.read());
}

}


[Juni25a_TwoSoftwareSerial.rar|attachment](upload://fRra0VkccePknyjtUEHVCqYllF5.rar) (21.9 KB)

![Serial Monitor.png|484x298](upload://7PfaUI8BMIetL3F78qY8sUjxTWy.png)
	while(Serial1.available() > 0){
		Serial.write(Serial1.read());
	}

Serial.read() returns an int. Serial.write() expects a byte. Any integer value greater than 255 will be truncated. That may, or may not, be a problem.

Serial.write() sends binary data. Expecting to be able, as a human, to read binary data on a text display seems silly.

PaulS:
Serial.read() returns an int. Serial.write() expects a byte. Any integer value greater than 255 will be truncated. That may, or may not, be a problem.

Serial.write() sends binary data. Expecting to be able, as a human, to read binary data on a text display seems silly.

Thanks again PaulS! My experience is that if I don't "write" the upcoming info but "print" it on my Serial Monitor, They are just numbers, which are the ASCII numbers of each letter of the info. So I decided to "write" the info to me.
Update: I've tried any potential trouble makers. I changed a new checked RS-485 chip, use a external power jack to power up mega, in order to let the chip working on the suggested 5 Volt. At the end of the day I discovered if I make a "delay(50);" in the looply(), the Transmitter can be set to ZERO correctly, but I still can't get the right command confirm answer through Serial1. I even use a oscilloscope to take up the signal of the Serial1's rx and tx PIN and one of the RS-485 channel's signal.
P.S. I thought the answer signal from transmitter is pretty bad. On the oscilloscope the voltage is no more than two volt.

I believe I can at the last get the right answer from the transmitter always correctly. Haha!
Is there some one can help me to accelerate the process? :slight_smile:

Finally I solve the problems.

  1. It's interesting that the weight transmitter don't send fully 5 V signal at the beginning. And about 5 min. later it works just as expected.
  2. The oscilloscope shows the command sending takes nearly 2 ms, than wait 1 to 2 ms the transmitter answer the read value through the same rs-485 cable. That means I can set a 3 ms delay between two command which change the rs-485 chip's mode. In order to let the command be fully sent and have the correct time point to change chip's mode to catch the answer.

Thank you all!

question: cause each command have a CRC HEX number at the end. That's calculated through XOR. How can I generate it by myself? :slight_smile: