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

Problem in data transfer in Bluetooth at 10ms

Hi,

We are using NRF52840 Dk board to transfer the data at 10ms through Bluetooth which is central and peripheral  as other cc250moda controller  Bluetooth. Our objective is to send the data of 8 bytes at  10ms from the NRF52840 Bluetooth to other Bluetooth. We are able to send the data from NRF52840 Bluetooth of 8 bytes at 30ms,50ms,100ms,500 ms to other controller Bluetooth correctly which means at every 50ms  we are sending 8  of bytes data which is receiving  8 bytes of data at every 50ms in the receiving controller Bluetooth. The problem here is when we are sending the  8 bytes of data at 10ms from NRF52840  Bluetooth to  receiving Bluetooth it should read  8 bytes of data at 10ms but here the problem is it is reading as 8 bytes, 16 bytes ,24 bytes ,0 bytes ,0 bytes, 24 bytes,16 bytes, 0 bytes, 0 bytes  as such at every 10 ms.Can you please tell me what is the problem . How to resolve the issue.

  • Thanks for the reply.

    In the peripheral side the there is an scheduler function which reads the data at every 10ms. I am using termite application to log the data from the controller.

    But in the captured_log1data i have noticed that one point of time the master has not connected to slave  but the data is sending.I am here by attaching the log file .

    please give me the solution.

  • Hello,

    sharmelaraju said:
    In the peripheral side the there is an scheduler function which reads the data at every 10ms. I am using termite application to log the data from the controller.

    Could you share some code or elaborate more on the scheduler function you use to read data ever 10 ms? It could be that this scheduler does not work as intended.

    sharmelaraju said:
    But in the captured_log1data i have noticed that one point of time the master has not connected to slave  but the data is sending.I am here by attaching the log file .

    The first highlighted section might be caused by the peripheral not acknowledging the reception of the packet sent from the central device. This causes the central to resend the packet. 
    It might also be due to that the sniffer might receive packets that is lost or corrupted to the central/peripheral device - and vice verse. The first highlighted section of the screenshot you have shared might be showing this. That the sniffer lost a packet that the central/peripheral might still have received.
    The frequency of loss and packet corruption depends heavily on the environment in which the devices are working.

    What is interesting is the transmission starting on packet number 1209... I must have missed this exchange when reading the log earlier. What might be happening is that the central attempts to start a transfer, that is not acknowledged by the slave. This causes the central to have to wait until the next connection interval to re-transmit the non-acknowledged packet. Since your program schedules new data to be sent every 10 ms, a new packet will be placed in the TX buffer before the previous is retransmitted. This leads to the transmission exchanges we are seeing at packet 1209 - the master suddenly has more than one packet to transmitt at once, since the previous one was never acknowledged.
    The re-transmission feature also ensures that no data is lost, even though it will arrive in the next connection interval. Note also how all the extra data is fitted into the next connection interval, without causing any sort of delay.
    So, In essence; you are ensured that all the data will be transmitted over the BLE connection, but some data might arrive in the next connection interval, if the first transmission attempt is never acknowledged by the peripheral.
    This is probably the cause of the logger "stutter" you've seen in your log. :)

    As for the Empty PDU in the second highlighted section, it is probably caused by the central TX buffer being empty when the connection interval is up, causing the central to send an empty packet just to maintain the connection to the peripheral.
    You can double click the packet in question  to see its contents.

    Best regards,
    Karl

  • Thanks.

    I am hereby attaching the code of the peripheral which reads the data every 10ms.

     /* The following function is the main user interface thread.  It     */
       /* opens the Bluetooth Stack and then drives the main user interface.*/
    
    
    int main(void)
    {
       /* Configure the hardware for its intended use.                      */
       HAL_ConfigureHardware(1);
    
       /* Enable interrupts and call the main application thread.           */
       MainThread();
    
       /* MainThread should run continously, if it exits an error occured.  */
       while(1)
       {
          ToggleLED(NULL);
    
          BTPS_Delay(100);
       }
    }
    
       /* The following function is the main user interface thread.  It     */
       /* opens the Bluetooth Stack and then drives the main user interface.*/
    static void MainThread(void)
    {
       int                           Result;
       BTPS_Initialization_t         BTPS_Initialization;
       HCI_DriverInformation_t       HCI_DriverInformation;
       HCI_HCILLConfiguration_t      HCILLConfig;
       HCI_Driver_Reconfigure_Data_t DriverReconfigureData;
    
       /* Configure the UART Parameters.                                    */
       HCI_DRIVER_SET_COMM_INFORMATION(&HCI_DriverInformation, 1, VENDOR_BAUD_RATE, cpHCILL_RTS_CTS);
       HCI_DriverInformation.DriverInformation.COMMDriverInformation.InitializationDelay = 100;
    
       /* Set up the application callbacks.                                 */
       BTPS_Initialization.GetTickCountCallback  = GetTickCallback;
       BTPS_Initialization.MessageOutputCallback = DisplayCallback;
    
       /* Initialize the application.                                       */
       if((Result = InitializeApplication(&HCI_DriverInformation, &BTPS_Initialization)) > 0)
       {
          /* Register a sleep mode callback if we are using HCILL Mode.     */
          if((HCI_DriverInformation.DriverInformation.COMMDriverInformation.Protocol == cpHCILL) || (HCI_DriverInformation.DriverInformation.COMMDriverInformation.Protocol == cpHCILL_RTS_CTS))
          {
             HCILLConfig.SleepCallbackFunction        = HCI_Sleep_Callback;
             HCILLConfig.SleepCallbackParameter       = 0;
             DriverReconfigureData.ReconfigureCommand = HCI_COMM_DRIVER_RECONFIGURE_DATA_COMMAND_CHANGE_HCILL_PARAMETERS;
             DriverReconfigureData.ReconfigureData    = (void *)&HCILLConfig;
    
             /* Register the sleep mode callback.  Note that if this        */
             /* function returns greater than 0 then sleep is currently     */
             /* enabled.                                                    */
             Result = HCI_Reconfigure_Driver((unsigned int)Result, FALSE, &DriverReconfigureData);
             if(Result > 0)
             {
                /* Flag that sleep mode is enabled.                         */
                Display(("Sleep is allowed.\r\n"));
             }
          }
    
          /* We need to execute Add a function to process the command line  */
          /* to the BTPS Scheduler.                                         */
          if(BTPS_AddFunctionToScheduler(ReadFunction, NULL, 10))
          {
             /* Add the idle function (which determines if LPM3 may be      */
             /* entered) to the scheduler.                                  */
             if(BTPS_AddFunctionToScheduler( Writefunction, NULL, 10))
             {
                /* Loop forever and execute the scheduler.                  */
                while(1)
                   BTPS_ExecuteScheduler();
             }
          }
       }
    }
    static void ReadFunction(void *UserParameter)
    {
    //xxx Fill in to put processor into low power mode
    	ProcessCommandLine1();
    }
    static void Writefunction(void *UserParameter)
    {
    //xxx Fill in to put processor into low power mode
    	ProcessCommandLine2();
    }
    void ProcessCommandLine1()
    {
      //Display(("Read data\r\n"));
       ReadDataCommand(NULL);
    }
    void ProcessCommandLine2()
    {
      //Display(("Write data\r\n"));
       SendDataCommand(NULL);
    }
    
       /* The following function is responsible for reading data sent by a  */
       /* remote device to which a connection exists.  This function will   */
       /* return zero on successful execution and a negative value on       */
       /* errors.                                                           */
    
    static int ReadDataCommand(ParameterList_t *TempParam)
    {
       int           LEConnectionIndex;
       Boolean_t     Done;
       //  char BT_address[12] = "d78206cba936";
        //  char BT_address[12] = "f43538fe9c18";
       char BT_address[12] = "cc78ab7945c2";
    
       BD_ADDR_t     BD_ADDR;
       unsigned int  Temp;
       DeviceInfo_t *DeviceInfo;
    
       /* Next, make sure that a valid device address exists.               */
      // if((TempParam) && (TempParam->NumberofParameters > 0) && (TempParam->Params[0].strParam) && (BTPS_StringLength(TempParam->Params[0].strParam) >= (sizeof(BD_ADDR_t)*2)))
       //{
          /* Convert the parameter to a Bluetooth Device Address.           */
         // StrToBD_ADDR(TempParam->Params[0].strParam, &BD_ADDR);
          StrToBD_ADDR(BT_address, &BD_ADDR);
    
          /* Find the LE Connection Index for this connection.              */
          if((LEConnectionIndex = FindLEIndexByAddress(BD_ADDR)) >= 0)
          {
             /* Get the device info for the connection device.              */
             if((DeviceInfo = SearchDeviceInfoEntryByBD_ADDR(&DeviceInfoList, LEContextInfo[LEConnectionIndex].ConnectionBD_ADDR)) != NULL)
             {
                /* Determine the number of bytes we are going to read.      */
                Temp = LEContextInfo[LEConnectionIndex].SPPLEBufferInfo.ReceiveBuffer.BufferSize - LEContextInfo[LEConnectionIndex].SPPLEBufferInfo.ReceiveBuffer.BytesFree;
    
                Display(("Read: %u.\r\n", Temp));
    
                /* Loop and read all of the data.                           */
                Done = FALSE;
                while(!Done)
                {
                   /* Read the data.                                        */
                   Temp = SPPLEReadData(&(LEContextInfo[LEConnectionIndex]), DeviceInfo, SPPLE_DATA_BUFFER_LENGTH, SPPLEBuffer);
                   if(Temp > 0)
                   {
                      /* Display the data.                                  */
                      SPPLEBuffer[Temp] = '\0';
                      Display(((char *)SPPLEBuffer));
                   }
                   else
                      Done = TRUE;
                }
                Display(("\r\n"));
             }
             else
                Display(("No Device Info.\r\n"));
          }
          else
          {
             /* No matching ConnectionBD_ADDR.                              */
             Display(("No connection with BD_ADDR %s exists.\r\n", TempParam->Params[0].strParam));
          }
      // }
       //else
       //{
          /* Invalid parameters specified so flag an error to the user.     */
         // Display(("Usage: LEREAD [BD_ADDR].\r\n"));
       //}
    
       return(0);
    }
      /* The following function is responsible for sending a number of     */
       /* characters to a remote device to which a connection exists.  The  */
       /* function receives a parameter that indicates the number of byte to*/
       /* be transferred.  This function will return zero on successful     */
       /* execution and a negative value on errors.                         */
    static int SendDataCommand(ParameterList_t *TempParam)
    {
       int           LEConnectionIndex;
       BD_ADDR_t     BD_ADDR;
       DeviceInfo_t *DeviceInfo;
        char BT_address[12]="cc78ab7945c2";
    
       /* Make sure that all of the parameters required for this function   */
       /* appear to be at least semi-valid.                                 */
      // if((TempParam) && (TempParam->NumberofParameters >= 2) && (TempParam->Params[1].intParam > 0) && (TempParam->Params[0].strParam) && (BTPS_StringLength(TempParam->Params[0].strParam) >= (sizeof(BD_ADDR_t)*2)))
       //{
          /* Convert the parameter to a Bluetooth Device Address.           */
          StrToBD_ADDR(BT_address, &BD_ADDR);
    
          /* Find the LE Connection Index for this connection.              */
          if((LEConnectionIndex = FindLEIndexByAddress(BD_ADDR)) >= 0)
          {
             /* Check to see if we are sending to another port.             */
             if(!(LEContextInfo[LEConnectionIndex].SPPLEBufferInfo.SendInfo.BytesToSend))
             {
                /* Get the device info for the connection device.           */
                if((DeviceInfo = SearchDeviceInfoEntryByBD_ADDR(&DeviceInfoList, LEContextInfo[LEConnectionIndex].ConnectionBD_ADDR)) != NULL)
                {
                   /* Get the count of the number of bytes to send.         */
                   LEContextInfo[LEConnectionIndex].SPPLEBufferInfo.SendInfo.BytesToSend  = (Word_t)DataStrLen;//(DWord_t)TempParam->Params[1].intParam;
                   LEContextInfo[LEConnectionIndex].SPPLEBufferInfo.SendInfo.BytesSent    = 0;
    
                   /* Kick start the send process.                          */
                   SPPLESendProcess(&(LEContextInfo[LEConnectionIndex]), DeviceInfo);
                }
                else
                   Display(("No Device Info.\r\n"));
             }
             else
                Display(("Send Currently in progress.\r\n"));
          }
          else
          {
             /* No matching ConnectionBD_ADDR.                              */
             Display(("No connection with BD_ADDR %s exists.\r\n", TempParam->Params[0].strParam));
          }
      /* }
       else
          DisplayUsage("LESEND [BD_ADDR] [Number of Bytes to send]\r\n");*/
    
       return(0);
    }
    
    
    
    

  • Hello again,

    I was under the impression from your earlier comments that you currently were using the nRF as the peripheral device?
    The code you have shared in your last reply seem to be for your CC250MODA device - which I am not familiar with. If there is a problem with this device, then I rather recommend that you contact Texas Instrument regarding this.

    Nevertheless, giving the code a quick look, it looks to me like you are indeed scheduling a single read every 10 ms. Instead of setting up a scheduler to do a reading every 10 ms - when you already know that you will be receiving a packet every 10 ms - I suggest making use of the generated BLE Radio events (RX complete events) to start the processing of your data. I am not sure how this is implemented on the CC250MODA device, but I am sure they will generate an interrupt or event upon the completion of a BLE transfer.

    Looking forward to resolving this issue,

    Best regards,
    Karl

  • Thanks for the reply.

    I have tried  cc2564moda Bluetooth(central) with  cc2564moda Bluetooth(peripheral) .With this communication it is working fine.But not with the nrf52840  controller. can you please give me some solution.

Related