Bluetooth RN4871 characteristic update is causing communication halt.

Go To Last Post
19 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all,

 

I know I might offend some people by posting here but unfortunately I didn't receive any help when I posted this in IoT forum. So I am trying my luck here. This question is about the GATT implementation of Bluetooth RN4871. Please direct me if I am at wrong place.

 

I am working on the project where I am reading six ADC channels with 10 bit value each on ATMEGA324PB and then sending the resulting Bytes to a RN4871 BLE device configured as a GATT server. The ADC read is working fine. I have following structure where I can assign the ADC results to the char array using structure bit fields.

typedef struct{

    uint8_t volatile in_status;
    uint8_t volatile out_status;

    union{

        volatile char adc_data8];

        struct{
            volatile uint64_t adc_ch0:		10;
            volatile uint64_t adc_ch1:		10;
            volatile uint64_t adc_ch2:		10;
            volatile uint64_t adc_ch3:		10;
            volatile uint64_t adc_ch4:		10;
            volatile uint64_t adc_ch5:  	10;
            volatile uint64_t pad_bits:		4;
        }data_s;

    }data_u;

}COMM_PACKET_t;

COMM_FRAME_t packet;

Now when I try to write these bytes to a BLE characteristic with 8 byte size the BLE goes wild and start sending err message as response. just to mention I am converting these bytes to hex string before sending to BLE over UART.

Following is my conversion code :

int main(void)
{
    // system initialization
    //Module initiliazation

    while(1)
    {
        _delay(ms)// tried w/wo delay

        char *str = str_from_hex_array(packet.data_u.adc_data);

        BLE_Module_Write_Char(OUT_VOLTS_HANDLE,str,OUT_VOLTS_SIZE);
    }
}

// FUNCTION DEFINITION
char *str_from_hex_array(volatile unsigned char *src, size_t len)
{

    char *outstr = malloc(2*len+1);
    if (!outstr) return outstr;
    char *p = outstr;
    for (size_t i= 0; i<len; i++)
    {
        p+=sprintf(p, "%02X", src[i]);
    }
    return outstr;

}

int BLE_Module_Write_Char(char charHandle[],char charValue[],char charSize[])
{
	_delay_ms(DELAY_BEFORE_CMD);
	int max = (int)strtol(charSize, NULL, 16); //convert the size from bytes in hex to an int
	max = max * 2; //max is the maximum number of characters, and there are two characters per byte.

	//check if the data is longer than the allowed size
	if (strlen(charValue) > max)
	{
		return(0);
	}

	//check if the data is valid hexadecimal (0-9,a-f)
	for(int i = 0; i < strlen(charValue); i++)
	{
		if (!(isxdigit(charValue[i])))
		{
			return(0);
		}
	}

	//semd the command
	Ring_Buffer_Clear(&RXBuffer);
	USART_Transmit_String(WRITE_LOCAL_CHARACT,0);
	USART_Transmit_String(charHandle,0);
	USART_Transmit_Char(',');
	USART_Transmit_String(charValue,1);

	timeout_start(); //begin the timeout timer
	while(RXBuffer.count < strlen(AOK_RESP) && timeout == 0){}; //wait until the expected characters have been received or the timeout triggers

	if (strstr(RXBuffer.data, AOK_RESP) != NULL)
	{
		return(1);
	}

	return 0;
}

 With everything looking good I still don't have a clue what is wrong. In my assumption this has something to do with the string size I am sending to update characteristic. But in theory it is looking correct. 

 

 

Any help will be big favor. 

 

Regards,

#Learning AVR step by step

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So that we don't have to search for and therefore second guess what your using; post the details of the API for "RN4871 BLE device configured as a GATT server".

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 the BLE goes wild and start sending err message as response. just to mention I am converting these bytes to hex string before sending to BLE over UART.

What err messages??---be specific. 

The module very likely should care less what actual data you are sending or any conversion you are doing. 

You are probably getting overrun/command and control troubles.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

N.Winterbottom wrote:

So that we don't have to search for and therefore second guess what your using; post the details of the API for "RN4871 BLE device configured as a GATT server".

 

 

I think the whole code is out of scope here. But I can certainly share the details.

 

