Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

Writing/Reading to Flash and Transmitting Large Amount Data Over BLE

Hello everyone,

I am an intern and new to BLE. I was tasked with developing a simple temperature logger that will placed in rivers/lakes. So far I've had some success.

My development environment is as follows: Custom PCB with a nRF52832 chip, ST-Link on a Nucleo board for flashing and erasing the chip, Eclipse IDE with Cross GCC and I am using the nRF5 SDK 17.

To my question: I am storing a temperature reading and a timestamp +  some other data in a RAM buffer. The whole payload is 12 bytes. Now I know that a single page in flash is 4096 bytes which gives roughly 341 entries per page. How do I write to flash without disrupting the bluetooth communication. And also how do I receive the data from flash, say 10 pages worth of entries, to my central device when I issue a command from my BLE terminal or phone.

I've used the ble_nus module for simple commands: setting the time between measurements, setting the internal clock, receiving current temperature reading etc., but this time the data is quite large - over 40KB. Is this service appropriate or should I use another? And how do I go about setting it up for such a big payload of data.

typedef struct {
    int32_t     temp;
    calendar_t  timestamp;
    place_t     type;
} temperature_flash_data_t;

 

static temperature_flash_data_t ram_to_flash_buffer[MAX_ENTRIES];
static uint32_t entry_count = 0;
void log_data_to_buffer(int32_t temperature, custom_time_t *time, place_t *place)
{
	if(entry_count >= MAX_ENTRIES)
	{
	    flush_data_to_flash();
	}

	ram_to_flash_buffer[entry_count].temperature = temperature;
	ram_to_flash_buffer[entry_count].timestamp.year = time->year;
	ram_to_flash_buffer[entry_count].timestamp.month = time->month;
	ram_to_flash_buffer[entry_count].timestamp.day = time->day;
	ram_to_flash_buffer[entry_count].timestamp.hour = time->hour;
	ram_to_flash_buffer[entry_count].timestamp.minute = time->minute;
	ram_to_flash_buffer[entry_count].timestamp.second = time->second;
	ram_to_flash_buffer[entry_count].place.type = place->river;

	entry_count++;
}

void flush_data_to_flash(void) 
{
	uint32_t total_words = (entry_count * ENTRY_SIZE) / sizeof(uint32_t);

    nrf_nvmc_page_erase(flash_page_address); 
	nrf_nvmc_write_words(flash_page_address, (const uint32_t *)ram_to_flash_buffer, total_words);

	entry_count = 0;
	flash_page_address += 0x00001000; // Increment to next page

	if(flash_page_address >= 0x00080000) 
	{
		flash_page_address = 0x00078000;
	}
}

In the above snippet I log my data into RAM and send it to page 120 in flash. But I am a bit lost on how read it back and then transmit via BLE with ble_nus module.

Any help would be appreciated!

Thanks

Related