Go Down

Topic: Arduino Mega 2560 bug when using Serial1, Serial2 or Serial3 (Read 2042 times) previous topic - next topic

_Sander_1

Hi,

I have an arduino mega 2560 and I have connected an ESP8266 to it with the Serial1, Serial2 or Serial3. The problem is, that if I use those Serials, the String class is bugging. If I use substring() for example, it should remove the first part of the String, but it also removes the second part of the string. It doesn't do that when I only use the PC-Arduino Serial (Serial0 or how you'd like to call it :) ). String.remove() is also not working. I found this bug when I connected my Java program via wifi to my esp and sent it a message: "Hi ESP8266!".

Here is my arduino code:

Code: [Select]

void setup(){
  Serial.begin(115200);
  Serial2.begin(115200);
}

void loop() {
  if (Serial2.available()) {
    String result = "";
    while (Serial2.available()) {
      char temp = Serial2.read();
      result += temp;
      delay(1);
    }
    Serial.println(result);
    if(result.startsWith("0,CONNECT") || result.startsWith("1,CONNECT") || result.startsWith("2,CONNECT") || result.startsWith("3,CONNECT")){
      result = result.substring(20);
      Serial.println(result);
    }
  }
}




Java code:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {

   public static void main(String args[]) {
      try {
         Socket socket = new Socket("192.168.1.135", 444);
         DataOutputStream out = new DataOutputStream(socket.getOutputStream());
         out.writeUTF("Hi ESP8266!");
         out.close();
      } catch (UnknownHostException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}



Response in the Serial monitor:

0,CONNECT

+IPD,0,13: Hi ESP8266!

13:



Response that should appear in the Serial Monitor:

0,CONNECT

+IPD,0,13: Hi ESP8266!

13: Hi ESP8266!

J-M-L

Well the way you read serial is just wrong... What guarantee do you have that you have received the full string when the available() returns false? Or do you read fast enough with the delay you have there? At 115200 bauds you send 100 characters in 1 ms and your buffer can only hold 64... So during your delay you might loose data...

Don't use Strings it's not worth it on arduino, use char arrays, build it up until you get a end of line or something and then use c functions to parse the data
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

_Sander_1


_Sander_1



I tried it with a char array. The response wasn't the same. It should print "+IPD,0,13:  Hi ESP8266!" but it printed just like this: "+IPD,0,13:". When I was using the String method, the String only bugged when I used substring. Now it removes "  Hi ESP8266" immediately without me removing the first part.

Here is my new code (I used Serial3 this time):

Code: [Select]

void setup() {
  Serial.begin(115200);
  Serial3.begin(115200);
}

void loop() {
  if (Serial3.available()) {
    char result[38];
    for (int i = 0; i < sizeof(result); i++) {
      result[i] = ' ';
    }
    int cnt = 0;
    while (Serial3.available()) {
      char temp = Serial3.read();
      result[cnt] = temp;
      cnt++;
      delayMicroseconds(100);
    }
    Serial.println(result);
    char connectMsg[10] = "0,CONNECT";
    boolean found = true;
    for (int i = 0; i < 9; i++) {
      if (connectMsg[i] != result[i]) {
        found = false;
        break;
      }
    }
    if (found) {
    } else {
      connectMsg[0] = '1';
      found = true;
      for (int i = 0; i < 9; i++) {
        if (connectMsg[i] != result[i]) {
          found = false;
          break;
        }
      }
      if (found) {
      } else {
        connectMsg[0] = '2';
        found = true;
        for (int i = 0; i < 9; i++) {
          if (connectMsg[i] != result[i]) {
            found = false;
            break;
          }
        }
        if (found) {
        } else {
          connectMsg[0] = '3';
          found = true;
          for (int i = 0; i < 9; i++) {
            if (connectMsg[i] != result[i]) {
              found = false;
              break;
            }
          }
          if (found) {
          } else {

          }
        }
      }
    }
  }
}


J-M-L

You don't need any delay -> get rid of       delayMicroseconds(100);

also you are still not reading until the \n you are reading whatever is available. ...

your loop should be about while you have not received the \n, keep reading. when you get the \n put a \0 in the result buffer at current position so that you have a nice looking string. (don't initialize your buffer with spaces, better to initialize with 0 (null character which marks the end of a string '\0') - will be needed for your serialPrint)
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

_Sander_1

Thanks, you helped me a lot! You were right about the delay and that I should use char arrays in stead of Strings. It's a lot easier. The biggest problem was that the esp8266 sent this message back:

"+IPD,0,13:\0\0message"

And I thought it sent me this:

"+IPD,0,13:  message"

So it sent me \0's in stead of spaces. That's why the String was cut of. You told me that I should add a \0 at the end of the String for the Serial.print method. That helped me so much!

Thanks!

Robin2

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up