需要帮助了解发送字节到串行端口

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了需要帮助了解发送字节到串行端口相关的知识,希望对你有一定的参考价值。

我正在构建这个应该转发中继的C#应用​​程序。它有一个USB转串口。手册说:

模块可以从上位监视器接收单字节(波特率9600):

Upper Monitor                   0x50            0x51
ICSE012A                                0xAB
ICSE013A                                0xAD (This is the one i have)
ICSE014A                                0xAC

收到0x51后,模块将转为正常工作状态。然后每个数据字节将直接控制继电器。每个位控制一个继电器(0标记开始,1标记停止)。阅读以下详细信息:

Bit: 0 // Controls relay 1
Bit: 1 // Controls relay 2

所以要启动继电器,我应该使用:This.SerialPort1.Write(0x51)

但后来我想开始接力我放入什么?我怎么理解这个?

答案

我有类似的项目ICSE013A:

Bus 001 Device 009: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
/dev/serial/by-path/platform-20980000.usb-usb-0:1.3:1.0-port0
/dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller-if00-port0
/sys/bus/usb-serial/drivers/pl2303/ttyUSB1

但我认为我遇到了一个错误或设计缺陷。

拔下并重新插入设备。

在第一个控制台中,运行永久性:

$ cat /dev/ttyUSB1

在第二个控制台中,运行

$ echo -e -n "x50" > /dev/ttyUSB1

运行几次;每次您在第一个控制台(ab,ac或ad)中收到确认。现在发送启动命令:

echo '51' | xxd -r -p >>/dev/ttyUSB1

你没有得到任何确认。第二次发送同一行:

echo '51' | xxd -r -p >>/dev/ttyUSB1

开关1打开,没有确认。发送50,开关关闭,没有确认:

echo '50' | xxd -r -p >>/dev/ttyUSB1

因此,命令的顺序很重要。一旦发送50-51,所有字节将控制继电器。对于随机时间运行的脚本,无法知道设备是否已经启动。一个解决方案可能是在/etc/rc.local中启动时运行启动:但是想象一下USB电源有一个小问题:你认为你可以控制继电器,实际上它们正在等待init。继电器设计不佳。这是我能找到的最便宜的:2个继电器4e,8r板9e。其他USB继电器要贵得多,但它具有抵抗初始化问题的逻辑:它们需要接收完整的帧,包括校验和......用于每个继电器命令。例如'A0 01 01 A2'或'01 05 00 00 FF 00 8C 3A'。

此外,在单个框架中对订单进行分组将失败。如果你在电力循环后做了

echo '50 51 03' | xxd -r -p >>/dev/ttyUSB1

它不会打开继电器。你必须逐个发送字节;一个简单的睡眠0.001(使用bash内部命令)似乎就足够了。行为可能因shell版本,内核和分发而异:

i=0.001
echo '50' | xxd -r -p >>/dev/ttyUSB1 ; sleep $i
echo '51' | xxd -r -p >>/dev/ttyUSB1 ; sleep $i
echo '03' | xxd -r -p >>/dev/ttyUSB1

现在,发送此命令:

echo '50 51 03' | xxd -r -p >>/dev/ttyUSB1

它会关闭继电器,而不提供确认。那么,如何重新确定?从软件来看,这似乎很复杂;根据硬件的不同,重启可能无法重置所有USB设备。重新加载pl2303是不够的。在普通桌面上,将整个USB堆栈卸载到usbcore应该允许重置设备。在rPi上,usbcore不是模块化的,卸载usbserial并不足够。

所以,对于我的rPi,我必须在/etc/rc.local启动时执行此操作

echo '50' | xxd -r -p >>/dev/ttyUSB1
echo '51' | xxd -r -p >>/dev/ttyUSB1

并假设设备不会断开连接

另外:不可能知道继电器的状态;当你想要改变一个继电器时,你需要记住(存储)其他继电器的状态。即使此方面由守护程序服务管理,如果您热重启服务,该服务也无法知道该板是否已初始化;有疑问的是,服务必须这样做,并在50-51-00之间发出适当的小睡眠;但是,如果它已经初始化,这可能会在短时间内激活继电器1,5和7。

不同的方法:我的主板有一个串口输入(USB插头左侧有4个空洞)。我焊接了几个引脚,并将其链接到USB串行适配器(Rx和Tx标记反转)。事情表现完全一样。

经过数小时的dychotomy,我找到了一个可以处理初始化的字符串,并且仍然可以在启动后使用。采用这种方法,OFF继电器不受影响; ON继电器在8ms内断开(不要试图添加电容,它可能会产生振荡)。根据受控设备对断开的敏感程度,这个小的关闭时间可以接受(或不接受):

echo '50 00 50 00 51 01 00 ZZ' | xxd -r -p >>/dev/ttyUSB1

其中ZZ是继电器控制字节。这是一个可行的替代模板:

echo '50 50 50 50 51 52 00 ZZ' | xxd -r -p >>/dev/ttyUSB1

编辑:经过几个小时的测试后,硬件板不可靠。这个简单的测试失败:每10或20秒,继电器处于OFF状态:

while true ; do echo -e -n "x03" > /dev/ttyUSB1 ; sleep 1 ; done

它非常慢,并且仍会触发固件内部的竞争问题......而且此测试通过板载USB插头和使用第三方串行端口适配器都失败了。 ICSE013A没什么好处的

另一答案

我已成功尝试在ubuntu上执行以下命令。 打开2个终端并键入$ su以获得root访问权限,或者您可以更改设备的权限

$chmod 777 /dev/ttyUSB0  

在我的机器上 lsusb输出:总线003器件018:ID 067b:2303 Prolific Technology,Inc。PL2303串行端口 dmesg输出:[11837.715851] usb 3-2:pl2303转换器现在连接到ttyUSB0

1.在第一个终端上 键入以下内容以读取设备ID:

$cat /dev/ttyUSB0 | hexdump -C  

2.在第二个终端 键入以下命令以获取设备ID(我的是0xAB,4通道)

$ echo -e -n "x50" > /dev/ttyUSB0 

3.取下设备并检查第一个终端的输出

$cat /dev/ttyUSB0 | hexdump -C  
00000000  ab                                                |.|    
00000001

4.在第二个终端上按照命令序列: 握手:

$ echo -e -n "x50" > /dev/ttyUSB0   

要激活继电器控制器:

$ echo -e -n "x51" > /dev/ttyUSB0   

要关闭所有继电器:

$ echo -e -n "xff" > /dev/ttyUSB0   

要打开所有继电器:

$ echo -e -n "x00" > /dev/ttyUSB0   

要打开第一个继电器:

$ echo -e -n "x01" > /dev/ttyUSB0   

打开第四个继电器:

$ echo -e -n "x04" > /dev/ttyUSB0     
另一答案

其实

$ echo -e -n "x04" > /dev/ttyUSB0     

打开第三个继电器。它是每个中继一位,我们必须用二进制思考。因此,要打开第四个继电器,需要更改第4个位,如:

$ echo -e -n "x08" > /dev/ttyUSB0     

希望这澄清一下。

以上是关于需要帮助了解发送字节到串行端口的主要内容,如果未能解决你的问题,请参考以下文章

从串行端口发送十六进制数据的问题

在串行端口(QtSerialPort)读取传入字节的连续流

RS-485 串行端口波特率性能效率

正确类型转换字节以写入 C++ 中的串行句柄

在 C 中通过串行/COM 端口发送 MIDI 数据时出现问题

可以在网站上使用 pySerial 打开并将数据发送到本地计算机上的串行端口吗?