diff options
| author | jacqueline <me@jacqueline.id.au> | 2023-08-28 13:26:53 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2023-08-28 13:26:53 +1000 |
| commit | 3a0c42f9240eedfbc6a1e94ad3a59c52664fb5b5 (patch) | |
| tree | 0505db40de6fceaf5829548ef86f4cb53b739bcb /src/drivers/adc.cpp | |
| parent | a1327763ab70dbf4996e032dd227de368f78f4ad (diff) | |
| download | tangara-fw-3a0c42f9240eedfbc6a1e94ad3a59c52664fb5b5.tar.gz | |
Move battery measurement to its own class
Diffstat (limited to 'src/drivers/adc.cpp')
| -rw-r--r-- | src/drivers/adc.cpp | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/src/drivers/adc.cpp b/src/drivers/adc.cpp new file mode 100644 index 00000000..56d2cbb4 --- /dev/null +++ b/src/drivers/adc.cpp @@ -0,0 +1,67 @@ +/* + * Copyright 2023 jacqueline <me@jacqueline.id.au> + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include "adc.hpp" +#include <cstdint> + +#include "esp_adc/adc_cali.h" +#include "esp_adc/adc_cali_scheme.h" +#include "esp_adc/adc_oneshot.h" +#include "hal/adc_types.h" + +namespace drivers { + +static const adc_bitwidth_t kAdcBitWidth = ADC_BITWIDTH_12; +static const adc_unit_t kAdcUnit = ADC_UNIT_1; +// Max battery voltage should be a little over 2V due to our divider, so we need +// the max attenuation to properly handle the full range. +static const adc_atten_t kAdcAttenuation = ADC_ATTEN_DB_11; +// Corresponds to SENSOR_VP. +static const adc_channel_t kAdcChannel = ADC_CHANNEL_0; + +AdcBattery::AdcBattery() { + adc_oneshot_unit_init_cfg_t unit_config = { + .unit_id = kAdcUnit, + }; + ESP_ERROR_CHECK(adc_oneshot_new_unit(&unit_config, &adc_handle_)); + + adc_oneshot_chan_cfg_t channel_config = { + .atten = kAdcAttenuation, + .bitwidth = kAdcBitWidth, + }; + ESP_ERROR_CHECK( + adc_oneshot_config_channel(adc_handle_, kAdcChannel, &channel_config)); + + // calibrate + // TODO: compile-time assert our scheme is available + adc_cali_line_fitting_config_t calibration_config = { + .unit_id = kAdcUnit, + .atten = kAdcAttenuation, + .bitwidth = kAdcBitWidth, + }; + ESP_ERROR_CHECK(adc_cali_create_scheme_line_fitting( + &calibration_config, &adc_calibration_handle_)); +} + +AdcBattery::~AdcBattery() { + adc_cali_delete_scheme_line_fitting(adc_calibration_handle_); + ESP_ERROR_CHECK(adc_oneshot_del_unit(adc_handle_)); +} + +auto AdcBattery::Millivolts() -> uint32_t { + // GPIO 34 + int raw = 0; + ESP_ERROR_CHECK(adc_oneshot_read(adc_handle_, kAdcChannel, &raw)); + + int voltage = 0; + ESP_ERROR_CHECK( + adc_cali_raw_to_voltage(adc_calibration_handle_, raw, &voltage)); + + // Voltage divider halves the battery voltage to get it into the ADC's range. + return voltage * 2; +} + +} // namespace drivers |
