Hi,
I want to read the ADC value and send it over BLE to mobile app at every 5sec, which BLE peripheral code i need to use , Please suggest asp.
Thanks in Advance
Pavan S K
Hi Pavan,Thank you for posting your question online.Please refer on this Tutorial:1. Introduction — DA145XX Tutorial SDK peripherals (renesas.com)This tutorial is based on the empty_peripheral_template example and on chapter 9 you can find information regarding the ADC on SDK6.Since you want to send the data every 5sec over BLE, you should implement an app_easy_timer as well. Keep in mind that if you have implemented Extended Sleep Mode during your connection you will have to sample the ADC when the BLE core is active.Kind Regards,OV_Renesas
Hi ,
Its only peripheral example, How to send the ADC value over BLE to mobile app. Which BLE peripheral program to use and how to add adc peripheral there. Please help to share the example program.
T
Hi Pavan,I worked on the ble_app_peripheral example.The ble_app_peripheral example has by default 3 custom services with multiple custom characteristics.If you want more information on how you can achieve that please check this tutorial: DA145XX Tutorial Create a Custom GATT Profile — DA145XX Tutorial Create a Custom GATT Profile (renesas.com)In the 1st custom service, there is a characteristic with a Characteristic User Description: "Control Point" and another characteristic with a Characteristic User Description: "ADC Value 1". If you write any value other than 0 on the Control Point characteristic, then a timer starts and updates the ADC Value 1 characteristic every second with an incrementing value.On user_custs1_impl.c For the Control Point Characteristic:
void user_svc1_ctrl_wr_ind_handler(ke_msg_id_t const msgid, struct custs1_val_write_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t val = 0; memcpy(&val, ¶m->value[0], param->length); if (val != CUSTS1_CP_ADC_VAL1_DISABLE) { timer_used = app_easy_timer(APP_PERIPHERAL_CTRL_TIMER_DELAY, app_adcval1_timer_cb_handler); } else { if (timer_used != EASY_TIMER_INVALID_TIMER) { app_easy_timer_cancel(timer_used); timer_used = EASY_TIMER_INVALID_TIMER; } } }
void app_adcval1_timer_cb_handler() { struct custs1_val_ntf_ind_req *req = KE_MSG_ALLOC_DYN(CUSTS1_VAL_NTF_REQ, prf_get_task_from_id(TASK_ID_CUSTS1), TASK_APP, custs1_val_ntf_ind_req, DEF_SVC1_ADC_VAL_1_CHAR_LEN); // ADC value to be sampled static uint16_t sample __SECTION_ZERO("retention_mem_area0"); sample = (sample <= 0xffff) ? (sample + 1) : 0; //req->conhdl = app_env->conhdl; req->handle = SVC1_IDX_ADC_VAL_1_VAL; req->length = DEF_SVC1_ADC_VAL_1_CHAR_LEN; req->notification = true; /*Change the value updated with adc_val_mv */ memcpy(req->value, &sample, DEF_SVC1_ADC_VAL_1_CHAR_LEN); ke_msg_send(req); if (ke_state_get(TASK_APP) == APP_CONNECTED) { // Set it once again until Stop command is received in Control Characteristic timer_used = app_easy_timer(APP_PERIPHERAL_CTRL_TIMER_DELAY, app_adcval1_timer_cb_handler); } }
/****************************************************************************************/ /* UART2 configuration */ /****************************************************************************************/ // Define UART2 Tx Pad #if defined (__DA14531__) #define UART2_TX_PORT GPIO_PORT_0 #define UART2_TX_PIN GPIO_PIN_5 #else #define UART2_TX_PORT GPIO_PORT_0 #define UART2_TX_PIN GPIO_PIN_4 #endif #define ADC_INPUT_PORT GPIO_PORT_0 #define ADC_INPUT_PIN GPIO_PIN_6
void GPIO_reservations(void) { /* i.e. to reserve P0_1 as Generic Purpose I/O: RESERVE_GPIO(DESCRIPTIVE_NAME, GPIO_PORT_0, GPIO_PIN_1, PID_GPIO); */ #if defined (CFG_PRINTF_UART2) RESERVE_GPIO(UART2_TX, UART2_TX_PORT, UART2_TX_PIN, PID_UART2_TX); #endif RESERVE_GPIO(LED, GPIO_LED_PORT, GPIO_LED_PIN, PID_GPIO); #if !defined (__DA14586__) RESERVE_GPIO(SPI_EN, SPI_EN_PORT, SPI_EN_PIN, PID_SPI_EN); #endif RESERVE_GPIO(ADC_INPUT, ADC_INPUT_PORT, ADC_INPUT_PIN, PID_ADC); } void set_pad_functions(void) { /* i.e. to set P0_1 as Generic purpose Output: GPIO_ConfigurePin(GPIO_PORT_0, GPIO_PIN_1, OUTPUT, PID_GPIO, false); */ #if defined (__DA14586__) // Disallow spontaneous DA14586 SPI Flash wake-up GPIO_ConfigurePin(GPIO_PORT_2, GPIO_PIN_3, OUTPUT, PID_GPIO, true); #else // Disallow spontaneous SPI Flash wake-up GPIO_ConfigurePin(SPI_EN_PORT, SPI_EN_PIN, OUTPUT, PID_SPI_EN, true); #endif #if defined (CFG_PRINTF_UART2) // Configure UART2 TX Pad GPIO_ConfigurePin(UART2_TX_PORT, UART2_TX_PIN, OUTPUT, PID_UART2_TX, false); #endif GPIO_ConfigurePin(ADC_INPUT_PORT, ADC_INPUT_PIN, INPUT, PID_ADC, false); GPIO_ConfigurePin(GPIO_LED_PORT, GPIO_LED_PIN, OUTPUT, PID_GPIO, false); }
#include "adc.h" #include "adc_531.h" #include "arch_console.h" /* According to SDK6 Peripheral Drivers Tutorial http://lpccs-docs.renesas.com/da145xx_tutorial_sdk6_peripherals/da14531_adc.html */ static uint16_t gpadc_read(void); static uint16_t gpadc_sample_to_mv(uint16_t sample); static uint16_t gpadc_read(void) { /* Initialize the ADC */ adc_config_t adc_cfg = { .input_mode = ADC_INPUT_MODE_SINGLE_ENDED, .input = ADC_INPUT_SE_P0_6, .smpl_time_mult = 2, .continuous = false, .interval_mult = 0, .input_attenuator = ADC_INPUT_ATTN_4X, .chopping = false, .oversampling = 0, }; adc_init(&adc_cfg); /* Perform offset calibration of the ADC */ adc_offset_calibrate(ADC_INPUT_MODE_SINGLE_ENDED); adc_start(); uint16_t result = adc_correct_sample(adc_get_sample()); adc_disable(); return (result); } static uint16_t gpadc_sample_to_mv(uint16_t sample) { /* Resolution of ADC sample depends on oversampling rate */ uint32_t adc_res = 10 + ((6 < adc_get_oversampling()) ? 6 : adc_get_oversampling()); /* Reference voltage is 900mv but scale based in input attenation */ uint32_t ref_mv = 900 * (GetBits16(GP_ADC_CTRL2_REG, GP_ADC_ATTN) + 1); return (uint16_t)((((uint32_t)sample) * ref_mv) >> adc_res); }
void app_adcval1_timer_cb_handler() { struct custs1_val_ntf_ind_req *req = KE_MSG_ALLOC_DYN(CUSTS1_VAL_NTF_REQ, prf_get_task_from_id(TASK_ID_CUSTS1), TASK_APP, custs1_val_ntf_ind_req, DEF_SVC1_ADC_VAL_1_CHAR_LEN); // ADC value to be sampled static uint16_t sample __SECTION_ZERO("retention_mem_area0"); sample = (sample <= 0xffff) ? (sample + 1) : 0; /* Perform single ADC conversion */ uint16_t result = gpadc_read(); /* Print the Adc Result */ arch_printf("\n\radc result: %dmv", gpadc_sample_to_mv(result)); /* Save the ADC Result in a variable in order to update the characteristic */ uint16_t adc_val_mv = gpadc_sample_to_mv(result); //req->conhdl = app_env->conhdl; req->handle = SVC1_IDX_ADC_VAL_1_VAL; req->length = DEF_SVC1_ADC_VAL_1_CHAR_LEN; req->notification = true; /*Change the value updated with adc_val_mv */ memcpy(req->value, &adc_val_mv, DEF_SVC1_ADC_VAL_1_CHAR_LEN); ke_msg_send(req); if (ke_state_get(TASK_APP) == APP_CONNECTED) { // Set it once again until Stop command is received in Control Characteristic timer_used = app_easy_timer(APP_PERIPHERAL_CTRL_TIMER_DELAY, app_adcval1_timer_cb_handler); } }
Hi
Do you have the modified ble_app_peripheral example Project to share?
I tried to make the modifications and compile and got the following errors.
..\src\user_peripheral.c(326): error: #20: identifier "RX_DATAREADY" is undefined case RX_DATAREADY:..\src\user_peripheral.c(454): warning: #167-D: argument of type "void (*)(char *)" is incompatible with parameter of type "timer_callback" X_timer = app_easy_timer(NOTIFICATION_DELAY / 10, user_send_uart_ntf);..\src\user_peripheral.c: 2 warnings, 1 errorcompiling user_serial_interface_manager.c.....\src\user_serial_interface_manager.c(46): error: #20: identifier "TX_COMPLETE" is undefined struct tx_complete *rsp =KE_MSG_ALLOC(TX_COMPLETE,..\src\user_serial_interface_manager.c(74): warning: #167-D: argument of type "void (*)(uint16_t, const ke_msg_id_t, const struct custs1_att_info_req *, const ke_task_id_t, const ke_task_id_t)" is incompatible with parameter of type "uart_cb_t" uart_register_tx_cb(uart, sim_uart_send_cb);..\src\user_serial_interface_manager.c(97): error: #20: identifier "RX_DATAREADY" is undefined struct rx_dataready *res =KE_MSG_ALLOC(RX_DATAREADY,..\src\user_serial_interface_manager.c(102): error: #136: struct "custs1_att_info_req" has no field "m1" strcpy(res->receive_buffer_data,param->m1);..\src\user_serial_interface_manager.c(123): warning: #167-D: argument of type "void (*)(uint16_t, const ke_msg_id_t, const struct custs1_att_info_req *, const ke_task_id_t, const ke_task_id_t)" is incompatible with parameter of type "uart_cb_t" uart_register_rx_cb(uart, sim_uart_receive_cb);..\src\user_serial_interface_manager.c: 2 warnings, 3 errors
Thanks
Jay
Hi Jay,Thank you for your interest in our Wireless products.Please find attached the ble_app_peripheral_adc_characteristic.zip file which contains the project.8015.ble_app_peripheral_adc_characteristic.zipKeep in mind that it has been already shared on this thread as well: (+) ADC VALUES - Bluetooth Low Energy - Wireless Connectivity - Renesas Engineering CommunityNote: Keep in mind that if I remember correctly this is a project based on the SDK v6.0.16. If you are using SDK v6.0.18 or v6.0.20 you can follow the logic shown to port this into the latest versions.Best Regards,OV_Renesas
Hello
Thank you for the prompt response. The SDKI am using is 6.0.16.1144
I am able to compile but during linking I am getting the following
error.111 warnings generated.compiling user_periph_setup.c...linking...In file included from C:\Users\Jameel\AppData\Local\Temp\p2784-2:26:.\out_DA14531\Objects\ble_app_peripheral_531.axf: error: 'da1458x_stack_config.h' file not found#include "da1458x_stack_config.h".\out_DA14531\Objects\ble_app_peripheral_531.axf: Error: L6636E: Pre-processor step failed for '.\..\src\config\copied_scatter_531.sct'.\out_DA14531\Objects\ble_app_peripheral_531.axf: Error: L6372E: Image needs at least one load region.Not enough information to produce a SYMDEFs file.Not enough information to list image symbols.Not enough information to list load addresses in the image map.Finished: 3 information, 0 warning and 2 error messages.".\out_DA14531\Objects\ble_app_peripheral_531.axf" - 3 Error(s), 111 Warning(s).Target not created.Build Time Elapsed: 00:00:17
Regards
Hi Jay,Thank you for the reply.My apologies for the misinformation.The project shared is actually created with the SDK v6.0.18.I was able to use the python script to fix the paths on the SDK v6.0.18 and compile the project as expected.I have added the .hex file here in case you want to Flash it on your device to test it out. ble_app_peripheral_531.zipYou can follow the approach/logic of this implementation on the SDK v6.0.16 as well.If you have any further questions, please create a new ticket because it is easier for us to track that down.Best Regards,OV_Renesas
Thanks for the hex file and I quickly uploaded it to the dev board just to test the functionality and I have the following queries.
>In the 1st custom service, there is a characteristic with a Characteristic User Description: "Control Point" >and another characteristic with a Characteristic User Description: "ADC Value 1". >If you write any value other than 0 on the Control Point characteristic, then a timer starts and updates the >ADC Value 1 characteristic every second with an incrementing value.
I am able to connect and use the SmartBond and I see the 3 custom services.
On clicking the first or 3rd service I am not able to find the control point or the ADC Value parameter is this a modified version of the original one?
Please ignore my earlier post, I managed to get the ADC value in one of the attributes.
How do we interpret this hex value of bf 02
Hi Jay,The Values shown in the SmartBond app are reversed.So the hex value of [bf 02] corresponds to:The GPADC is configured for P0_6, you will have to connect the P0_6 to some power supply to check the values given. We would also suggest you open a Terminal to see the Debug Messages and the ADC result in millivolts being printed out.The UART pins being used are P0_5 and P0_4 and this can be seen on user_periph_setup.h file.For more information on the GPADC, please refer on the adc.h and adc_531.h files and also check the DA14531 Datasheet, on section 27. General Purpose ADC, on page:147.If you have further questions, please raise a new ticket.Best Regards,OV_Renesas