Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python PySerial,通过半双工RS-485转接板使用Beaglebone黑埃自动RTS_Python_Pyserial_Beagleboneblack_Angstrom Linux_Rs485 - Fatal编程技术网

Python PySerial,通过半双工RS-485转接板使用Beaglebone黑埃自动RTS

Python PySerial,通过半双工RS-485转接板使用Beaglebone黑埃自动RTS,python,pyserial,beagleboneblack,angstrom-linux,rs485,Python,Pyserial,Beagleboneblack,Angstrom Linux,Rs485,我正在尝试使用Beaglebone Black运行Angstrom(3.8内核)与9600-N-8-1的半双工RS-485网络上的设备通信 我正试图使用一个RS-485转接板类似于这个:,除了芯片是一个MAX3485。我买了一块预先组装好的电路板,上面有插脚和端子排。我的一个朋友用示波器测试了它,并宣布RS-485板可以工作。该板有五个引脚连接到BBB。3-5V(电源)、RX-I、TX-O、RTS和GND 我已禁用BBB上的HDMI支持,以便UART4\u RTSn和UART4\u CTSn引脚

我正在尝试使用Beaglebone Black运行Angstrom(3.8内核)与9600-N-8-1的半双工RS-485网络上的设备通信

我正试图使用一个RS-485转接板类似于这个:,除了芯片是一个MAX3485。我买了一块预先组装好的电路板,上面有插脚和端子排。我的一个朋友用示波器测试了它,并宣布RS-485板可以工作。该板有五个引脚连接到BBB。3-5V(电源)、RX-I、TX-O、RTS和GND

我已禁用BBB上的HDMI支持,以便
UART4\u RTSn
UART4\u CTSn
引脚可用

    mkdir /mnt/boot
    mount /dev/mmcblk0p1 /mnt/boot
    nano /mnt/boot/uEnv.txt
    #change contents of uEnv.txt to the following:
    optargs=quiet capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN 
然后,我发现了一个覆盖层,用于启用带有RTS/CTS控制的UART-4:

            /*
     * Modified version of /lib/firmware/BB-UART4-00A0.dtbo to add RTS so we can reset Arduinos
     */
    /dts-v1/;
    /plugin/;

    / {
      compatible = "ti,beaglebone", "ti,beaglebone-black";
      part-number = "BB-UART4-RTS";
      version = "00A0";
      exclusive-use = "P9.13", "P9.11", "P9.15", "P8.33", "P8.35", "uart4";

      fragment@0 {
        target = <0xdeadbeef>;

        __overlay__ {


          pinmux_bb_uart4_pins {
            pinctrl-single,pins = <
              0x070 0x26   /* P9_11 = UART4_RXD = GPIO0_30,    MODE6 */
              0x074 0x06   /* P9_13 = UART4_TXD = GPIO0_31,    MODE6 */
              /* need to enable both RTS and CTS, if we only turn on RTS then driver gets confused */
              0x0D0 0x26   /* P8_35 = UART4_CTSN = lcd_data12, MODE6 */
              0x0D4 0x06   /* P8_33 = UART4_RTSN = lcd_data13, MODE6 */
              /* 0x040 0x0F   /* P9_15 = GPIO1_16 = GPIO48,       MODE7  failed attempt to put DTR on gpio */
            >;
            linux,phandle = <0x1>;
            phandle = <0x1>;
          };
        };
      };

      fragment@1 {
        target = <0xdeadbeef>;

        __overlay__ {
          status = "okay";
          pinctrl-names = "default";
          pinctrl-0 = <0x1>;
        };
      };

      __symbols__ {
        bb_uart4_pins = "/fragment@0/__overlay__/pinmux_bb_uart4_pins";
      };

      __fixups__ {
        am33xx_pinmux = "/fragment@0:target:0";
        uart5 = "/fragment@1:target:0"; /* Not a mistake: UART4 is named uart5 */
      };

      __local_fixups__ {
        fixup = "/fragment@1/__overlay__:pinctrl-0:0";
      };
    };
像这样把485板连接到BB上

    3-5V to P9_05 (VDD_5V)
    RX-I to P9_13 (UART4_TXD) 
    TX-O to P9_11 (UART4_RXD)
    RTS  to P8_33 (UART4_RTSn)
    GND  to P9_01 (DGND)
在python中,我尝试使用如下串行端口:

    import serial
    ser = serial.Serial('/dev/ttyO4', baudrate=9600, rtscts=True)
    ser.write(list_of_byte_dat)
echo -en '\x02\xFD\xCD......' > /dev/ttyO4
我知道该程序可以工作,因为当我在
/dev/ttyUSB0
上使用USB到RS-485转换器并设置
rtscts=False
时,双向通信工作正常。但我无法使用RS-485板使通信正常工作

