Java/Arduino - Read data from the Serial Port

后端 未结 2 1198
灰色年华
灰色年华 2020-12-14 10:57

I\'ve got a program in Java where I have to read the information that an Arduino is sending. I took the Java code from here. Now, I didn\'t really understand how it works, b

相关标签:
2条回答
  • 2020-12-14 11:37

    You don't want to specifically write a read function it's already there in the sample code.As TheMerovingian pointed out you can check the input Buffer before reading.Here is the working code which I have used in one of my projects.

    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import gnu.io.CommPortIdentifier; 
    import gnu.io.SerialPort;
    import gnu.io.SerialPortEvent; 
    import gnu.io.SerialPortEventListener; 
    import java.util.Enumeration;
    
    
    public class SerialTest implements SerialPortEventListener {
    SerialPort serialPort;
        /** The port we're normally going to use. */
    private static final String PORT_NAMES[] = {                  "/dev/tty.usbserial-A9007UX1", // Mac OS X
            "/dev/ttyUSB0", // Linux
            "COM35", // Windows
    };
    private BufferedReader input;
    private OutputStream output;
    private static final int TIME_OUT = 2000;
    private static final int DATA_RATE = 9600;
    
    public void initialize() {
        CommPortIdentifier portId = null;
        Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
    
        //First, Find an instance of serial port as set in PORT_NAMES.
        while (portEnum.hasMoreElements()) {
            CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
            for (String portName : PORT_NAMES) {
                if (currPortId.getName().equals(portName)) {
                    portId = currPortId;
                    break;
                }
            }
        }
        if (portId == null) {
            System.out.println("Could not find COM port.");
            return;
        }
    
        try {
            serialPort = (SerialPort) portId.open(this.getClass().getName(),
                    TIME_OUT);
            serialPort.setSerialPortParams(DATA_RATE,
                    SerialPort.DATABITS_8,
                    SerialPort.STOPBITS_1,
                    SerialPort.PARITY_NONE);
    
            // open the streams
            input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
            output = serialPort.getOutputStream();
    
            serialPort.addEventListener(this);
            serialPort.notifyOnDataAvailable(true);
        } catch (Exception e) {
            System.err.println(e.toString());
        }
    }
    
    
    public synchronized void close() {
        if (serialPort != null) {
            serialPort.removeEventListener();
            serialPort.close();
        }
    }
    
    public synchronized void serialEvent(SerialPortEvent oEvent) {
        if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
            try {
                String inputLine=null;
                if (input.ready()) {
                    inputLine = input.readLine();
                                System.out.println(inputLine);
                }
    
            } catch (Exception e) {
                System.err.println(e.toString());
            }
        }
        // Ignore all the other eventTypes, but you should consider the other ones.
    }
    
    public static void main(String[] args) throws Exception {
        SerialTest main = new SerialTest();
        main.initialize();
        Thread t=new Thread() {
            public void run() {
                //the following line will keep this app alive for 1000    seconds,
                //waiting for events to occur and responding to them    (printing incoming messages to console).
                try {Thread.sleep(1000000);} catch (InterruptedException    ie) {}
            }
        };
        t.start();
        System.out.println("Started");
    }
    }
    

    EDIT : serialEvent function is responsible for reading the buffer.

    public synchronized void serialEvent(SerialPortEvent oEvent) {
     if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
        try {
            String inputLine=null;
            if (input.ready()) {
                inputLine = input.readLine();
                System.out.println(inputLine);
            }
    
        } catch (Exception e) {
            System.err.println(e.toString());
        }
     }
    // Ignore all the other eventTypes, but you should consider the other ones.
    }
    
    0 讨论(0)
  • 2020-12-14 11:56

    The BufferedReader class has a ready() method that returns True if "the buffer is not empty, or if the underlying character stream is ready." and False otherwise. So you could add a check in the read() method to make sure there is data to be read before trying to read.

    public synchronized int read(){
    
        int b = 0;  
    
        try{
            if (input.ready()) {
                b = (int)input.read();
            }
        }catch (Exception e) {
            System.err.println(e.toString());
        }
        return b;
    }
    

    It looks like the code has a try-catch in place to handle if those things fail, which is possibly what causes your lag because try-catch are quite expensive. So the input.ready() check should result in fewer exceptions.

    0 讨论(0)
提交回复
热议问题