So RN4871 is being configured with a private service and four characteristics (2B(Write/notify), 2B(Read/notify), 8B(Read/notify), 2B(Read/notify))

 

To configure these characteristics. BLE is entered into command mode and characteristics are configured by sending PC,UUID, permission commands. Service and Characteristics availability are checked and reconfigured (if required) on each power reset. The send command function is as below:

/**
		* A generic function to send commands to the bluetooth module
		*
		*  \param commandString the command to be sent to the bluetooth module
		*  \param argument a int indicating if there is additional arguments or not,
		*		  set to 0 if there isn't, 1 if there is
		*  \param argumentString the argument string to be used if required
		*  \param responseString the expected response from the BLE module as a string
		*  \param EOL if an EOL character should be sent at the end of the command or not
		*  \return returns 1 if the	module returns the value expected from the responseString, 0 if not
		*/
		int sendCommand(char commandString[], int argument ,char argumentString[], char responseString[], int EOL);

 

I didn't have any issue in setting up BLE.

Only while I am trying to update the characteristics values(Especially 8 byte characteristic) via microcontroller in A while loop, I find this odd behavior.

I suspected that when I am doing hex to string conversion may be I am doing something wrong and the resulting string is either overflowing or missing chars, which results into wrong command structure and hence BLE goes out of sync with Microcontroller and start sending the Error message as "Err". 

 

When I removed the code section updating 8 byte characteristic everything works fine.

I partially resolved this problem by changing the Baud rate to 57600. But I am not sure this will work.

 

avrcandies wrote:

What err messages??---be specific. 

 

I start receiving Error message "Err" in response to every command being send from Microcontroller until a manual reset.

 

I hope this explain a little bit.

 

Regards,

 

Sam_Vir       

#Learning AVR step by step

Last Edited: Mon. Aug 16, 2021 - 09:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

one parameter

sam_vir wrote:

        char *str = str_from_hex_array(packet.data_u.adc_data);

 

2 parameters

sam_vir wrote:

 

char *str_from_hex_array(volatile unsigned char *src, size_t len)

sam_vir wrote:

    char *outstr = malloc(2*len+1);

you keep mallocing, but never free up the memory. Eventually it will run out.

I don't see any need for malloc in a case like this.

Just allocate a char aray big enough for the biggest case, and pas that into str_from_hex_array, where it will fill it in. Use the same array each time.

Also, i think the name would be more accurate as hex_str_from array!

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


From the  RN4871 Product Page, the " Wireless Brochure" gives some possible sources of help:

 

 

Technical Support: http://www.microchip.com/support 

Knowledge base and peer help: http://www.microchip.com/forums

Overview of Technical Training Resources: http://www.microchip.com/training

Developer Help Website: http://www.microchip.com/developerhelp

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sam_vir wrote:
I partially resolved this problem by changing the Baud rate to 57600. But I am not sure this will work.

BLUETOOTH LOW-ENERGY MODULE | Microchip Technology (RN4871)

[datasheet, page 11]

Maximum Data Rate (Transparent UART)

10 kbps (iOS®9)

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gchapman wrote:

 

 

 

BLUETOOTH LOW-ENERGY MODULE | Microchip Technology (RN4871)

[datasheet, page 11]

Maximum Data Rate (Transparent UART)

10 kbps (iOS®9)

 

 

That makes sense. 

But why then RN487x modules have default rate set as 115200.

My understanding was that it only applies to Transparent UART.

Since I am using GATT server application, I thought I can go as high as 115200. What is your opinion?

 

 

 

 

#Learning AVR step by step

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sam_vir wrote:
why then RN487x modules have default rate set as 115200.

The data rate between a DTE (eg, your AVR) and a DCE (a "modem"; eg, the RN) is not necessarily the same as the rate across the comms link.

 

It's not uncommon for the DTE-DCE rate to be higher than the comms link rate - in which case, some buffering & flow-control is needed ...

 

Since I am using GATT server application, I thought I can go as high as 115200. What is your opinion?

Remember that BLE was never designed for high-speed; if the datasheet says 10 kbps, then that is probably the case.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
Remember that BLE was never designed for high-speed; if the datasheet says 10 kbps, then that is probably the case.

 

You are right.

