title: Python PySerial with Auto RTS through Half-Duplex RS-485 breakout board using Beaglebone Black Angstrom
body: <p>I'm trying to use a Beaglebone Black running Angstrom (3.8 kernel) to communicate with devices on a half-duplex RS-485 network at 9600-N-8-1.  </p>
  
  <p>I'm trying to use an RS-485 Breakout board similar to this one: <a href="https://www.sparkfun.com/products/10124" rel="noreferrer">https://www.sparkfun.com/products/10124</a>, except the chip is a MAX3485 <a href="http://www.maximintegrated.com/datasheet/index.mvp/id/1079" rel="noreferrer">http://www.maximintegrated.com/datasheet/index.mvp/id/1079</a>.  I bought the board pre-assembled with pins and a terminal strip.  A friend of mine tested it with an oscilloscope and declared that the RS-485 board does work.  The board has five pins that connect to the BBB. 3-5V (Power), RX-I, TX-O, RTS, and GND.  </p>
  
  <p>I've disabled HDMI support on the BBB so that the <code>UART4_RTSn</code> and <code>UART4_CTSn</code> pins will be available.</p>
  
  <pre><code>    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 
  </code></pre>
  
  <p>Then I've found an overlay to enable UART-4 with RTS/CTS control:</p>
  
  <pre><code>            /*
       * 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 = &lt;0xdeadbeef&gt;;
  
          __overlay__ {
  
  
            pinmux_bb_uart4_pins {
              pinctrl-single,pins = &lt;
                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 */
              &gt;;
              linux,phandle = &lt;0x1&gt;;
              phandle = &lt;0x1&gt;;
            };
          };
        };
  
        fragment@1 {
          target = &lt;0xdeadbeef&gt;;
  
          __overlay__ {
            status = "okay";
            pinctrl-names = "default";
            pinctrl-0 = &lt;0x1&gt;;
          };
        };
  
        __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";
        };
      };
  </code></pre>
  
  <p>Compiled and Enabled the overlay:</p>
  
  <pre><code>    cd /lib/firmware
      dtc -O dtb -o BB-UART4-RTS-00A0.dtbo -b 0 -@ BB-UART4-RTS-00A0.dts 
      echo BB-UART4-RTS:00A0  &gt; /sys/devices/bone_capemgr.*/slots
  </code></pre>
  
  <p>Hooked up the 485 board to the BB like this</p>
  
  <pre><code>    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)
  </code></pre>
  
  <p>In python I'm trying to use the serial port like this:</p>
  
  <pre><code>    import serial
      ser = serial.Serial('/dev/ttyO4', baudrate=9600, rtscts=True)
      ser.write(list_of_byte_dat)
  </code></pre>
  
  <p>I know the program works because when I use a USB to RS-485 converter on <code>/dev/ttyUSB0</code> and set <code>rtscts=False</code> the communication works in both directions just fine. But I can't get communication to work correctly using the RS-485 board.</p>
  
  <p>I have two issues with the RS-485 board, both deal with RTS.</p>
  
  <ol>
  <li><p>The RTS on the board works backwards from the way I expect it to.  When I apply voltage on the RTS pin of the rs485 board the RTS led on the board goes off and the board will not transmit.  When I remove voltage from the RTS pin the RTS led turns on and the board will transmit.  How do I reverse the polarity of the UART_RTSn pin on the BBB?  </p>
  
  <p><code>Temporary solution: I've made a small bone script program that uses UART4_RTSn pin as input.  It turns on a different GPIO when the UART4_RTSn pin is off and turns off that same GPIO pin when the UART4_RTSn pin is on.  Then hooked up the RTS pin on the rs485 board to the GPIO pin instead of the UART4_RTSn pin.</code></p>
  
  <p>This seems to be a poor solution, but it does make the RTS on the RS485 board come on at the correct time when echoing to the <code>/dev/ttyO4</code> from the command line.  </p>
  
  <p>How can I change the polarity of the <code>UART4_RTSn</code> pin either by adjusting the hardware configuration or by changing the configuration in pyserial?</p>
  
  <p>This brings me to the second issue</p></li>
  <li><p>As I stated in problem 1 the <code>UART4_RTSn</code> pin will work automatically (but backwards) for me when echoing a value to the tty port like this:</p>
  
  <pre><code>echo -en '\x02\xFD\xCD......' &gt; /dev/ttyO4
  </code></pre>
  
  <p>This will make the <code>UART4_RTSn</code> led blink while the data is being transmitted.  If I have it setup without the bonescript mentioned above, then it will be on normally and blink off while transmitting.  If I use my bonescript hack then it will be off normally and blink on while transmitting (which is what I want).  However this only works when using echo from the command line.  When I use python and setup the serial port the <code>UART4_RTSn</code> pin becomes inactive.  It will not blink while transmitting.  As soon as I make the statement in python:</p>
  
  <pre><code>ser = serial.Serial('/dev/ttyO4', baudrate=9600, rtscts=True)
  </code></pre>
  
  <p>The <code>UART4_RTSn</code> pin shuts off and stays off.  It does not blink when sending information using <code>ser.write(stuff)</code>.  As a result the rs485 board is not enabled for transmission.  How do I get the <code>UART4_RTSn</code> pin to work automatically in pyserial?  I've tried setting <code>rtscts=False</code> and it did not work.  </p>
  
  <p>I am able to use <code>ser.setRTS(True)</code> or <code>ser.setRTS(False)</code> to manually toggle the pin value so I know I'm using the correct pin and that it is being recognized.  But I don't want to toggle the UART4_RTSn pin directly.  I want it to work automatically when the serial port is transmitting data and it does when using echo, but not in Python.</p></li>
  </ol>
  
  <p>Any help would be greatly appreciated.</p>