I’m trying to write a program that reads data from 4 hall effect sensors and outputs it to a serial monitor over Bluetooth. The sensors communicate over I2C. The programs works fine when I just read 1, 2 or 3 sensors. I can also read 4 sensors, but when I put a magnet up close to the sensors the outputted string becomes very long and the program crashes.
This function reads a given hall sensor based on the address provided by the first parameter. It returns the sensor data as a string:
char* MLX_read(int8_t add, uint16_t id)
{
static char mybuf[100];
uint8_t CH_config2[0];
uint8_t data[7];
if (one_axis == true){
CH_config2[0] = 0x38; //
writeBytes(add, CH_config2, 1);
readBytes(add, data, 1);
CH_config2[0] = 0x48; //
writeBytes(add, CH_config2, 1);
readBytes(add, data, 7);
z_axis = (uint16_t) data[1] << 8 | data[2];
if (z_axis > 32767){
z_axis = (65536 - z_axis);
}
data_length = Data_length_setup(z_axis);
sprintf(mybuf,"%d \n", z_axis);
BLT_data_send(mybuf,data_length); // Data send over bluetooth
}else{
CH_config2[0] = 0x3E; //
writeBytes(add, CH_config2, 1);
readBytes(add, data, 1);
CH_config2[0] = 0x4E; //
writeBytes(add, CH_config2, 1);
readBytes(add, data, 7);
x_axis = (uint16_t) data[1] << 8 | data[2];
y_axis = (uint16_t) data[3] << 8 | data[4];
z_axis = (uint16_t) data[5] << 8 | data[6];
if (x_axis > 32767) x_axis = (65536 - x_axis);
if (y_axis > 32767) y_axis = (65536 - y_axis);
if (z_axis > 32767) z_axis = (65536 - z_axis);
sprintf(mybuf,"%d,%d,%d,%d,",id, x_axis, y_axis, z_axis);
}
return mybuf;
}
This function resolves how many sensors are to be read and appends it to a string. This string is sent over Bluetooth to the serial monitor:
void resolve_sensors(int s1p, int s2p, int s3p, int s4p){
char str[1000];
strcpy(str, "");
if(s1p) strcat(str, MLX_read(MLX_1, 1));
if(s2p) strcat(str, MLX_read(MLX_2, 2));
if(s3p) strcat(str, MLX_read(MLX_3, 3));
if(s4p) strcat(str, MLX_read(MLX_4, 4));
strcat(str, "\n");
BLT_data_send(str,strlen(str)); // Data send over bluetooth
nrf_delay_ms(500);
}
This is the output to the serial monitor. As a magnet is moved closer to the sensors and the string gets longer, the program crashes:

My Bluetooth functions look like this:
void BLT_data_send(char *data, int16_t data_l)
{
uint32_t err_code = ble_nus_data_send(&m_nus, data,&data_l, m_conn_handle);
if(err_code == NRF_ERROR_RESOURCES) {
NRF_LOG_INFO("Queue full, waiting");
NRF_LOG_FLUSH();
full_queue = true;
while(full_queue) {
// ble_nus_data_send(&m_nus, data,&data_l, m_conn_handle);
nrf_pwr_mgmt_run();
}
}
idle_state_handle();
}
uint32_t ble_nus_data_send(ble_nus_t * p_nus,
uint8_t * p_data,
uint16_t * p_length,
uint16_t conn_handle)
{
ret_code_t err_code;
ble_gatts_hvx_params_t hvx_params;
ble_nus_client_context_t * p_client;
VERIFY_PARAM_NOT_NULL(p_nus);
err_code = blcm_link_ctx_get(p_nus->p_link_ctx_storage, conn_handle, (void *) &p_client);
VERIFY_SUCCESS(err_code);
if ((conn_handle == BLE_CONN_HANDLE_INVALID) || (p_client == NULL))
{
return NRF_ERROR_NOT_FOUND;
}
if (!p_client->is_notification_enabled)
{
return NRF_ERROR_INVALID_STATE;
}
if (*p_length > BLE_NUS_MAX_DATA_LEN)
{
return NRF_ERROR_INVALID_PARAM;
}
memset(&hvx_params, 0, sizeof(hvx_params));
hvx_params.handle = p_nus->tx_handles.value_handle;
hvx_params.p_data = p_data;
hvx_params.p_len = p_length;
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
return sd_ble_gatts_hvx(conn_handle, &hvx_params);
}
I’ve tried changing the buffer sizes and putting the buffers into global space – but to no success. I’ve tried testing the Bluetooth sender function by just sending a very long generic string, and it’s able to do that with no problem. Ive also tried sending each sensor data string with seperate bluetooth calls, but it still crashes. Im at a loss here.