实施RS-485协议,我必须:
high
并进入写入模式。low
并进入阅读模式。详细信息包括为什么写引脚必须设置为高和低,为什么16个数据包完全正确,以及...是某些硬件实现细节我无法改变。
// .....
private final Serial serial;
private final GpioPinDigitalOutput pin;
private final long DELAY_M = 2;
private final int DELAY_N = 0
// .....
public boolean send(final byte[] packet) {
result = false;
try {
this.pin.high();
this.serial.write(packet);
Thread.sleep(DELAY_M, DELAY_S); // -> THE TROUBLE MAKER
this.pin.low();
result = true;
}
// ... Now in read mode, recv 16 bytes in a pre-defined time window
return result;
在进入读取模式(将pin
设置为low
)之前,我必须等到串行缓冲区中的所有数据都被传输完毕。我正在使用Pi4J库,它无法检查缓冲区中的剩余字节。肮脏的解决方案是等待一个恒定的DELAY_M毫秒但是这个恒定的时间在不同的环境,不同的硬件和......中发生变化。
研究Pi4J的代码,在本机实现(JNI)中,它调用了WiringPi的API。 WiringPi又将串口视为常规linux文件并写入文件。同样,WiringPi没有提供检查缓冲区中剩余字节的方法。那么它必须是Linux-Hardware-Kernely的东西,而不一定是Pi4j的责任。那么:如何检查raspberry的串口缓冲区中的剩余数据?这是/dev/ttyAMA0
P.S:Pi4j中的串行接口有一个方法flush(),带有这个文档:
强制在串行端口发送缓冲区中传输任何剩余数据。 请注意,这不会强制传输数据,它会丢弃它!
关于@sawdust在评论中指出的内容,我找到了this教程。它可以实现所谓的RTS和CTS(更多关于这些标志here和here)但是它还没有工作。我的示波器在CTS和RTS引脚上没有显示信号。
另请注意,the article的日期可以追溯到2013年,gpio_setfunc
甚至无法编译。它需要一些在任何地方都没有的奇怪脚本但请查看带有apt-cache search gpio
的apt-get软件包列表,然后找到所需的工具。
答案 0 :(得分:1)
您可以将接收启用保持为低,这意味着您将收到自己的传输。这样你就可以知道传输何时完成,然后可以将Tx设置为低电平。然后只需从响应中过滤传输。
例如。对于你的传输例程:
synchronized(mutex) {
transmitEnable.high();
awaitingEcho = true;
expectedEcho = "test\n";
serial.writeln("test");
}
和接收:
synchronized(mutex) {
data = event.getAsciiString();
if (awaitingEcho && data.contains(expectedEcho)) {
transmitEnable.low();
data = data.replace(expectedEcho, EMPTY);
expectedEcho = null;
}
}