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!