我正在构建这个应该转发中继的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)
但是我想开始接力我放入什么?我怎么理解这个?
答案 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}