In my project, I aim to send an ADC value (10 bits ADC) and 6 data (16 bits/each data) from MPU6050 by using nrf51 DK to Android app ( modified from https://github.com/NordicPlayground/Android-nRF-UART). I created two timers for ADC channel and MPU6050 to aim for getting sampling rate of 500 samples/second. Since the buffer of the NUS just has only 8 bits, I partitioned the value of ADC and 6 data of MPU6050 into values with 8 bits long, which ended up having 2 bytes for an ADC value and 12 bytes for 6 data of MPU. It means that I need to send to Android app total 14 bytes for each time. In Android app, I did a simple technique to combine the data partitioned into real data.
The data of MPU collected on Android app seem correct as I tried to send 6 constant number before getting real data from MPU function; however, there are something wrong in ADC value with sampling rate. I tried to send a sinusoidal wave with the frequency of 10Hz as an analog input, but after receiving data on App, I just got a signal with only 0.71Hz. Without sending 6 data of MPU6050, I can receive sine signal with the same frequency.
Is that because of sending too long data (14 bytes) caused the mismatch of frequency between analog signal and signal after digitalizing?
I notice that we can set up the length of buffer of NUS like this. Could I change the buffer size up to 16 bits so that I can reduce the length of data transmitted to App each time?
#define UART_TX_BUF_SIZE 256 /**< UART TX buffer size. */ #define UART_RX_BUF_SIZE 256 /**< UART RX buffer size. */
Here is code I used to send 14 bytes. I create a buffer with the size of 14. First two bytes are for ADC value and the rest is for MPU data
static void adc_event_handler(nrf_drv_adc_evt_t const * p_event)
{
if (p_event->type == NRF_DRV_ADC_EVT_DONE)
{
adc_event_counter++;
// printf(" ADC event counter: %d\r\n", adc_event_counter);
uint32_t i;
printf("Data size: %d\r\n",p_event->data.done.size);
for (i = 0; i < p_event->data.done.size; i++)
{
printf("%d\r\n",p_event->data.done.p_buffer[i]); //Print ADC result on hardware UART
adc_result[(2*i)] = p_event->data.done.p_buffer[i] >> 8;
adc_result[(2*i)+1] = p_event->data.done.p_buffer[i];
}
APP_ERROR_CHECK(nrf_drv_adc_buffer_convert(adc_buffer,ADC_BUFFER_SIZE)); //Allocate buffer for ADC
//LEDS_INVERT(BSP_LED_3_MASK); //Indicate sampling complete on LED 4
}
}
This code is for partitioning the ADC value and store in first two bytes of variable name adc_results.
static void sensor_measurement_handler(void * p_context)
{
uint32_t err_code;
UNUSED_PARAMETER(p_context);
int16_t MPU6050_data[6];// = {100, 200, 300, 400, 500, 600};
int16_t angles[6];
//int8_t MPU6050_send[12];
int16_t len_send_data = 12, i = 0;
// Read ACC value
MPU6050_Get_Accel_Angles(&MPU6050_data[0],&MPU6050_data[1],&MPU6050_data[2], &angles[0],&angles[1],&angles[2]);
// Read Gyro value
MPU6050_Get_Gyro_Angles(&MPU6050_data[3],&MPU6050_data[4],&MPU6050_data[5],&angles[3],&angles[4],&angles[5]);
//MPU6050_data[6] = 0.96 * angles[0] + 0.04 * angles[3]; //filter góc t? gyro và accel
//MPU6050_data[7] = 0.96 * angles[1] + 0.04 * angles[4]; //filter góc t? gyro và accel
//MPU6050_data[8] = 0.96 * angles[2] + 0.04 * angles[5]; //filter góc t? gyro và accel
/*
MPU6050_data[6] = angles[0];
MPU6050_data[7] = angles[1];
MPU6050_data[8] = angles[2];
MPU6050_data[9] = (int16_t) ble_sensor_get_status(); // l?y status c?a led
*/
/*
// using this function to send MPU6050 data to BLE and smartphone
err_code = ble_sensor_measurement_send(&ble_sensor_handle, MPU6050_data, sizeof(MPU6050_data));
if ((err_code != NRF_SUCCESS) &&
(err_code != NRF_ERROR_INVALID_STATE) &&
(err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
)
{
APP_ERROR_HANDLER(err_code);
}
*/
for (i = 1; i < len_send_data/2+1; i++){
printf("Sensor value: %d\r\n",MPU6050_data[i]);
adc_result[(2*i)] = MPU6050_data[i-1] >>8;
adc_result[(2*i)+1] = MPU6050_data[i-1];
}
ble_nus_string_send(&m_nus, &adc_result[0], 14);
}
This code is for getting data from MPU and put it in the next 12 bytes of variable adc_results. After that, I call function ble_nus_string_send(&m_nus, &adc_result[0], 14) to send data to Android app.
Thank you!