2013-11-23 47 views
1

我正在使用RXTX在JAVA和微控制器之間進行通信。java rxtx SerialWriter問題

這是打開連接,發送和接收數據

package app; 

import gnu.io.CommPort; 
import gnu.io.CommPortIdentifier; 
import gnu.io.SerialPort; 

import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 

public class SerialCommunication1 { 
    private static SerialCommunication1 instance = null; 
    private static boolean coonected = false; 

    public static SerialCommunication1 getInstance(){ 
     if(instance == null) 
      instance = new SerialCommunication1(); 
     return instance; 
    } 

    private SerialCommunication1() { 
     super(); 
     try { 
      connect("COM4"); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     SerialCommunication1.coonected = true; 
    } 

    void connect(String portName) throws Exception { 
     CommPortIdentifier portIdentifier = CommPortIdentifier 
       .getPortIdentifier(portName); 
     if (portIdentifier.isCurrentlyOwned()) { 
      System.out.println("Error: Port is currently in use"); 
     } else { 
      CommPort commPort = portIdentifier.open(this.getClass().getName(), 
        2000); 

      if (commPort instanceof SerialPort) { 
       SerialPort serialPort = (SerialPort) commPort; 
       serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, 
         SerialPort.STOPBITS_2, SerialPort.PARITY_NONE); 

       InputStream in = serialPort.getInputStream(); 
       OutputStream out = serialPort.getOutputStream(); 

       (new Thread(new SerialReader(in))).start(); 
       (new Thread(new SerialWriter(out))).start(); 

      } else { 
       System.out 
         .println("Error: Only serial ports are handled by this example."); 
      } 
     } 
    } 

    /** */ 
    public static class SerialReader implements Runnable { 
     InputStream in; 

     public SerialReader(InputStream in) { 
      this.in = in; 
     } 

     public void run() { 
      byte[] buffer = new byte[1024]; 
      int len = -1; 
      try { 
       while ((len = this.in.read(buffer)) > -1) { 
        System.out.print(new String(buffer, 0, len)); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    /** */ 
    public static class SerialWriter implements Runnable { 
     OutputStream out; 
     static String str = null; 

     public SerialWriter(OutputStream out) { 
      this.out = out; 
     } 

     public void run() { 
      System.out.println("Will try to execute"); 
      try { 
       if(str.length() > 0){ 
        this.out.write(str.getBytes()); 
        str = null; 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

} 

的Java代碼,這是當事件觸發

SerialCommunication1.getInstance(); 
if(ledStatus == true) {SerialCommunication1.SerialWriter.str = "4A01";} 
else {SerialCommunication1.SerialWriter.str = "4A00";} 
stopProcess(); 

而現在的問題是調用Java代碼。我需要使用代碼4A01向微控制器發送命令,並在收到答案後,再次使用代碼4A00調用它。這些調用由我的Java界面中的按鈕觸發。問題是沒有執行第二個呼叫(4A00不發送)。我試圖反轉命令代碼,他們工作得很好。在執行第一個(4A01)之後,我的微控制器反應併發送由java讀取的響應,並且更新我的接口。當我發送invers命令(4A00)時,它正好停在此行SerialCommunication1.SerialWriter.str = "4A00";處,甚至不會進入SerialWriter的run()方法內部。

你知道爲什麼會發生這種情況嗎?從我的微控制器一側沒有問題,我用一個工具檢查了所有的可能性。

我希望我明確自己。

謝謝!

LE:我忘了你電話,它沒有把我不知道,因爲我沒能測試你的代碼,但我覺得你的問題是在SerialWriter類中的任何錯誤或異常

回答

1

public static class SerialWriter implements Runnable { 
    OutputStream out; 
    static String str = null; // Here str is initialized to null 

    public SerialWriter(OutputStream out) { 
     this.out = out; 
    } 

    public void run() { 
     System.out.println("Will try to execute"); 
     try { 
      if(str.length() > 0) { // this should throw NPE because str is null 
       this.out.write(str.getBytes()); 
       str = null; 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

由於在該方法中不存在環路,則該線程在該行內SerialCommunication1創建:

(new Thread(new SerialWriter(out))).start(); 

最有可能的完成我在發送第一個str之後執行ts。

老實說,我不明白它是如何發送一個單一的字符串,因爲str被初始化爲null,它應該拋出NullPointerExceptionstr.length()行。

我建議你這種方法:

  • 不觸發一個作家線程建立連接時,就觸發一個新的每一個消息將被髮送的時間。
  • 正確使用單例模式。
  • 保留對SerialCommunication1類中的串口的引用。

翻譯成代碼會是這樣的:

class SerialWriter implements Runnable { 
    OutputStream out; 
    String message; 

    public SerialWriter(OutputStream out) { 
     this.out = out; 
    } 

    public void setMessage(String msg) { 
     this.message = msg; 
    } 

    public void run() { 
     try { 
      if(message != null) { 
       this.out.write(str.getBytes()); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

然後在SerialCommunication1類中添加這個公共方法:

public void sendMessage(String msg) { 
    SerialWriter writer = new SerialWriter(serialPort.getOutputStream()); // of course you'll have to keep reference to serialPort when connection is established 
    writer.setMessage(msg); 
    (new Thread(writer)).start(); 
} 

最後調用此方法是這樣的:

SerialCommunication1.getInstance().sendMessage("4A01"); 
0

tzortzik,

我認爲這是一個超時問題。嘗試addding延遲到作家:

/** */ 
public static class SerialWriter implements Runnable { 
    OutputStream out; 
    static String str = null; 

    public SerialWriter(OutputStream out) { 
     this.out = out; 
    } 

    public void run() { 
     Thread.sleep(500); //<----------- this should be in mainThread before to SerialWriter.start(); 
     System.out.println("Will try to execute"); 
     try { 
      if(str.length() > 0){ 
       this.out.write(str.getBytes()); 
       str = null; 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

它發生在我很多次,「我們應該學會等待響應」 (^_^)

檢查,如果你都運行得很好一個secuence像下一個:

Send command 4A01 
Receive response 4A01 from micro 

WAIT FOR RESPONSE BEFORE SEND SECOND COMMAND. Thread.sleep(500); //wait for 500 milis or more 

Send command 4A00 
Receive response 4A00 from micro 

我希望它能幫助你。