我正在制作一个项目,该项目使用登录表单并使用串行端口访问Arduino。我必须在应用程序启动时向Arduino发送一个字符串,并等待设备的响应以了解其已准备好操作,然后检查登录用户名和密码是否正确。我创建了两个类,一个叫Login,用于检查用户名和密码,另一个叫serial,用于包含jssc实现。
我使用的是库java简单串行连接器和这里的例子。
public class PortReader implements SerialPortEventListener {
@Override
public void serialEvent(SerialPortEvent event) {
if(event.isRXCHAR() && event.getEventValue() > 0) {
try {
synchronized(this){
String receivedData = serialPort.readString(event.getEventValue());
System.out.println("Received response from port: " + receivedData);
serialPort.closePort();
}
}
catch (SerialPortException ex) {
System.out.println("Error in receiving response from port: " + ex);
}
}
}
}
这个函数在Login类中创建串行对象。
try {
reader.connect(comReader);
writer.connect(comWriter);
//Message to Arduino, wait response.
writer.serialWrite("1");
synchronized(writer){
try{
writer.wait();
}
catch(Exception e){
e.printStackTrace();
}
}
} catch (Exception ex) {
lblMensaje.setText("Fallo de conexion serial.");
System.out.println(ex);
}
我成功地将数据发送到Arduino并接收响应,但我不知道如何将该值传递给Login类。我得到的只是一个空值或什么都没有。我尝试过使用wait方法,尝试在serial内部传递Login的新实例,并尝试通过getter变量将该方法公开,但到目前为止,一切都不起作用。
将SerialEvent变量传递给调用类的正确方法是什么?该类如何知道串行事件已经完成以继续比较登录表单?
没关系,在对并发进行了大量研究后,找到了如何使其工作。显然,为了访问正在实时更新的值,您需要设置一个Lock对象,该对象基本上会阻塞给定线程,直到它完成变量更新。
所以答案是:
- 生成一个在SerialEventHandler内部调用的set方法并实现一个Lock
- 生成一个get方法,该方法将在您想要检索数据的任何地方调用,并等待锁定完成
下面是我在jssc实现中使用的代码:
public class Serial implements SerialPortEventListener {
public final Object lock = new Object();
@Override
public void serialEvent(SerialPortEvent event) {
if(event.isRXCHAR() && event.getEventValue() > 0) {
try {
receivedData += serialPort.readString(event.getEventValue());//serialPort.readString(event.getEventValue());
setData(receivedData);
}
catch (SerialPortException ex) {
System.out.println("Error in receiving response from port: " + ex);
}
}
}
public void setData(String data){
synchronized(lock){
readData = data;
ready = true;
lock.notifyAll();
}
}
public String getData() throws InterruptedException{
synchronized(lock){
while(ready == false){
lock.wait();
}
String temp = readData;
readData = "";
return temp;
}
}
}
这在我的登录类中实现如下:
try {
reader.connect(comReader);
writer.connect(comWriter);
//Enviar mensaje de conexion a Arduino principal y eperar respuesta.
writer.serialWrite("1");
} catch (Exception ex) {
System.out.println(ex);
}
try {
System.out.println("Recibi dato: " + writer.getData());
} catch (InterruptedException ex) {
Logger.getLogger(LoginController.class.getName()).log(Level.SEVERE, null, ex);
}