Hello, I am using the heart rate collector example on one NRF52 DK (central), and the heart rate service example on another NRF52 DK (peripheral).
I replaced the sensor sim on the peripheral, and replaced it with saadc to send actual readings to the collector.
With both DK's plugged in to my PC, I - as expected - received a constant reading of 100% battery from the peripheral. But when i unplugged the peripheral from USB power to sample the percentage level of a brand new Energizer cr2032 coin cell battery, the readings did not go as expected.
The initial percentage of the coin cell read from the peripheral started at 100%, but within a few seconds, the battery level began rapidly decreasing (about 2% every 20 seconds). After a few minutes I noticed that the percentage of the battery had halted at around 16-17%, and wouldn''t decrease any further from that level. I took that battery out, and tested another new cr2032. The same thing happened where it drained to about 16% and stopped within a few minutes.
Every 2 seconds (app timer), the battery_level_meas_timeout_handler is called on the peripheral
static void adc_configure(void)
{
ret_code_t err_code = nrf_drv_saadc_init(NULL, saadc_event_handler);
APP_ERROR_CHECK(err_code);
nrf_saadc_channel_config_t config =
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_VDD);
err_code = nrf_drv_saadc_channel_init(0, &config);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_buffer_convert(&adc_buf[0], 1);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_buffer_convert(&adc_buf[1], 1);
APP_ERROR_CHECK(err_code);
}
static void battery_level_meas_timeout_handler(void * p_context)
{
UNUSED_PARAMETER(p_context);
battery_level_update();
}
static void battery_level_update(void)
{
ret_code_t err_code;
err_code = nrf_drv_saadc_sample();
APP_ERROR_CHECK(err_code);
}
void saadc_event_handler(nrf_drv_saadc_evt_t const * p_event)
{
if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
{
nrf_saadc_value_t adc_result;
uint16_t batt_lvl_in_milli_volts;
uint8_t percentage_batt_lvl;
uint32_t err_code;
adc_result = p_event->data.done.p_buffer[0];
err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, 1);
APP_ERROR_CHECK(err_code);
batt_lvl_in_milli_volts = ADC_RESULT_IN_MILLI_VOLTS(adc_result) +
DIODE_FWD_VOLT_DROP_MILLIVOLTS;
percentage_batt_lvl = battery_level_in_percent(batt_lvl_in_milli_volts);
printf("Battery level is: %d%%", percentage_batt_lvl);
err_code = ble_bas_battery_level_update(&m_bas, percentage_batt_lvl, BLE_CONN_HANDLE_ALL);
if ((err_code != NRF_SUCCESS) &&
(err_code != NRF_ERROR_INVALID_STATE) &&
(err_code != NRF_ERROR_RESOURCES) &&
(err_code != NRF_ERROR_BUSY) &&
(err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
)
{
APP_ERROR_HANDLER(err_code);
}
}
}
I also used the defines that where provided in the proximity example:
#define ADC_REF_VOLTAGE_IN_MILLIVOLTS 600 /**< Reference voltage (in milli volts) used by ADC while doing conversion. */
#define ADC_PRE_SCALING_COMPENSATION 6 /**< The ADC is configured to use VDD with 1/3 prescaling as input. And hence the result of conversion is to be multiplied by 3 to get the actual value of the battery voltage.*/
#define DIODE_FWD_VOLT_DROP_MILLIVOLTS 270 /**< Typical forward voltage drop of the diode . */
#define ADC_RES_10BIT 1024 /**< Maximum digital value for 10-bit ADC conversion. */
#define ADC_RESULT_IN_MILLI_VOLTS(ADC_VALUE)\
((((ADC_VALUE) * ADC_REF_VOLTAGE_IN_MILLIVOLTS) / ADC_RES_10BIT) * ADC_PRE_SCALING_COMPENSATION)
Any idea as to what could cause these weird battery percentage readings?
(I don't plan on using the heart rate example in the future, and I'm aware that not uninitializing ADC in between samples consumes large amounts of current, I simply wanted to test the results of saadc for use in other programs.)
Thanks, Jeremy