在RxTx中发送多个查询

时间:2012-11-27 05:08:15

标签: java scala rxtx

我正在尝试通过RxTx一次向设备(汽车的ECU,特别是ELM327)发送多个查询。这是使用RxTx的类:

import collection.JavaConversions._
import gnu.io._
import java.io._
import java.util.TooManyListenersException

class Serial private (portName: String, 
                      baudRate: Int, 
                      dataBits: Int, 
                      stopBits: Int, 
                      parity: Int, 
                      flowControl: Int) {

  private val portId = CommPortIdentifier.getPortIdentifier(portName)
  private val serial = portId.open("Serial Connection from OBDScan", 
                                   5000).asInstanceOf[SerialPort]
  setPortParameters(baudRate, dataBits, stopBits, parity, flowControl)

  private val istream = serial.getInputStream
  private val ostream = serial.getOutputStream

  def this(portName: String, baudRate: Int = 115200) = this(portName, baudRate,
    SerialPort.DATABITS_8,
    SerialPort.STOPBITS_1,
    SerialPort.PARITY_NONE,
    SerialPort.FLOWCONTROL_NONE)

  def close = {
    try {
      istream.close
      ostream.close
    } catch {
      case ioe: IOException => // don't care, it's ended already
    }

    serial.close
  }

  def query(command: String) = {
    ostream.write(command.getBytes)
    ostream.write("\r\n".getBytes) // neccessary for Serial port.
  }

  def queryResult: String = {
    try {
      val availableBytes = istream.available
      val buffer = new Array[Byte](availableBytes)

      if (availableBytes > 0) {
        istream.read(buffer, 0, availableBytes)
      }
      new String(buffer, 0, availableBytes)
    } catch {
      case ioe: IOException => "Something wrong! Please try again."
    }
  }

  def addListener(listener: SerialPortEventListener) = {
    try {
      serial.addEventListener(listener)
      serial.notifyOnDataAvailable(true)
    } catch {
      case tm: TooManyListenersException => println("Too many listener")
    }
  }

  def removeListener = {
    serial.removeEventListener
  }

  private def setPortParameters(br: Int, 
                                db: Int, 
                                sb: Int, 
                                p: Int, 
                                fc: Int) = {
    serial.setSerialPortParams(baudRate, dataBits, stopBits, parity)
    serial.setFlowControlMode(flowControl)
  }
}

object Serial {
  def connect(portName: String, baudRate: Int = 115200): Serial = {
    try {
      val ret = new Serial(portName, baudRate)
      ret
    } catch {
      // exception handling omitted.
    }
  }
}

现在查询工作正常,并给我正确的结果。当我一次发送几个查询时出现问题:

val serial = Serial.connect("COM34")
serial.query("AT Z")
serial.query("10 00")

设备收到了两个查询,但只返回一个结果。如果我想获得下一个结果,我必须发送另一个查询,这将导致程序迟到一个查询。如果我在每次查询后拨打Thread.sleep

val serial = Serial.connect("COM34")
serial.query("AT Z")
Thread.sleep(500)
serial.query("10 00")

问题已解决,但当然在调用Thread.sleep时整个应用程序停止。我不希望这样,因为应用程序将始终执行此查询(这意味着如果我这样做,它将一直挂起。)

由于我在使用Scala,我正在考虑使用Actors或类似的东西,但我认为这对桌面应用程序来说太过分了。没有Actors,有没有办法做到这一点?也许我正在读串口错误的响应?

TL; DR:我想通过RxTx对串行设备进行多次查询而不锁定整个应用程序(当前解决方案通过Thread.sleep实现,这会阻止整个应用程序)。我怎么能这样做?

0 个答案:

没有答案