【问题标题】:Need help understading sending bytes to serial port需要帮助了解向串口发送字节
【发布时间】:2014-11-13 16:32:49
【问题描述】:

我正在构建这个 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)

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

【问题讨论】:

  • 0x51 是十六进制,转换为二进制为 01010001,这可能意味着打开继电器 1、5 和 7。所以只启动继电器 1,只需发送二进制 00000001(十六进制 @ 987654330@)
  • 我有继电器板附带的这个软件。在软件中我需要打开连接并点击“打开sele”并在0x01之前关闭程序。该软件必须以某种方式激活该板。

标签: c# io hex


【解决方案1】:

我有类似的物品 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)中收到一个 ack。现在发送启动命令:

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

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

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

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

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

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

此外,将订单分组到一个框架中也会失败。如果重启后你这样做了

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

它不会打开继电器。您必须一个一个地发送字节;一个简单的 sleep 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

它会关闭中继,而不提供 ack。那么,如何确定重置板?从软件上看,这似乎很复杂;根据硬件,重新启动可能不会重置所有 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 标记是倒置的)。事情的表现完全一样。

经过数小时的二分法,我找到了一个可以处理初始化的字符串,并且在启动后仍然可以使用。使用这种方法,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 秒,继电器就会处于关闭状态:

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

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

【讨论】:

    【解决方案2】:

    我已成功尝试在 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 "\x00" > /dev/ttyUSB0 中更正从“off”到“on”的错误打印
    【解决方案3】:

    其实

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

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

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

    希望这可以澄清。

    【讨论】:

      【解决方案4】:

      我遇到了与@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}
      

      【讨论】:

        猜你喜欢
        • 2021-05-23
        • 2017-06-19
        • 2016-05-03
        • 1970-01-01
        • 2021-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多