0

I have a while loop that reads from a serial port using a scanner and adds all the data it reads to a List<String>. My problem is I don't know how to exit the loop when I receive the data?

The data I receive in the loop is

[***, REPORT, ***, MIB-Series, Currency, Counter, --------------------------------, Mar.6,2022,, 01:26, Station:1, Deposit, No.:, 2, Mixed, Mode, RSD, UV, MG, IR, --------------------------------, DENOM, UNIT, TOTAL, D10, 0, D, 0, D20, 0, D, 0, D50, 0, D, 0, D100, 0, D, 0, D200, 0, D, 0, D500, 0, D, 0, D1000, 0, D, 0, D2000, 0, D, 0, D5000, 0, D, 0, --------------------------------, TOTAL, 0, D, 0, --------------------------------, m3]

And the code that I use is

public static List<String> readFromPort(SerialPort serialPort) {

    Scanner sc = new Scanner(serialPort.getInputStream());

    List<String> line = new ArrayList<>();
    
    while (sc.hasNextLine()) {
        line.add(sc.next());
    }
    sc.close();
    return line;
}

I tried adding this condition to WHILE loop && !line.contains("m3") but for some reason, I then have to press "Send" on the serial device twice to receive data. If I use some other string from the list it works fine(I press "Send" only once), but then I don't receive the complete data.

Any ideas what else to try?

NOTE: I'm using JSerialComm library.

EDIT: The String at the end of List is like in the screenshot below, the two unrecognized characters are deleted automatically when I post the question.

enter image description here

enter image description here

  • Isn't the delimiter ']' (not "m3")? If so, then sc.useDelimiter("\]") with while(sc.hasNext()). You can precede that delimiter with "m3" if necessary – g00se Mar 06 '22 at 11:47
  • I didnt exactly understand how did you want me to use sc.useDelimiter. Can you please explain a little more? – Danilo Djurovic Mar 06 '22 at 16:00
  • In the case above, let's assume ']' marks end of message. sc.useDelimiter("\\]") should do it for you. That's telling the scanner that each token ends with that character. You can then do while(sc.hasNext()) and it will correctly break for each message – g00se Mar 06 '22 at 16:23

3 Answers3

1

If you know the unicode code-point for the two characters displayed as squares in the screen capture in your question, then use a literal, for example:

!line.contains(\u03A9m\uFFFF3)

In the above line, the first literal is \u03A9 which precedes the lowercase m and the second literal is \uFFFF which follows the lowercase m and precedes the digit 3.

Abra
  • 19,142
  • 7
  • 29
  • 41
1

java Scanner has several issues when reading new lines or skipping inputs

  1. Scanner is skipping nextLine() after using next() or nextFoo()?

  2. How to use java.util.Scanner to correctly read user input from System.in and act on it?

  3. Scanner skipping input, possible white space?

An better but slower solution involves using BufferedReader for reading any input from any input stream see Scanner vs. BufferedReader

Also taking points from @Abra solution you should use uni code points for non printable characters

\u03A9m\uFFFF3

Full code below

try(BufferedReader reader=new BufferedReader(new InputStreamReader(serialPort.getInputStream()))
{
 List<String> lines = new ArrayList<>();

 String line;
 while((line=reader.readLine())!=null && !line.contains(\u03A9m\uFFFF3))
 {
  line.add(line);
 }
 
 return lines;
}
Sync it
  • 1,180
  • 2
  • 11
  • 29
  • Moving the comment. Actually I meant to place it below the actual question – g00se Mar 06 '22 at 11:46
  • In my situation, the scanner works great for what I need, I'm just having a problem finding a condition to get out of while loop when I receive the data. I don't know what Unicode characters are those squares. – Danilo Djurovic Mar 06 '22 at 15:07
  • You did say you "Send" on the serial device twice to receive data so that could be because of the scanner skipping certain input. As for getting out of the while loop you have to know what the unicode of those delimiters are – Sync it Mar 06 '22 at 15:45
  • That only happens when I use unicode characters in the condition, if I use any other String, it works without problems. I'll try to find out what those characters are. Any suggestion how would I do this? Thanks EDIT: When I paste the characters into a web browser a get a symbol "ESC". See the original question. – Danilo Djurovic Mar 06 '22 at 16:05
0

I solved this using this code:

public static List<String> readFromPort(SerialPort serialPort) {

    Scanner sc = new Scanner(serialPort.getInputStream());

    List<String> line = new ArrayList<>();

    while (sc.hasNextLine()) {
        line.add(sc.next());
        if(line.contains("m3")){
            break;
        }
    }
    return line;
}

I added an IF statement inside the WHILE loop which contained the same condition as I previously used in WHILE loop. This solved my problem, and now I'm getting the correct data with only one click on "Send" from my device.

Thanks everyone for your help.