I can try dropping the speed.

Like I said, when I decreased the data rate FROM 115200 to 57600 the issue was resolved to a greater extent.

I will try sticking to 9600 Recommended as per data sheet.

 

Thanks everyone.

 

Regards,

Sam_Vir  

#Learning AVR step by step

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sam_vir wrote:
What is your opinion?

  • Compare to MCC generated code
  • Evaluate Microchip Bluetooth 8051 (IS1871) versus Texas Instruments Bluetooth 8051

 

MPLAB® Code Configurator RN4870 | RN4871 BLE Module v1.0.1 Library Release Notes

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

always good to follow the recommendations in the datasheet ... wink

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think the baudrate thing is a distraction, unless or course there is significant baudrate error from your AVR. You can use 115200 (as I do routinely) just don't transmit too many messages/second.

 

More importantly though can we trust the code you posted ?

sam_vir wrote:

    volatile char adc_data8];  // Missing square bracket
        
// FUNCTION DEFINITION
char *str_from_hex_array(volatile unsigned char *src, size_t len) { ... }

// FUNCTION CALL
char *str = str_from_hex_array(packet.data_u.adc_data); // argument len is missing

 

This could NOT have compiled.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I hate to ask, after all of these posts, but you never mention the frequency of your external crystal and it's capacitor value you are using (requires 2 caps) ...that can make a difference...what do you have in place?

It is imperative that your UART divider setting be matched "perfectly" to your external crystal.

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

N.Winterbottom wrote:

More importantly though can we trust the code you posted ?

 

I genuinely feel sorry about these mistakes. Just some copy & paste errors. I was trying to call the function with hard coded values for len while I copied the code. Code is compiling fine, please ignore the mistakes and consider the value for len as 8.

Purpose of posting this code was to get an expertise review whether I am doing the conversion and the generated string length is not overflowing.  

 

avrcandies wrote:

I hate to ask, after all of these posts, but you never mention the frequency of your external crystal and it's capacitor value you are using (requires 2 caps) ...that can make a difference...what do you have in place?

I was using 16MHz crystal with loading value of 8pF and external caps 5.8pF each before, but after having a look at Atmega324pb datasheet doc DS40001892A-page 240, the baud rate examples table mentioned the error rate of -3.5%- +2.1% for baud of 115200. So, I changed my crystal to 18.432Mhz with loading value of 12pF and external caps to 6.8pF each. 

 

But as mentioned by gchapman & awneil above, I can stick to 9600 baud as recommended by data sheet for RN4870/71 and still keep my 16MHz crystal. I actually tried 9600 BAUD even with 18.430MHz and its looking promising. 

I also noticed(thanks to gchapman) in the RN4870/71 example codes by Microchip, they also use the baud rate of 9600 which is probably the most genuine choice unless you are dealing with a very high speed data transfer requirements. 

 

Thanks to everyone.  

 

Regards,

sam_vir

#Learning AVR step by step

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

and external caps to 6.8pF each. 

To me, that seems/sounds a little low...I am not saying it is wrong, but typically I'd expect 15 pF, maybe 18 pF, or even 22 pF.  so 6.8pf sound a little "surprising"  ...like I just won 3 million dollars.

Maybe there has been a shift in values since the last time I looked---crystal packages have gotten a lot smaller.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PB megaAVR high frequency crystal oscillator is reduced current (therefore, reduced load capacitance and reduced trim capacitance)

Example Layout of ATxmega32A4 and ATmega324PB Devices | AVR® Microcontroller Hardware Design Considerations

[2/3 page]

Figure 4. ATmega324PB - Basic Schematic Example of Required/Recommended Connections

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gchapman,

Exactly what I followed for the design of oscillator stage.

 

I tried to go as close as possible to the reference circuit. The parameter values required for external caps calculations as mentioned in Example layout and the data sheet of Atmega324pb were a little out of agreement so I found a middle ground by getting the microchip support on the matter.

For 16MHz crystal mentioned in my earlier post I analyzed the resulting clock frequency using DSO for validation purpose and found 16Mhz.    

 

 

 

sam_vir

#Learning AVR step by step

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


 

That is interesting...over the years we've settled on around 15pf...maybe time to do a re-eval

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!