0

I'm making a project that uses a login form and accesses an Arduino using the serial port. I must send a String to the Arduino as the application starts and wait for a response from the device to know its ready to operate before checking the login username and passwords are correct. I made two classes, one called Login that checks username and password, and another called serial that contains the jssc implementation.

I'm using the library java simple serial connector and the example found HERE.

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);
            }
        }
    }
}

And this function creates the serial object in the Login class.

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);
    }

I successfully send data to the Arduino and receive the response but I don't know how to pass that value to the Login class. All I get is a null value or nothing. I've tried using a wait method, tried passing both a new instance of Login inside serial and trying to make the method public through a getter variable but nothing has worked so far.

What's the right way to pass a SerialEvent variable to the calling class? And how does that class know the serial event has finished to proceed comparing login forms?

rasa911216
  • 97
  • 2
  • 12

1 Answers1

0

Never mind, found how to make it work after some vigorous study of Concurrency. Apparently in order to access a value that's being updated in real time you need to set a Lock object that essentially blocks a given thread until it has finished updating variables.

So the answer is:

  • Generate a set method that gets called inside the SerialEventHandler and implement a Lock.
  • Generate a get method to be called wherever you want to retrieve the data and that waits for the lock to finish.

Below's the code I used on the jssc implementation:

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;
    }
}
}

and that was implemented in my Login class as follows:

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);
    }
rasa911216
  • 97
  • 2
  • 12