0

I'm working on a project where I get sensordata on an Arduino which prints it over a Serial to my laptop. When I'm using the Arduino IDE this works fine with the Serial Monitor. (The full messages look like this: 1-35 251 58 152). The characters after the - are a UID, so they should always be the same as I am only testing with one device.

When I try to read this through Java I get different messages (or at least not complete ones).

public void setupUSB() {
    SerialPort ports[] = SerialPort.getCommPorts();
    for (SerialPort port : ports) {
        if (port.getSystemPortName().equals("COM6")) myPort = port; // using LoRa over USB
    }
    myPort.setBaudRate(38400);
    myPort.openPort();
    myPort.setComPortTimeouts(SerialPort.TIMEOUT_SCANNER, 0, 0);
}

The method above initiates the USB port which I am using. After some checks I try to read the port as following (removed try catch and other non-important code to this question).

Scanner data = new Scanner(myPort.getInputStream()).useDelimiter("\n");
if (data.hasNext()) {
    String line = data.next();
    System.out.println("readUSB: " + line);
}

I have also tried the following:

Scanner data = new Scanner(myPort.getInputStream());
if (data.hasNextLine()) {
    String line = data.nextLine();
    System.out.println("readUSB: " + line);
}

The results which I'm getting from the System.out.println("readUSB: " + line); are as follows:

readUSB: �
readUSB:  152
readUSB: 9-35 251 58 152 
readUSB: 152
readUSB: 1-35 251 58 152 
readUSB: 5 251 58�152 
readUSB: 251 58 152 
readUSB: 
readUSB:  58 152

As you see (there is some noise in the messages), most of these messages are not complete.

Could anyone tell me what causes this and how to fix it?

[EDIT]

As I am using LoRa to transfer the data from one sensor to another Arduino, I'm collecting the data as chars. Both of the Arduino's and my USB port use the same baudRate at 38400. I feel like the error could be in the code below, as when I hook up the sensor USB (instead of sending it over LoRa) the values are actually correct.

if (packetFound) {
  // Print the packet over Serial per character
  Serial.println();
  for (int i=0; i<19; i++) { //20 and 21 are squares
    Serial.print(char(RxData[i]));
    RxData[i] = 0x00; // Clear buffer [0x20 -> space]
  }
}
Mathieu Brouwers
  • 564
  • 7
  • 19
  • Pretty trivial question but I should ask it, sorry. Are you sure the baudrates are matching? P.S. Please add the arduino code – eugene-nikolaev Jan 31 '17 at 12:37
  • Are you using a matching charset? – Klitos Kyriacou Jan 31 '17 at 12:45
  • Why not use a `InputStream` to read the data from the serial? Two useful resources related to `InputStream`: 1. http://stackoverflow.com/questions/336714/reading-serial-port-in-java 2. http://www.java-samples.com/showtutorial.php?tutorialid=11 – Ofer Arial Jan 31 '17 at 12:48
  • Are all packets exactly 19 characters long? Also, what is the type of RxData, and where does the array get allocated? – Klitos Kyriacou Jan 31 '17 at 13:50
  • I do have matching baudrates; I can't confirm if I have matching charsets, but it works from the Arduino with sensor, so I guess the other Arduino would be the same; Haven't tried using `InputStream`, certainly gonna look into it; All packets are 21 characters, but the last 2 are not important (always 2 squares, they cant be shown in comment section ). – Mathieu Brouwers Jan 31 '17 at 14:30
  • I don't know anything about LoRa, but could it possibly be that when `packetFound` is true, not all of the data has yet been completely written to the RxData array? So you start sending it to the serial port before it's ready? In other words, some kind of synchronization issue. – Klitos Kyriacou Jan 31 '17 at 21:03

1 Answers1

0

I can't seem to get rid of this problem, but I noticed the following.

If I add a String to the front of the message in Arduino I'm getting results like this:

  • readUSB: llo World: 9-35 251 58 152 (Obviously it should say Hello World).

My current solution to my issue is adding a set of 10 # characters to the start of my string in Arduino and filtering them out of the string later on.

while (line.charAt(0) == '#') { // Remove all the # chars in front of the real string
    line = line.substring(1, line.length());
}

As suggested in Comment: better way to write this code:

int i = 0;
while (line.charAt(i) == '#') {
    i++;
}
line = line.substring(i);

I'm accepting this answer as it works for my problem. BUT if someone has a real (good) solution to this issue, please post it and I will accept it.

Mathieu Brouwers
  • 564
  • 7
  • 19
  • 1
    This is not an efficient way to handle strings, since `substring()` will create a new `String` object N times and the old string will get released to the garbage collector. It's better to find the index of the first non-# in the string (`while (line.charAt(i) == '#') ++i;`) and then take a single substring. This won't fix your problem but is just a general comment on string handling best practice. – Klitos Kyriacou Jan 31 '17 at 15:33