2015-07-10 69 views
1

我正在嘗試編寫一個簡單的Java程序,以顯示在某些物理傳感器上來自用戶的刺激時,饋送給Arduino板的模擬輸入。從Java讀取Arduino太慢了

如果我使用Arduino程序本身並查看串行監視器,我會立即看到基於用戶輸入更新的模擬讀取。但是,當從我的Java程序讀取輸入時,物理刺激與顯示值之間會有顯着的延遲(5-6秒)。

上傳到Arduino的代碼非常簡單,通過一堆模擬端口的只是週期和打印數據:

void setup() { 
    Serial.begin(9600); 
    pinMode(30, OUTPUT); 
} 

void loop() 
    digitalWrite(30, HIGH); 

    for (int i = 0; i < 10; i++) { 
    int sensorValue = analogRead(i); 
    Serial.print(String(i) + ":"); 
    Serial.println(sensorValue); 
    } 
} 

我使用的Java代碼幾乎完全從設置here,與示例複製我更新了端口名稱以適用於我的系統(Mac OS X 10.10.3)的例外情況。

下面是Java代碼:

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/cu.usbmodem1411", 
      "/dev/cu.usbmodem1451", 
    }; 

    /** 
    * A BufferedReader which will be fed by a InputStreamReader 
    * converting the bytes into characters 
    * making the displayed results codepage independent 
    */ 
    private BufferedReader input; 

    /** The output stream to the port */ 
    private OutputStream output; 

    /** Milliseconds to block while waiting for port open */ 
    private static final int TIME_OUT = 2000; 

    /** Default bits per second for COM port. */ 
    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 { 
      // open serial port, and use class name for the appName. 
      serialPort = (SerialPort) portId.open(this.getClass().getName(), 
        TIME_OUT); 

      // set port parameters 
      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(); 

      // add event listeners 
      serialPort.addEventListener(this); 
      serialPort.notifyOnDataAvailable(true); 
     } catch (Exception e) { 
      System.err.println(e.toString()); 
     } 
    } 

    /** 
    * This should be called when you stop using the port. 
    * This will prevent port locking on platforms like Linux. 
    */ 
    public synchronized void close() { 
     if (serialPort != null) { 
      serialPort.removeEventListener(); 
      serialPort.close(); 
     } 
    } 

    /** 
    * Handle an event on the serial port. Read the data and print it. 
    */ 
    public synchronized void serialEvent(SerialPortEvent oEvent) { 
     if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) { 
      try { 
       String 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"); 
    } 
} 

所有程序所做的就是打印出來的Arduino的串口監視器的值,但它需要較長的方式(5-6秒)通過Java比它從做Arduino程序本身。

1)爲什麼會發生這種情況?
2)我該如何解決?

+1

我想你也應該在這裏發佈你的問題 - http://arduino.stackexchange.com/ – TDG

+0

我認爲它屬於這裏,因爲它似乎是一個Java問題,而不是一個Arduino之一,這是由事實證明Arduino IDE工作得很好,而且它不適用於Java。 – tam5

回答

0

爲我工作的答案是爲我的Arduino代碼添加一個delay方法。顯然Java被輸入速度所壓倒。

當然,Java仍然可以以足夠快的速度讀取任何實際的差異。