0

I am reading data from weigh bridge using java comm api. below is the code:

import java.io.*;
import java.util.*;
import javax.comm.*;

public class Parrot implements Runnable, SerialPortEventListener {
    static CommPortIdentifier portId;
    static Enumeration portList;

    InputStream inputStream;
    SerialPort serialPort;
    Thread readThread;

    public static void main(String[] args) {
        portList = CommPortIdentifier.getPortIdentifiers();
        while (portList.hasMoreElements()) {
            portId = (CommPortIdentifier) portList.nextElement();
            if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
                 if (portId.getName().equals("COM1")) {
                    Parrot reader = new Parrot();
                }
            }
        }
    }

    public Parrot() {
        try {
            serialPort = (SerialPort) portId.open("SimpleReadApp", 2000);
        } catch (PortInUseException e) {System.out.println(e);}
        try {
            inputStream = serialPort.getInputStream();
        } catch (IOException e) {System.out.println(e);}
    try {
            serialPort.addEventListener(this);
    } catch (TooManyListenersException e) {System.out.println(e);}
        serialPort.notifyOnDataAvailable(true);
        try {
            serialPort.setSerialPortParams(9600,
                SerialPort.DATABITS_8,
                SerialPort.STOPBITS_1,
                SerialPort.PARITY_NONE);
        } catch (UnsupportedCommOperationException e) {System.out.println(e);}
        readThread = new Thread(this);
        readThread.start();
    }

    public void run() {
        System.out.println("In the run method");
        try {
            Thread.sleep(20000);
        } catch (InterruptedException e) {System.out.println(e);}
    }

    public void serialEvent(SerialPortEvent event) {
        switch(event.getEventType()) {
        case SerialPortEvent.DATA_AVAILABLE:
            byte[] readBuffer = new byte[20];

            try {
                int availableBytes =  inputStream.available();
                System.out.println(availableBytes+" bytes are available to read");
                while (inputStream.available() > 0) {
                    int numBytes = inputStream.read(readBuffer);
                }
                System.out.print(new String(readBuffer));
            } catch (IOException e) {System.out.println(e);}
            break;
        }
    }
}

Below are two screen shots, one from hyper terminal and one from above java program:

Hyper Terminal (with Terminal Font) enter image description here

Java Program

enter image description here

I want to get the same characters as hyper terminal.

Usman Riaz
  • 2,920
  • 10
  • 43
  • 66
  • It looks like it's a binary protocol, basically - you shouldn't be treating it as text at all. – Jon Skeet Jul 22 '15 at 13:54
  • so what should i be doing ? – Usman Riaz Jul 22 '15 at 13:56
  • Bytes are not the same as characters. You need to find out what the encoding of the data is and use that, preferably using a `Reader`. Or if the stream is binary, you need to find out how it's composed and do the reads accordingly. – RealSkeptic Jul 22 '15 at 13:58
  • Can you please guide me further? how do i know the encoding of the data? -Thanks – Usman Riaz Jul 22 '15 at 14:01
  • You should be finding out what the data actually means - we don't know what device you're talking to, etc. Once you can understand the data, you can get it into human-readable form. – Jon Skeet Jul 22 '15 at 14:05
  • possible duplicate of [What is character encoding and why should I bother with it](http://stackoverflow.com/questions/10611455/what-is-character-encoding-and-why-should-i-bother-with-it) – Raedwald Jul 22 '15 at 14:06
  • You have at least two issues: Proper encoding and reading the stream into a buffer without specifying the end point. You create the `String` with the raw buffer, without giving the start and end points and without giving encoding. – MadConan Jul 22 '15 at 14:06
  • See also http://stackoverflow.com/questions/1536054/how-to-convert-byte-array-to-string-and-vice-versa – Raedwald Jul 22 '15 at 14:07

1 Answers1

0

It doesn't look like you are correctly reading the stream. You have

        byte[] readBuffer = new byte[20];

        try {
            int availableBytes =  inputStream.available();
            System.out.println(availableBytes+" bytes are available to read");
            while (inputStream.available() > 0) {
                // OVERWRITES THE BYTES FROM THE PREVIOUS READ
                int numBytes = inputStream.read(readBuffer);
            }
            // DOESN'T GIVE BUFFER END POINTS AND DOESN'T GIVE ENCODING
            System.out.print(new String(readBuffer));
        } catch (IOException e) {System.out.println(e);}

Should be

        byte[] readBuffer = new byte[20];
        int bytesRead;
        try {
            int availableBytes =  inputStream.available();
            System.out.println(availableBytes+" bytes are available to read");
            while ((bytesRead = inputStream.read(readBuffer)) != -1) {
                System.out.print(new String(readBuffer,0,bytesRead,Charset.forName(ENCODING));
            }

        } catch (IOException e) {System.out.println(e);}

Where ENCODING is a String that is the proper encoding, eg "UTF-8".

If you want to get a single String that has all of the content:

        byte[] readBuffer = new byte[20];
        int bytesRead;
        StringBuilder sb = new StringBuilder(100);
        try {
            int availableBytes =  inputStream.available();
            System.out.println(availableBytes+" bytes are available to read");
            while ((bytesRead = inputStream.read(readBuffer) != -1) {
                sb.append(new String(readBuffer,0,bytesRead,Charset.forName(ENCODING));
            }
            System.out.println("The content -> " + sb);

        } catch (IOException e) {System.out.println(e);}

EDIT: Answering your comment here: If you want to separate by line, you need to add a new-line to the StringBuilder within the loop. The boxes are likely because you do not have the proper encoding OR the content isn't even valid character data. I don't know how to programmatically determine encoding. It's usually something you know beforehand. The other problem may be the constants you use when setting up the com port stream

        serialPort.setSerialPortParams(9600,
            SerialPort.DATABITS_8,
            SerialPort.STOPBITS_1,
            SerialPort.PARITY_NONE);

Are you sure those are correct?

FYI: A list of encodings.You'll want to use a value from the middle column ("Canonical Name for java.io API and java.lang API").

MadConan
  • 3,749
  • 1
  • 16
  • 27
  • I just used your method. now i am getting all the data in one line rather then printing after while loop but again those characters (boxes) are showing – Usman Riaz Jul 22 '15 at 14:25