我正在尝试从Java应用程序内的子进程中的串行端口读取数据。这是我目前正在使用的代码:
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Text {
public static void main(String... arguments) throws IOException, InterruptedException {
Process pb = new ProcessBuilder().command("/bin/sh", "-c", "(stty raw; cat) < /dev/ttyAMA0").start();
final Scanner scanner = new Scanner(new InputStreamReader(new BufferedInputStream(pb.getInputStream())));
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
}
});
t.start();
pb.waitFor();
}
}
这个想法如下:我不想依赖操作系统(这里是Raspberry Pi上的Raspbian)来从串口发送原始输入。因此,我启动了一个子进程,使用stty将串口设置为RAW模式,并使用cat转发数据。这个技巧在命令行上完美运行。如果我然后将stdout重定向到Java程序,则数据会正确地流向其输入流。
这里的问题是使用这段代码将数据传递给子进程(而不是Java程序的stdin,你猜对了),我正在丢失字符。我希望用逗号分隔的10个3位数的行,我得到4到6个数字,有时后面跟一个逗号。
我认为存在缓冲问题,我的Java应用程序可能无法清空(非常有限的)串口缓冲区。
我有什么可以做Java的事情,或者我应该转向Linux内核极客来获取一些操作系统技巧吗?
谢谢,
马修
答案 0 :(得分:0)
写完后尝试冲洗,我想这就是你“松散”数据的原因:))
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
System.out.flush();
}
答案 1 :(得分:0)
只是一个黑客,但试试这个。来自cat的stdout默认是缓冲的,但你想要的是一个无缓冲的流。尝试更改该行:
(stty raw; cat) < /dev/ttyAMA0
到
(stty raw; cat -u) < /dev/ttyAMA0
答案 2 :(得分:0)
我们想要的是(不是那么多字节)串口缓冲区和管道中的下一个命令之间的更大缓冲区。鉴于我期望一个82字节的行全包,我使用buffer -s 82 -b 2
命令,它允许一行的两个块存储在每个扫描器nextLine调用之间的共享内存中。
这是一个完整的演示,应该让每个试图读取Java中的串行数据的Raspberry Pi所有者高兴(我是唯一一个吗?):
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Text2 {
public static void main(String... arguments) throws IOException, InterruptedException {
Process pb = new ProcessBuilder().command("/bin/sh", "-c", "(stty raw; cat | buffer -s 82 -b 2) < /dev/ttyAMA0").start();
final Scanner scanner = new Scanner(new InputStreamReader(new BufferedInputStream(pb.getInputStream())));
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
}
});
t.start();
pb.waitFor();
}
}
这需要buffer
实用程序,轻松安装,输入sudo apt-get install buffer
这也依赖于一些技巧来启用板载串行端口,如https://github.com/lurch/rpi-serial-console
感谢brettw带来的输入,即使它首先不起作用。
马修