2013-11-23 44 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 

我希望它能帮助你。