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

时间:2014-11-13 16:32:49

标签: c# io hex

我正在构建这个应该转发中继的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)

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

4 个答案:

答案 0 :(得分:3)

我有类似的项目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没有什么好处

答案 1 :(得分:1)

我已成功尝试在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。在第一个终端
输入以下内容以阅读deivce 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     

答案 2 :(得分:0)

实际上

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

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

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

希望这澄清。

答案 3 :(得分:0)

我遇到了与@benoit-pierre-demaine相同的问题,但是我想出了另一种方法来解决该问题。

由于无法从程序确定状态,因此我决定从操作系统初始化设备,并假定从应用程序开始使用设备时就已经对其进行了初始化。

我在/etc/udev/rules.d/ICSE014A.rules中创建了一个新的udev规则,内容如下:

SUBSYSTEM=="tty", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", ACTION=="add", RUN+="/usr/local/bin/icse014a-init"

然后我写了一个小脚本来初始化设备,该设备使用/usr/local/bin/icse014a-init处的脚本插入设备时:

#!/bin/sh

echo '50' | xxd -r -p > ${DEVNAME}
sleep 1

echo '51' | xxd -r -p > ${DEVNAME}