{"id":1205,"date":"2022-06-01T09:45:57","date_gmt":"2022-06-01T07:45:57","guid":{"rendered":"https:\/\/www.domedia.net\/?p=1205"},"modified":"2024-02-23T11:49:56","modified_gmt":"2024-02-23T10:49:56","slug":"home-assistant-and-serial-control-rs-232-422-485-how-to-do-it","status":"publish","type":"post","link":"https:\/\/www.domedia.net\/?p=1205&lang=en","title":{"rendered":"Home-Assistant and Serial Control (RS-232\/422\/485): How to do it ?"},"content":{"rendered":"<p>Even if it becomes less and less common years after years, there are still some devices in audiovisual pro that are controlable through serial port (RS-232, 422, 485). It allows very efficient and precise control of devices, and also if needed feedback of devices for a stable control.<\/p>\r\n<p><!--more--><\/p>\r\n<p>Main problem is to find an interface for physical interface with devices controlled. One easy and logical solution is to use ESP, tha allows a lot of flexibility for interface. Unhappy ESP works with 3V3 logical level while serial ports such as RS-232 use voltages between -25V and +25V at maximum, which is completely incompatible with ESP. Direct connection of a serial RS-232 port with ESP GPIO would destroy immediately the ESP ! It is mandatory to use an interface between the ESP and serial port with an electronic circuit such as <a href=\"https:\/\/www.analog.com\/en\/products\/MAX232.html\" target=\"_blank\" rel=\"noopener\">MAX232<\/a> from Maxim that will do the logical conversion of electrical levels. An other easier solution is to use an all build board, like for example, the <a href=\"https:\/\/www.kincony.com\/esp32-tuya-iot-adapter.html\" target=\"_blank\" rel=\"noopener\">Tuya Adapter<\/a> (Less than 20 bucks on Aliexpress) made by Kincony.<\/p>\r\n\r\n<figure class=\"wp-block-table\">\r\n<table>\r\n<tbody>\r\n<tr>\r\n<td><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1179 alignleft\" src=\"https:\/\/www.domedia.net\/wp-content\/uploads\/2022\/06\/kincony-tuya-adapter-4-300x300.jpeg\" alt=\"Kincony Tuya Adapter\" width=\"300\" height=\"300\" \/><\/td>\r\n<td><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1180 alignright\" src=\"https:\/\/www.domedia.net\/wp-content\/uploads\/2022\/06\/Screenshot_20240220_113838-300x148.png\" alt=\"Kincony Tuya Adapter (Schematic)\" width=\"300\" height=\"148\" \/><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/figure>\r\n\r\n<p>The board has been designed at first to interface with Tuya equipments but we are going to use it as RS-232 or RS-485 interface (depending of a jumper on the board). To power the board it can be done easily using either the standard round power connector or through the Phoenix one. RS-232 connection is done through the sub-d9 and RS-485 on the Phoenix connector.<\/p>\r\n<p>We need now to prepare an ESPHome sketch to overwrite the existing manufacturer firmware and be able to integrate it easily in Home-Assistant.<\/p>\r\n<p>Configuration is going to be quite simple and I&rsquo;m going to share 2 use cases. First we&rsquo;ll start with control of a Meridian Audio Processor. Protocol supplied by manufacturer is avalaible on <a href=\"https:\/\/www.domedia.net\/wp-content\/uploads\/2024\/02\/ControlInterfaceSpecification_SL1xx_V3-0-0_20100623.pdf\" target=\"_blank\" rel=\"noopener\">this link<\/a>. First thing we need is communication parameters: for a serial link it implies speed in bauds, stop bit, and parity. In protocol document it&rsquo;s indicated 9600 bauds, 1 stop bit and no parity. We get luck, it&rsquo;s nearly default ESPHome settings for serial port so we&rsquo;ll just need to configure speed at 9600 bauds.<\/p>\r\n<p>For wiring we just need to connect 3 wires: RX, TX and GND (Ground). Depending of devices, RX and TX will need to be crossed or straight between Kincony and device controlled (no scientific rule about crossing or not !).<\/p>\r\n<p>We need now to determine syntax of \u00ab\u00a0messages\u00a0\u00bb for control of the device. Protocol indicates we need just to send 2 characters sometimes with an extra argument and ends with \u00ab\u00a0Carriage Return\u00a0\u00bb. We&rsquo;ll just need to put that string in uart.write command in ESPHome code. Carriage Return is an invisible character that encodes the return at begin of line, it&rsquo;s most of time encoded as CR or here for ESPHome with the escape characters so: \\r . It&rsquo;s quite common that commands are ended by CR or LF (Line Feed) or both. Here programmer by default has included both in code.<\/p>\r\n<p>For example to switch Meridian processor on TV input, command will be: <strong>TV\\r\\n<\/strong><\/p>\r\n<pre><strong>esphome:\r\n  name: esp-meridian\r\n  platform: ESP32\r\n  board: esp32dev\r\n\r\nlogger:\r\n\r\nweb_server:\r\n\r\nota:\r\n\r\nwifi:\r\n  networks:\r\n  - ssid: !secret wifi_ssid\r\n    password: !secret wifi_passwd\r\n\r\ncaptive_portal:\r\n\r\napi:\r\n  reboot_timeout: 10min\r\n\r\nbutton:\r\n  - platform: template\r\n    name: Meridian CD input\r\n    on_press:\r\n      - uart.write: \"TV\\r\\n\"\r\n      - delay: 1s\r\n      - uart.write: \"VN90\\r\\n\"\r\n      - delay: 20s\r\n      - uart.write: \"VN90\\r\\n\"\r\n  - platform: template\r\n    name: Meridian DV input\r\n    on_press:\r\n      - uart.write: \"DV\\r\\n\"\r\n  - platform: template\r\n    name: Meridian Stanby\r\n    on_press:\r\n      - uart.write: \"SB\\r\\n\"\r\n\r\nswitch:\r\n  - platform: template\r\n    name: Meridian Audio Direct\r\n    id: direct\r\n    optimistic: true\r\n    restore_mode: restore_default_off\r\n    internal: false\r\n    on_turn_on:\r\n      - uart.write: \"PN0\\r\\n\"\r\n      - switch.turn_off: cinema\r\n      - switch.turn_off: music \r\n      - switch.turn_off: thx\r\n  - platform: template\r\n    name: Meridian Audio Cinema\r\n    id: cinema\r\n    optimistic: true\r\n    restore_mode: restore_default_off\r\n    internal: false\r\n    on_turn_on:\r\n      - uart.write: \"PN12\\r\\n\"\r\n      - switch.turn_off: direct\r\n      - switch.turn_off: music\r\n      - switch.turn_off: thx\r\n  - platform: template\r\n    name: Meridian Audio Music\r\n    id: music\r\n    optimistic: true\r\n    restore_mode: restore_default_off\r\n    internal: false\r\n    on_turn_on:\r\n      - uart.write: \"PN1\\r\\n\"\r\n      - switch.turn_off: cinema\r\n      - switch.turn_off: direct\r\n      - switch.turn_off: thx\r\n  - platform: template\r\n    name: Meridian Audio THX\r\n    id: thx\r\n    optimistic: true\r\n    restore_mode: restore_default_off\r\n    internal: false\r\n    on_turn_on:\r\n      - uart.write: \"PN13\\r\\n\"\r\n      - switch.turn_off: cinema\r\n      - switch.turn_off: music\r\n      - switch.turn_off: direct\r\n\r\nuart:\r\n  tx_pin: GPIO17\r\n  rx_pin: GPIO16\r\n  baud_rate: 9600\r\n<\/strong><\/pre>\r\n<p>In this second case, we are going to control a Loewe TV that has a serial port on RJ-11 connector (quite unusual connector for RS-232). Protocol supplied by manufacturer is avalaible on <a href=\"https:\/\/www.domedia.net\/wp-content\/uploads\/2024\/02\/ControlInterfaceSpecification_SL1xx_V3-0-0_20100623.pdf\" target=\"_blank\" rel=\"noopener\">this link<\/a>. We are going to use same logic as previously.<\/p>\r\n<p>For serial port parameters, we are in same configuration.<\/p>\r\n<p>For commands to send, we are in quite similar case. Little change here, we are going to control volume which implies to send values in a dynamic way to device. Using lambda, we&rsquo;ll be able to build dynamically string to send at TV (\u00ab\u00a0data volume XX\u00a0\u00bb with XX being volume level requested). Value will be stored in a local variable in ESPHome that&rsquo;ll be avalaible directly in HA so we can adjust volume as we wish (common use is with a bargraph).<\/p>\r\n<pre><strong>esphome:\r\n  name: esp-tv-loewe\r\n  platform: ESP32\r\n  board: esp32dev\r\n\r\nlogger:\r\n\r\nweb_server:\r\n\r\nota:\r\n\r\nwifi:\r\n  networks:\r\n  - ssid: !secret wifi_ssid\r\n    password: !secret wifi_passwd\r\n\r\ncaptive_portal:\r\n\r\napi:\r\n  reboot_timeout: 10min\r\n\r\nbutton:\r\n  - platform: template\r\n    name: TV HDMI1\r\n    on_press:\r\n      - uart.write: \"prog -6\\r\\n\"\r\n  - platform: template\r\n    name: TV HDMI2\r\n    on_press:\r\n      - uart.write: \"prog -7 \\r\\n\"\r\n\r\nswitch:\r\n  - platform: template\r\n    name: \"TV mute\"\r\n    optimistic: True\r\n    turn_on_action: \r\n      - uart.write: \"data mute 1\\r\\n\"\r\n    turn_off_action: \r\n      - uart.write: \"data mute 0\\r\\n\"\r\n  - platform: template\r\n    name: \"Power tv\"\r\n    assumed_state: True\r\n    optimistic: True\r\n    turn_on_action: \r\n      - uart.write: \"power tv\\r\\n\"\r\n    turn_off_action: \r\n      - uart.write: \"power off\\r\\n\"\r\n\r\nnumber:\r\n  - platform: template\r\n    name: \"TV Volume\"\r\n    id: test\r\n    optimistic: true\r\n    min_value: 0\r\n    max_value: 95\r\n    step: 1\r\n    on_value:\r\n       - uart.write: !lambda  \r\n                      char buf[128];\r\n                      sprintf(buf, \"data volume %.1f\\r\\n\", id(test).state);\r\n                      std::string s = buf;\r\n                      return std::vector( s.begin(), s.end() );\r\n\r\nuart:\r\n  tx_pin: GPIO17\r\n  rx_pin: GPIO16\r\n  baud_rate: 9600\r\n<\/strong><\/pre>\r\n<p><strong>Few key points to get your serial control working:<\/strong><\/p>\r\n<ul>\r\n<li>wiring between controlled device and ESP board <strong>might need to reverse RX and TX<\/strong> (depending of devices wiring will need to be straight or crossed !). Wiring will be done most of time on SUB-D9 but con be more exotic connectors such as RJ-11 for our Loewe TV.<\/li>\r\n<li>Be careful to <strong>configure properly speed, parity and stop bit<\/strong> (depending of protocol documentation from manufacturer).<\/li>\r\n<li><strong>be able to get protocol documentation supplied by manufacturer<\/strong> (it&rsquo;s impossible to guess control protocol if you are unable to get from manufacturer, each manufacturer has its own protocol that can even be different for different devices from same manufacturer).<\/li>\r\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>Even if it becomes less and less common years after years, there are still some devices in audiovisual pro that are controlable through serial port (RS-232, 422, 485). It allows very efficient and precise control of devices, and also if needed feedback of devices for a stable control.<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"categories":[46],"tags":[673,507,229,677,679,681,683,685,675,687],"class_list":["post-1205","post","type-post","status-publish","format-standard","hentry","category-technology","tag-esphome","tag-ha-en","tag-home-assistant-en","tag-kincony-en","tag-rs-232-en","tag-rs-422-en","tag-rs-485-en","tag-serial-en","tag-serial-port","tag-tuya-adapter-en"],"_links":{"self":[{"href":"https:\/\/www.domedia.net\/index.php?rest_route=\/wp\/v2\/posts\/1205","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.domedia.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.domedia.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.domedia.net\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.domedia.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1205"}],"version-history":[{"count":5,"href":"https:\/\/www.domedia.net\/index.php?rest_route=\/wp\/v2\/posts\/1205\/revisions"}],"predecessor-version":[{"id":1211,"href":"https:\/\/www.domedia.net\/index.php?rest_route=\/wp\/v2\/posts\/1205\/revisions\/1211"}],"wp:attachment":[{"href":"https:\/\/www.domedia.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1205"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.domedia.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1205"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.domedia.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1205"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}