0

I am trying to create a class which sends and receives commands via serial port. Sadly the whenComplete is never called. I also tried to log the response and in the callback it is correct but when I try to get the variable in execute, it is completely different and looks like some random bytes. I tried to use the Latch to get the callback data. Is there any better way?

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class Device {
    private static final String port = "/dev/ttyS0";
    private static final int baud = 9600;
    private SerialHelper2 serialPort;
    private final int timeout = 500;
    private CountDownLatch responseLatch;
    private String response;

    public Device() {
    }

    public boolean open() {
        this.serialPort = new SerialHelper2(port, baud) {
            @Override
            protected void onDataReceived(final byte[] data) {
                Device.this.response = new String(data).trim();
                Serial.out.println(Device.this.response); // Output is correct
                Device.this.responseLatch.countDown();
            }
        };

        try {
            this.serialPort.open();
            return this.serialPort.isOpen();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    public CompletableFuture<String> execute(String cmd) {
        // reset latch
        Device.this.responseLatch = new CountDownLatch(1);
        return CompletableFuture.supplyAsync(() -> {
            Device.this.serialPort.sendHex(cmd);
            try {
                if (responseLatch.await(Device.this.timeout, TimeUnit.MILLISECONDS)) {
                    Serial.out.println(Device.this.response); // Complete garbage. Looks like some wrong memory access?
                    return Device.this.response;
                } else { // Timeout exceeded
                    throw new TimeoutException(String.format("Command '%s' timed out after %d ms", cmd, Device.this.timeout));
                }
            } catch (Exception e) {
                throw new IllegalStateException(e);
            }
        });
    }

    public CompletableFuture<Boolean> init() {
        return this.execute("REQ")
                .thenApply(res -> res.equalsIgnoreCase("RES"));
    }


}

Somewhere I call:

device.init()
    .whenComplete((result, ex) -> {
        if (null != ex) {
            Serial.out.println("Failed")
        } else {
            Serial.out.println("Device initialization " + (result ? "succeeded" : "failed"));
        }
    });
2
  • Please provide a minimal reproducible example. You mentioned the values are not what is expected but didn't share any values. You should provide debugging details. Commented Apr 19, 2024 at 11:34
  • Also provide details of your testing setup. What device is connected to what device/emulator that is running the code. If you are using libraries, do specify which libraries you are using. Commented Apr 19, 2024 at 20:18

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.