我正在研究一个项目,以在RS485串行连接的两个Raspberry Pi之间发送数据。为此,我编写了一些Java程序来发送数据。设置正在工作,但我无法以某种方式改变Java Prog中数据传输的速度。我使用的是带有25KB随机数据和两个Raspberry Pi 1B的测试文件。作为库,我正在使用RXTX Java库。
我已经更改了/boot/config.txt
和/boot/cmdline.txt
中的设置,因此我可以使用串行端口并更改速度。
要测试硬件是否可以执行此操作,我将带有简单控制台命令的数据。一个raspi发送:
cat 25kTestfile.txt > /dev/ttyAMA0
另一个收到:
cat /dev/ttyAMA0 > 25kTestfile.txt
我用sudo stty
改变了速度。使用此命令行设置,我可以发送最多1MB的数据并更改我喜欢的速度。
在我的Java程序中,速度不会改变。无论我是将串行端口设置为115200还是1000000,它发送的速度保持不变。通过我的程序,发送25K的时间为3秒钟,控制台为0.3秒
Java程序由两个文件组成。我在下面包含了该程序中最重要的部分。一个设置串行端口连接的文件在此处。
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class SerialConnect {
private SerialPort serialPort = null;
private InputStream in = null;
private OutputStream out = null;
private CommPort commPort = null;
private CommPortIdentifier portIdentifier = null;
void connect( String portName ) throws Exception {
portIdentifier = CommPortIdentifier
.getPortIdentifier( portName );
if( portIdentifier.isCurrentlyOwned() ) {
System.out.println( "Error: Port is currently in use" );
} else {
int timeout = 2000;
commPort = portIdentifier.open( this.getClass().getName(), timeout );
if( commPort instanceof SerialPort ) {
serialPort = ( SerialPort )commPort;
serialPort.setSerialPortParams( 1000000,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE );
serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
in = serialPort.getInputStream();
out = serialPort.getOutputStream();
} else {
System.out.println( "Error: Only serial ports are handled by this example." );
}
}
}
[...]
public void write(byte[] input) {
try {
for(int i = 0; i < input.length; i++) {
this.out.write( input[i] );
}
this.out.flush();
} catch( IOException e ) {
e.printStackTrace();
}
}
public void write(byte input) {
try {
this.out.write(input);
} catch( IOException e ) {
e.printStackTrace();
}
}
[...]
public SerialConnect() {}
public SerialConnect(String portName) {
try{
connect(portName);
}
catch (Exception e) {
System.out.println("Error Failed to connect port.n");
}
}
}
使用串行连接的另一个在这里:
File outFile = new File("./25kTestfile.txt");
FileInputStream in = new FileInputStream(outFile);
byte[] c = new byte[(int)outFile.length()];
in.read(c);
SerialConnect serialConnection = new SerialConnect("/dev/ttyAMA0");
if(serialConnection == null) {
System.out.println("Could not open Serial port.n");
return;
}
serialConnection.write(c);
我的问题现在是:为什么速度不变?我需要设置其他一些东西吗?Java是否有可能在RASPI上如此慢,以至于发送速度不能更快?
我发现了这个问题。我用来发送字节阵列的写入功能是通过循环中的输出流将数据字节写入输出流。这显然非常低效。我更改了写功能,现在看起来像这样:
public void write(byte[] input) {
try {
this.out.write( input ); // no loop
this.out.flush();
} catch( IOException e ) {
e.printStackTrace();
}
}
这使发送过程更快约10倍。
因此,问题不是因为连接的速度没有改变,而是该函数不够快,无法将足够的数据馈送到流。