我有两个问题与RS-485板,都处理RTS

  • 板上的RTS工作方式与我预期的相反。当我在rs485板的RTS引脚上施加电压时,板上的RTS led熄灭,板将不传输。当我从RTS引脚移除电压时,RTS led亮起,电路板将进行传输。如何反转BBB上UART_RTSn引脚的极性

    临时解决方案:我制作了一个小脚本程序,它使用UART4\u RTSn pin作为输入。当UART4_RTSn引脚关闭时,它打开不同的GPIO,当UART4_RTSn引脚打开时,它关闭相同的GPIO引脚。然后将rs485板上的RTS引脚连接到GPIO引脚,而不是UART4\U RTSn引脚。

    这似乎是一个糟糕的解决方案,但当从命令行回显
    /dev/ttyO4
    时,它确实会使RS485板上的RTS在正确的时间启动

    如何通过调整硬件配置或更改pyserial中的配置来更改
    UART4\u RTSn
    引脚的极性

    这就引出了第二个问题

  • 正如我在问题1中所述,
    UART4\u RTSn
    pin将在向tty端口回显值时自动(但向后)工作,如下所示:

        import serial
        ser = serial.Serial('/dev/ttyO4', baudrate=9600, rtscts=True)
        ser.write(list_of_byte_dat)
    
    echo -en '\x02\xFD\xCD......' > /dev/ttyO4
    
    这将使
    UART4\u RTSn
    led在传输数据时闪烁。如果我没有上面提到的bonescript设置它,那么它将正常打开,并在传输时闪烁。如果我使用我的bonescript hack,它将正常关闭,并在传输时闪烁(这是我想要的)。但是,这仅在从命令行使用echo时有效。当我使用python并设置串行端口时,
    UART4\u RTSn
    pin变为非活动状态。它在传输时不会闪烁。一旦我用python做了陈述:

    ser = serial.Serial('/dev/ttyO4', baudrate=9600, rtscts=True)
    
    UART4\u RTSn
    引脚关闭并保持关闭状态。使用
    ser.write(stuff)
    发送信息时,它不会闪烁。因此,rs485板未启用传输。如何使
    UART4\u RTSn
    pin在pyserial中自动工作?我试过设置
    rtscts=False
    ,但没有成功

    我可以使用
    ser.setRTS(True)
    ser.setRTS(False)
    手动切换pin值,这样我就知道我使用的是正确的pin,并且正在识别它。但我不想直接切换UART4_RTSn引脚。我希望它在串口传输数据时自动工作,在使用echo时自动工作,但在Python中不工作

  • 任何帮助都将不胜感激

  • 您可以使用pnp晶体管/p沟道mosfet/逻辑门非逆变器,如7404

  • 可能在写操作之后必须刷新写缓冲区 ser.write(…) 弗拉什爵士()


  • RTS通常是一个有效的低电平信号,我怀疑您看到使用回波传输数据的原因是它没有使用RTS/CTS(保持高电平),因此只能传输数据

    根据一篇关于

    如果您启用硬件流控制(“手动终端”中的CRTSCTS),或 “stty crtscts-F/dev/ttyam0”或pySerial rtscts=True),然后发送 将仅在断言CTS时发生。RTS将被断言,除非 当内核输入缓冲区已满时。内核输入缓冲区大约是 一页或4KB,因此您的应用程序必须远远落后于其 在RTS实际更改之前读取

    因此,检查CTS是否在电路板外部被断言(拉至地)。然而,我不认为这将给你的RTS,你需要的正确控制

    因此,对于您的应用程序,您应该在写入之前禁用硬件流控制(
    rtscts=False
    ),并在写入之后使用
    setRTS(1)
    手动控制RTS


    如果您仍然看不到数据传输到设备,请尝试交换A&B导线-A/B标签在RS485设备上不一致(令人沮丧)。如果可能,最好在您自己的应用程序中使用D+/D标记。

    使用ioctl更改逻辑级别

    98         struct serial_rs485 rs485conf;
     99 
    100         /* Enable RS485 mode: */
    101         rs485conf.flags |= SER_RS485_ENABLED;
    102 
    103         /* Set logical level for RTS pin equal to 1 when sending: */
    104         rs485conf.flags |= SER_RS485_RTS_ON_SEND;
    105         /* or, set logical level for RTS pin equal to 0 when sending: */
    106         rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);
    107 
    108         /* Set logical level for RTS pin equal to 1 after sending: */
    109         rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
    110         /* or, set logical level for RTS pin equal to 0 after sending: */
    111         rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);
    112 
    113         /* Set rts delay before send, if needed: */
    114         rs485conf.delay_rts_before_send = ...;
    

    您正在使用的实际RS485适配器是什么?我正在使用此适配器:。图中显示了一个max485芯片,描述中说明了一个max485芯片,这就是它是如何到达的。@TimothyVann你看过这个了吗?我还没有找到解决这个问题的确切软件解决方案。然而,我找到了一个硬件解决方案。GHI Electronics使用MAX13487制造RS 484转换器。该芯片具有内置的自动方向控制功能,因此您无需在beaglebone上设置RTS/CTS引脚,该芯片可自动为您提供方向控制。即使这块木板不是为beaglebone设计的,它也能完美地工作。它有一个更好的尝试