{"id":2676,"date":"2024-07-14T05:29:39","date_gmt":"2024-07-14T05:29:39","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=2676"},"modified":"2024-07-14T05:29:40","modified_gmt":"2024-07-14T05:29:40","slug":"getting-started-with-rs-485-and-modbus-rtu-part-3-communication-with-device","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=2676","title":{"rendered":"Getting Started with RS-485 and Modbus-RTU Part 3: Communication with Device"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"700\" height=\"271\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Serial-Communications-Protocols-Part-Four-RS-485-1-1.png\" alt=\"\" class=\"wp-image-2677\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Serial-Communications-Protocols-Part-Four-RS-485-1-1.png 700w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Serial-Communications-Protocols-Part-Four-RS-485-1-1-300x116.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Serial-Communications-Protocols-Part-Four-RS-485-1-1-400x155.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Serial-Communications-Protocols-Part-Four-RS-485-1-1-250x97.png 250w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>In this third and final part guide on ModBus-RTU, we shall communication with ModBus enabled device.<\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Device connection with MAX485.<\/li><li>Sending and receiving data.<\/li><li>Conde download.<\/li><li>Results.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">7. Device Connection with MAX485:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>The connection of ModBus enabled device as following:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"632\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_0060-1024x632.png\" alt=\"\" class=\"wp-image-2678\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_0060-1024x632.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_0060-300x185.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_0060-768x474.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_0060-1150x710.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_0060-750x463.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_0060-400x247.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_0060-250x154.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_0060.png 1536w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>The connection as simple as connected A terminal to A of the device to A of the MAX485 and in similar manner for B.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p class=\"has-vivid-red-color has-text-color has-medium-font-size\">Note: My device is operating from main voltage, if you don&#8217;t know how to handle this, please use other device that uses different low voltage.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">8. Sending and Receiving Data:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>The device uses standard 8byte to be transmitted as explained in the previous guide.<\/p>\n\n\n\n<p>However, when receiving the data, the data structure as following:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"300\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_0061-1024x300.jpg\" alt=\"\" class=\"wp-image-2679\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_0061-1024x300.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_0061-300x88.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_0061-768x225.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_0061-1536x450.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_0061-1150x337.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_0061-750x220.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_0061-400x117.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_0061-250x73.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_0061.jpg 1806w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>1st byte for the device address.<\/li><li>Second byte for the command.<\/li><li>Third byte represents number of bytes to be send and the rest are zero.<\/li><li>From byte 4 to byte 11 are the data.<\/li><li>bye 12 and 13 is for CRC.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p>In main.c source. We start with including the following header files:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;delay.h&quot;\n#include &quot;uart1.h&quot;\n#include &quot;MAX485.h&quot;<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>From the setup of the device, the address is 1. From the datasheet, the read command is 0x03 and to read Van is register 0x0018.Hence, we can declare it as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#define Addr 0x01\n#define Read 0x03\n#define VaR\t 0x18<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Declare the following datasize to hold the data to be read, which is 40 so we have enough space to receive all the data as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#define dataSize 40\n\nuint8_t data[dataSize]={0};<\/pre><\/div>\n\n\n\n<p>Define a volatile to indicate that UART received all the data as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">volatile uint8_t uartRxDone=0;<\/pre><\/div>\n\n\n\n<p>Float to store the read voltage from the device:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">float volt;<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>The following function is convert 4 bytes of byte to float as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">float bytes_to_float(uint8_t *data) {\n    uint32_t int_rep = ((uint32_t)data[0] &lt;&lt; 24) |\n                       ((uint32_t)data[1] &lt;&lt; 16) |\n                       ((uint32_t)data[2] &lt;&lt; 8) |\n                       (uint32_t)data[3];\n    return *(float*)&amp;int_rep;\n}<\/pre><\/div>\n\n\n\n<p>In main function:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\tDelay_Init(16000000);\n\tMAX485_RE_DE_Init();\n\tSetRS485Mode(Receiver);\n\tUART1_Pins_Init();\n\tUART1_Init();\n\tDelay(10);\n\tUART1_DMA_RX_Until_IDLE(data,dataSize);<\/pre><\/div>\n\n\n\n<p>Intialize the delay with frequency of 16MHz (default for STM32F4xx).<\/p>\n\n\n\n<p>Initialize the RE\/DE pin.<\/p>\n\n\n\n<p>Set the MAX485 into receiver mode.<\/p>\n\n\n\n<p>Initialize the UART1 by initialization of pins first then the UART peripheral.<\/p>\n\n\n\n<p>delay for 10ms for stability.<\/p>\n\n\n\n<p>Enable the RX in DMA with IDLE line detection.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>In while 1 loop:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\t\tDelay(10);\n\t\tRS485SendData(Addr,Read,VaR,4);\n\t\twhile(uartRxDone==0);\n\t\tuartRxDone=0;<\/pre><\/div>\n\n\n\n<p>Wait for 10ms.<\/p>\n\n\n\n<p>Send the request to read voltage.<\/p>\n\n\n\n<p>Wait until the STM32 read the uart and get the voltage value.<\/p>\n\n\n\n<p>Reset the uartRxDone to 0.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>In UART_RX_Complete function:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void UART_RX_Complete(void)\n{\n\tuartRxDone=1;\n\tvolt=bytes_to_float(&amp;data[3]);\n\tUART1_DMA_RX_Until_IDLE(data,dataSize);\n}<\/pre><\/div>\n\n\n\n<ul class=\"wp-block-list\"><li>Set the uartRxDone to 1.<\/li><li>get the voltage values readying the four bytes starting from address 3.<\/li><li>Launch the DMA again.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">9. Results:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Build the project and start debugging session and add volt variable to live expression and start the code.<\/p>\n\n\n\n<p>You should get the following results:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"34\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-13-at-7.46.12\u202fPM-1024x34.png\" alt=\"\" class=\"wp-image-2680\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-13-at-7.46.12\u202fPM-1024x34.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-13-at-7.46.12\u202fPM-300x10.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-13-at-7.46.12\u202fPM-768x25.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-13-at-7.46.12\u202fPM-1150x38.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-13-at-7.46.12\u202fPM-750x25.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-13-at-7.46.12\u202fPM-400x13.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-13-at-7.46.12\u202fPM-250x8.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/Screenshot-2024-07-13-at-7.46.12\u202fPM.png 1340w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Which is the same as shown in the device:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/07\/IMG_4136.heic\" alt=\"\" class=\"wp-image-2681\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Note: Due to the fluctuation in our main, the results are slightly different.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Happy coding \ud83d\ude09<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this third and final part guide on ModBus-RTU, we shall communication with ModBus enabled device. In this guide, we shall cover the following: Device connection with MAX485. Sending and receiving data. Conde download. Results. 7. Device Connection with MAX485: The connection of ModBus enabled device as following: The connection as simple as connected A [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,11,12],"tags":[],"class_list":["post-2676","post","type-post","status-publish","format-standard","hentry","category-embedded-systems","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2676"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2676"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2676\/revisions"}],"predecessor-version":[{"id":2682,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2676\/revisions\/2682"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2676"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2676"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2676"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}