This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Modbus RTU protocol over "BLE UART"

I used the Nordic EVAL model nRF52-DK which uses the "nRF52832" chip.
The EVAL has been programmed as "Pheripheral" with the application "BLE over UART" made available by Nordic itself.
The "BLE over UART" profile contains the SoftDevice inside: "s132_nrf52_6.1.0_softdevice.hex".
The RX / TX signals of the UART have been connected to the serial port of an external device.
The BLE client is a PC application interfaced with the VCP of the "nRF51-Dongle" dongle.
The data frames to be exchanged have a maximum size of 512 bytes (stardard modbus RTU). The ATT_MTU = 20.
What is the reliability of BLE communication in the case of buffer fragmentation in packets of 20 bytes each ?
Is there a guarantee that the packets are always sent sequentially without the loss of packets ?
Which recommended solution to use for data exchange with such large buffers with modbus RTU ?

Best regards.
Thank you.

Demetrio Magrin

Parents
  • Hi,

    The link layer of BLE will ensure all packets are successfully received by peer and in the correct order. It's only a link loss that may interfere with this.

    To transmit large buffers it may be a good idea to use data length extension (include gatt_init in your project to handle this), this allow the two peers to exchange the maximum data packet size on-air, which overall will increase throughput and reduce latency.

    You can in the application have a large UART buffer, e.g. 1kByte, and in addition use hardware flow control on UART. This should ensure that the application can buffer the next packet while the current is transmitted. Enabling flow control will ensure that the peer don't overrun the buffer.

    Best regards,
    Kenneth

  • Hello Mr. Kenneth,

    With the examples provided by Nordic as UART over BLE (pheriferal and client) the transmission of a buffer of 300 bytes (for example), is received in 15 packets of 20 bytes with a pause between a packet and the next.
    If I send, through the UART, these 15 packets to my external control I would have the intervention of the end-of-frame modbus RTU interrupt at the end of each pack of 20 bytes.
    To solve this problem it is necessary to receive all the data in 20 bytes packets and then transmit all the received buffer to my control. Similar to Bluetooth BR/EDR.
    Note: for iOS systems it is advisable to use an ATT_MTU of 20 bytes.
    For this reason we have chosen to use ATT_MTU = 20 (default).
    We ignored the possibility of using an ATT_MTU> 20 bytes.
    I await a kind reply.

    Best regards,

    Demetrio Magrin

  • Hello Mr. Kenneth,

    I have modified the define as follows(Pheripheral and Central):

    #define MIN_CONNECTION_INTERVAL MSEC_TO_UNITS (20, UNIT_1_25_MS)
    #define MAX_CONNECTION_INTERVAL MSEC_TO_UNITS (20, UNIT_1_25_MS)

    Perfect. Now the buffers are received without pauses.
    I have seen that if I decrease the time from 20 ms to 10 ms nothing works.
    Thank you very much for your availability.

    BR

    Demetrio Magrin

  • Hello Mr. Kenneth,

    1st Test: a buffer of 200 bytes is sent from the VCP "BLE Pheripheral" (for example).
            The "BLE central" VCP displays 10 frames of 20 bytes each.
            The time elapsed between a frame received of 20 bytes and the next one is 20 ms.
             Is it possible to reduce this time by 20 ms ?
             On the code I saw that there are the following two definitions:
             #define MIN_CONNECTION_INTERVAL MSEC_TO_UNITS (20, UNIT_1_25_MS)
             #define MAX_CONNECTION_INTERVAL MSEC_TO_UNITS (20, UNIT_1_25_MS)

             Logger:

             28/01/2019 14:28:57.093 [RX] - 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
             28/01/2019 14:28:57.113 [RX] - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
             28/01/2019 14:28:57.133 [RX] - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
             28/01/2019 14:28:57.153 [RX] - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
             28/01/2019 14:28:57.173 [RX] - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
             28/01/2019 14:28:57.193 [RX] - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
             28/01/2019 14:28:57.213 [RX] - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
             28/01/2019 14:28:57.233 [RX] - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
             28/01/2019 14:28:57.254 [RX] - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
             28/01/2019 14:28:57.273 [RX] - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02

             Is it possible to reduce this time by 20 ms ?

    2nd Test: The "nRF51 dongle" dongle is associated with the Nordic "nRF Connect v.2.6.1" TOOL PC
                  In this case the Nordic TOOL PC programs the "nRF51 dongle" dongle in the mode
                  "BLE_connectivity".
                  A buffer of 200 bytes is sent from the "BLE Pheripheral" VCP.
                  The Nordic "nRF Connect v.2.6.1" TOOL PC displays 10 frames of 20 bytes each as follows:

                  14:39:20.706    Attribute value changed, handle: 0x0F, value (0x):    
                                              01-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
                  14:39:20.712    Attribute value changed, handle: 0x0F, value (0x):     
                                              00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
                  14:39:20.712    Attribute value changed, handle: 0x0F, value (0x):
                                              00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
                  14:39:20.726    Attribute value changed, handle: 0x0F, value (0x):
                                              00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
                  14:39:20.730    Attribute value changed, handle: 0x0F, value (0x):
                                              00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
                  14:39:20.736    Attribute value changed, handle: 0x0F, value (0x):
                                              00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
                  14:39:20.746    Attribute value changed, handle: 0x0F, value (0x):
                                              00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
                  14:39:20.749    Attribute value changed, handle: 0x0F, value (0x):
                                              00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
                 14:39:20.752    Attribute value changed, handle: 0x0F, value (0x):
                                             00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
                 14:39:20.764    Attribute value changed, handle: 0x0F, value (0x):
                                             00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-02

                 As seen, the time between a frame and the next is always less than 20 ms.
                 Why this diversity of behavior compared to the first test ?

    I await a kind reply.
    BR

    Demetrio Magrin

  • All good questions, but I don't see a short answer to your questions. I recommend reading up a bit on BLE to learn more about connection parameters and the various ways to send and receive data (for instance write command vs. notifications) between the peers. Learn the various roles between GAP central and peripheral, GATT server and client. In addition, I recommend downloading our nRF sniffer tool, that will allow you to view the actual on-air packets here.

    Best regards,
    Kenneth

  • Hello Mr. Kenneth,

    With reference to the project for the EVAL nRF52 present in:
                               "NRF5_SDK_15.2.0_9412b96 \ examples\ble_peripheral\ble_app_uart \".
    I have only modified the following define in the "sdk_config.h" file:
    #define NRF_SDH_BLE_GAP_DATA_LENGTH 27. It was 251.
    #define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 23. It was 247.

    After this change I saw that:
    1) A buffer of 100 bytes received from the EVAL UART is transmitted correctly through BLE.
         I have verified through the sniffer the presence of 5 frame of 20 bytes each.
    2) A buffer of 160 bytes received from the EVAL UART is not transmitted correctly through BLE.
         I have verified through the sniffer the presence of only one frame of 20 bytes. After the transmission   
         of  this frame the FW on the EVAL crashes and the message "UART started" reappears.

    3) If the 160 byte buffer is received by the BLE(EVAL), the EVAL UART transmits it correctly.
         I have verified through the sniffer the presence of 8 frame of 20 bytes each.

    What should I change to fix this problem ?

    I await a kind reply.
    BR

    Demetrio Magrin

  • Demetrio Magrin REEL said:
    After the transmission   
         of  this frame the FW on the EVAL crashes and the message "UART started" reappears.

    It seems to me that you have an assert, typically if you define DEBUG in your project, and set a breakpoint in app_error_fault_handler() you should find the file name, file number and error code.If you do not define DEBUG the fault handler will typically execute NVIC_SystemReset().

    Best regards,
    Kenneth

Reply
  • Demetrio Magrin REEL said:
    After the transmission   
         of  this frame the FW on the EVAL crashes and the message "UART started" reappears.

    It seems to me that you have an assert, typically if you define DEBUG in your project, and set a breakpoint in app_error_fault_handler() you should find the file name, file number and error code.If you do not define DEBUG the fault handler will typically execute NVIC_SystemReset().

    Best regards,
    Kenneth

Children
  • Hello Mr. Kenneth,

    With reference to the project for the EVAL nRF52 present in:
                               "NRF5_SDK_15.2.0_9412b96 \ examples\ble_central\ble_app_uart_c\".

    I have modified the FW in such a way that every 500 ms the "nRF52832" transmits the same buffer to "PCA10040" (fixed table with final CRC). 138 bytes are sent in all.
    The buffer is received and displayed by the PC terminal (DockLight connected to the JLink CDC UART).
    Randomly the buffer received and displayed by DockLight is incorrect.
    The data of the serial port (FW and DockLight) are following (default):
    Baud_rate = 115200 (default).
    Parity = None
    Data bit: 8
    Stop bit: 1

    Is there any news of this problem ?
    What should I do to solve this problem ?

    I await a kind reply.
    BR

    Demetrio Magrin

Related