{"id":4158,"date":"2026-01-15T09:39:26","date_gmt":"2026-01-15T09:39:26","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=4158"},"modified":"2026-01-15T09:40:09","modified_gmt":"2026-01-15T09:40:09","slug":"modbus-sensor-emulation-part-2-establishing-communication","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=4158","title":{"rendered":"Modbus Sensor Emulation Part 2: Establishing Communication"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/01\/ChatGPT-Image-Jan-6-2026-at-09_38_15-AM-1-1024x683.png\" alt=\"\" class=\"wp-image-4159\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/01\/ChatGPT-Image-Jan-6-2026-at-09_38_15-AM-1-1024x683.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/01\/ChatGPT-Image-Jan-6-2026-at-09_38_15-AM-1-300x200.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/01\/ChatGPT-Image-Jan-6-2026-at-09_38_15-AM-1-768x512.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/01\/ChatGPT-Image-Jan-6-2026-at-09_38_15-AM-1-1150x767.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/01\/ChatGPT-Image-Jan-6-2026-at-09_38_15-AM-1-750x500.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/01\/ChatGPT-Image-Jan-6-2026-at-09_38_15-AM-1-400x267.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/01\/ChatGPT-Image-Jan-6-2026-at-09_38_15-AM-1-250x167.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/01\/ChatGPT-Image-Jan-6-2026-at-09_38_15-AM-1.png 1536w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Part 2 of this guide focuses on establishing and validating the communication link between a Modbus RTU master and the STM32-based slave using a simple echo mechanism. The master sends a complete Modbus RTU frame and the slave returns the same frame unchanged, allowing verification of UART configuration, RS-485 direction control, and protocol framing before moving to full Modbus register handling.<\/p>\n\n\n\n<p><\/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\">\n<li>Importing project to STM32CubeIDE.<\/li>\n\n\n\n<li>Slave configuration.<\/li>\n\n\n\n<li>Master configuration.<\/li>\n\n\n\n<li>Results.<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Importing Project to STM32CubeIDE:<\/h2>\n\n\n\n<p>Open STM32CubeIDE, select your workspace and click on Launch.<\/p>\n\n\n\n<p>From the IDE, click File and select STM32 Project Create\/Import as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"873\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_16-57-21-1024x873.jpg\" alt=\"\" class=\"wp-image-3997\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_16-57-21-1024x873.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_16-57-21-300x256.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_16-57-21-768x655.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_16-57-21-1150x981.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_16-57-21-750x640.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_16-57-21-400x341.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_16-57-21-250x213.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_16-57-21.jpg 1524w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Next, from Import STM32 Project, select STM32CubeMX\/STM32CubeIDE Project and click on Next as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"769\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_17-00-37-1024x769.jpg\" alt=\"\" class=\"wp-image-3998\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_17-00-37-1024x769.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_17-00-37-300x225.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_17-00-37-768x577.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_17-00-37-1150x863.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_17-00-37-750x563.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_17-00-37-400x300.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_17-00-37-250x188.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_17-00-37.jpg 1172w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Next, select the folder that contains the .ioc file and click on Finish as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"652\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_09-59-36-1024x652.jpg\" alt=\"\" class=\"wp-image-4131\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_09-59-36-1024x652.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_09-59-36-300x191.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_09-59-36-768x489.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_09-59-36-1536x977.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_09-59-36-1150x732.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_09-59-36-750x477.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_09-59-36-400x255.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_09-59-36-250x159.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_09-59-36.jpg 1760w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Now, the project is the project window.<\/p>\n\n\n\n<p>Repeat the same step for the other project.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">7. Slave Configuration:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Once both projects have been imported, open main.c for the slave project.<\/p>\n\n\n\n<p>In main.c file, in user code begin PV, declare the 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;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#define bufferSize 50\n\nuint8_t rs485_buffer[bufferSize];<\/pre><\/div>\n\n\n\n<p>We are declaring a buffer with size of 50 Byte to hold the received data. The buffer size can vary depending on the requirements. 50 Bytes is more than enough for our application.<\/p>\n\n\n\n<p>Next, in user code begin 0, declare the following 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;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)\n\n{\tif(huart-&gt;Instance==USART1)\n\t{\n\t\tHAL_UART_Transmit(huart, rs485_buffer, Size, 100);\n\n\t\tHAL_UARTEx_ReceiveToIdle_IT(&amp;huart1, rs485_buffer, bufferSize);\n\t}\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>This function will be called either when full 50 characters are received or IDLE line is detected.<\/p>\n\n\n\n<p>Once the function is called, transmit the data that being received and rearm the UART to receive the data in interrupt mode again.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>In user code begin 2 in main function, start the UART reception in interrupt mode with IDLE line detection as follows:<\/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;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">HAL_UARTEx_ReceiveToIdle_IT(&amp;huart1, rs485_buffer, bufferSize);<\/pre><\/div>\n\n\n\n<p>Thats all for the slave configuration. <\/p>\n\n\n\n<p>Save, build and run the project as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"34\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_11-12-13-1024x34.jpg\" alt=\"\" class=\"wp-image-4132\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_11-12-13-1024x34.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_11-12-13-300x10.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_11-12-13-768x26.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_11-12-13-1536x51.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_11-12-13-1150x38.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_11-12-13-750x25.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_11-12-13-400x13.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_11-12-13-250x8.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-31_11-12-13.jpg 1986w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">8. Master Configuration:<\/h2>\n\n\n\n<p>Open main.c file for the master.<\/p>\n\n\n\n<p>In user code being includes, include the 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;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;stdio.h&quot;<\/pre><\/div>\n\n\n\n<p>This will provide us access to printf functions.<\/p>\n\n\n\n<p>Next, in user code begin PV, declare the following variable:<\/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;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">uint8_t counter;<\/pre><\/div>\n\n\n\n<p>The variable will increase with each time the master transmit the data.<\/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;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#define BufferSize 50\n\nuint8_t TxBuffer[BufferSize];\nuint8_t RxBuffer[BufferSize];<\/pre><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Declare the buffer size (same as the salve which is 5 bytes).<\/li>\n\n\n\n<li>Tx and Rx buffer to hold the transmitted and received data.<\/li>\n<\/ul>\n\n\n\n<p>In user code begin 0, declare the following 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;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)\n\n{\tif(huart-&gt;Instance==USART1)\n\t{\n\n\n\t\tHAL_UARTEx_ReceiveToIdle_IT(&amp;huart1, RxBuffer, BufferSize);\n\t}\n}<\/pre><\/div>\n\n\n\n<p>Here, we are just rearming the UART to receive the data again.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>In user code begin 2 in main function.<\/p>\n\n\n\n<p>In user code begin 2 in main function, start the UART reception in interrupt mode with IDLE line detection as follows: <\/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;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">HAL_UARTEx_ReceiveToIdle_IT(&amp;huart1, RxBuffer, BufferSize);<\/pre><\/div>\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;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">uint16_t len=sprintf(TxBuffer,&quot;Counter = %d\\r\\n&quot;,++counter);\n\nHAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);\n\nHAL_UART_Transmit(&amp;huart1, TxBuffer, len, 100);\n\nHAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);\n\nHAL_Delay(100);<\/pre><\/div>\n\n\n\n<p>Since the master is based on STM32F411 which doesn&#8217;t support hardware flow for the RS485, we need to set\/reset the DE pin manually. Before starting the transmission, set the DE pin to high, transmit the data and set it back to low.<\/p>\n\n\n\n<p>This way, the master will be able to receive after the transmission has been handled.<\/p>\n\n\n\n<p>Thats all for the master configuration.<\/p>\n\n\n\n<p>Save the project, build it and run it in debugging mode on your STM32F4 board.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"38\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/03\/2025-03-15_10-56-27-1024x38.jpg\" alt=\"\" class=\"wp-image-3296\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/03\/2025-03-15_10-56-27-1024x38.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/03\/2025-03-15_10-56-27-300x11.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/03\/2025-03-15_10-56-27-768x29.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/03\/2025-03-15_10-56-27-1536x57.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/03\/2025-03-15_10-56-27-1150x43.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/03\/2025-03-15_10-56-27-750x28.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/03\/2025-03-15_10-56-27-400x15.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/03\/2025-03-15_10-56-27-250x9.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/03\/2025-03-15_10-56-27.jpg 1878w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\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>Add the TxBuffer and RxBuffer to the live expression and you should get the following:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"587\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/01\/Screen-Recording-2026-01-15-at-10.19.23-587x1024.gif\" alt=\"\" class=\"wp-image-4160\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/01\/Screen-Recording-2026-01-15-at-10.19.23-587x1024.gif 587w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/01\/Screen-Recording-2026-01-15-at-10.19.23-172x300.gif 172w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/01\/Screen-Recording-2026-01-15-at-10.19.23-768x1340.gif 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/01\/Screen-Recording-2026-01-15-at-10.19.23-880x1536.gif 880w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/01\/Screen-Recording-2026-01-15-at-10.19.23-750x1309.gif 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/01\/Screen-Recording-2026-01-15-at-10.19.23-400x698.gif 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2026\/01\/Screen-Recording-2026-01-15-at-10.19.23-250x436.gif 250w\" sizes=\"(max-width: 587px) 100vw, 587px\" \/><\/figure><\/div>\n\n\n<p><\/p>\n\n\n\n<p>Next, we shall develop the modbus protocol.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Stay tuned.<\/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>Part 2 of this guide focuses on establishing and validating the communication link between a Modbus RTU master and the STM32-based slave using a simple echo mechanism. The master sends a complete Modbus RTU frame and the slave returns the same frame unchanged, allowing verification of UART configuration, RS-485 direction control, and protocol framing before [&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-4158","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\/4158"}],"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=4158"}],"version-history":[{"count":2,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/4158\/revisions"}],"predecessor-version":[{"id":4163,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/4158\/revisions\/4163"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4158"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4158"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4158"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}