0

Ok, im lost and dont know what to even google at this point.

I am reading data from a serial port using JSSC.

When I print as a check figure, the data is jacked up. It prints a few rows fine then prints by individual characters. It prints normally if I use "printf"

$GPRMC,212729.000,A,3805.8438,N,08459.5498,W,0.00,280.71,031117,,,D*73
$GPVTG,280.71,T,,M,0.00,N,0.0,K0
F



$
G
P
G

This is the for loop im using:

  for (String s: data2) { 

                System.out.println(s);

                 }

Other code:

String getData =  serialPort.readString(event.getEventValue());

List<String> data2 = new ArrayList<String>(Arrays.asList(getData.split("$")));

If I were just printing it, i would be fine with printf.

I need to split each sentence up by the $ sign.

Any help would be appreciated.

    import jssc.SerialPort; 
    import jssc.SerialPortEvent; 
    import jssc.SerialPortEventListener; import jssc.SerialPortException;
    import java.util.Arrays;
    import java.util.ArrayList;
    import java.util.List;


    public class test {

    static SerialPort serialPort;

    public static void main(String[] args) {
        serialPort = new SerialPort("COM!"); 
        try {
            serialPort.openPort();//Open ports
            serialPort.setParams(4800, 8, 1, 0);//Set params
          int mask = SerialPort.MASK_RXCHAR + SerialPort.MASK_CTS + SerialPort.MASK_DSR;//Prepare mask
           serialPort.setEventsMask(mask);//Set mask
           serialPort.addEventListener(new SerialPortReader());//Add SerialPortEventListener


        }
        catch (SerialPortException ex) {
            System.out.println(ex);
        }

}public void serialEvent(SerialPortEvent event) {
          //  if(event.isRXCHAR()){//If data is available
           //    if(event.getInputBufferBytesCount()  > 1){//Check bytes count in the input buffer
                    //Read data, if 10 bytes available 
                    try {


                          String getdata =  serialPort.readString(event.getEventValue());

                          String delimiter = "$";

                      List<String> data2 = new ArrayList<String>(Arrays.asList(getdata.split("$")));


                   for (String s: data2) { 

                    System.out.printf("NEW" + s);

                     }
                    }
                    catch (SerialPortException ex) {

                    }

UPDATED CODE PER REQUEST

    import jssc.SerialPort; 
import jssc.SerialPortEvent; 
import jssc.SerialPortEventListener; import jssc.SerialPortException;
//import java.util.Arrays;
//import java.awt.List;
//import java.util.Base64;
//import java.io.BufferedReader;
//import java.io.ByteArrayInputStream;
//import java.io.InputStream;
//import java.io.InputStreamReader;
//import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.io.IOException;
import java.lang.*;
//import static java.util.Arrays.asList;
//import java.util.List;
//import java.util.stream.Collectors;
//import org.apache.commons.lang3.StringUtils;


public class test {
static ArrayList<String> data = new ArrayList<String>();
static SerialPort serialPort;

public static void main(String[] args) {
    serialPort = new SerialPort("COM1"); 
    try {
        serialPort.openPort();//Open ports
        serialPort.setParams(4800, 8, 1, 0);//Set params
      int mask = SerialPort.MASK_RXCHAR + SerialPort.MASK_CTS + SerialPort.MASK_DSR;//Prepare mask
       serialPort.setEventsMask(mask);//Set mask
       serialPort.addEventListener(new SerialPortReader());//Add SerialPortEventListener


    }
    catch (SerialPortException ex) {
        System.out.println(ex);
    }
}

/*
 * In this class must implement the method serialEvent, through it we learn about 
 * events that happened to our port. But we will not report on all events but only 
 * those that we put in the mask. In this case the arrival of the data and change the 
 * status lines CTS and DSR
 */

static class SerialPortReader implements SerialPortEventListener {

    public void serialEvent(SerialPortEvent event) {
    //   if(event.isRXCHAR()){//If data is available
      //     if(event.getEventValue() < 577){//Check bytes count in the input buffer
                //Read data, if 10 bytes available 

                try {
                    String getdata =  serialPort.readString(event.getEventValue());
                String[] parts= getdata.split("$");

                data.set(data.size() - 1, data.get(data.size() - 1) + parts[0]);
                for (int i=1; i<parts.length; i++) {
                    data.add(parts[i]);
                }

                }
                catch (SerialPortException ex) {                  
             }

       }        
}
}
  • I may be rusty on the subject, but isn't your code supposed to be wrapped in the `serialEvent` implementation? If so, please share the whole class so we can take a better look – Piyin Nov 03 '17 at 22:09
  • see edit. i just dont get why a few lines print out fine but the rest dont – tornadoguycarguy Nov 04 '17 at 01:05
  • try using `System.out.print` instead of `System.out.printlln` – nits.kk Nov 04 '17 at 01:37
  • the system print is simply a check. it turns out that I start with around 260 bytes immediately and then after that i get one byte at a time. Byte count: [256] [1][1][1][1][1][1]. The sentences are variable length as well. I guess i need some kind of loop? I have no idea. – tornadoguycarguy Nov 04 '17 at 01:40

1 Answers1

1

Your serialEvent method is just an EventListener that fires up for each SerialPortEvent, but there's no guarantee the data will arrive "complete", so you should declare the List at class level, take the data that arrives and store it in the appropriate way. Something like:

public class test {
    // ...
    static List<String> data = new ArrayList<String>();
    // ...
    public void serialEvent(SerialPortEvent event) {
        try {
            String getdata =  serialPort.readString(event.getEventValue());
            // String.split takes a regular expression. In regular expressions,
            // the dollar sign ($) by it's own means the end of the line, so you
            // have to escape it using a backslash (\), but since it's a string
            // you have to escape that one with another backslash so it get's
            // passed correctly, thus searching for the dollar sign and not the
            // end of the line
            String[] parts = getdata.split("\\$");
            // Append whatever is before the first dollar sign to the last item
            // in your data
            if(!data.isEmpty()){
                data.set(data.size() - 1, data.get(data.size() - 1) + parts[0]);
            }
            // Append the rest of the parts in your data
            for (int i=1; i<parts.length; i++) {
                data.add(parts[i]);
            }
        }
        catch (SerialPortException ex) {}
        // ...
    }
    // ...
}
Piyin
  • 1,823
  • 1
  • 16
  • 23
  • **String[] parts = getdata.split("\\$"); // Append whatever is before the first dollar sign to the last item // in your data** Its a streaming dataset. I never know what the last item is. ** static List data = new ArrayList();** this gives me issues as well – tornadoguycarguy Nov 06 '17 at 02:20
  • Keep in mind I'm not talking about `getdata` but `data`, which is the `ArrayList`. The code, as I wrote it, shoult take care of the cases when you get data with some input after the first dollar sign (which would mean it's data from the last block). Which issue does that give you? – Piyin Nov 06 '17 at 03:37
  • 1
    java.lang.ArrayIndexOutOfBoundsException: -1 at java.util.ArrayList.elementData(ArrayList.java:418) at java.util.ArrayList.get(ArrayList.java:431) – tornadoguycarguy Nov 09 '17 at 04:47
  • Please update your question including the updated code so I can take a look – Piyin Nov 09 '17 at 14:25
  • Oh, ok, I'm sorry I didn't check that error earlier. The `java.lang.ArrayIndexOutOfBoundsException` happens because I didn't check first if the list had items – Piyin Nov 14 '17 at 03:56