Float voltage to int (#444)

* Change voltage float to millivolt integer
* Explain the ADC to milliVolts conversion
This commit is contained in:
Riku Isokoski 2021-07-02 18:30:32 +03:00 committed by GitHub
parent 7075b7f264
commit 38f40034b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 17 additions and 34 deletions

View File

@ -55,17 +55,21 @@ void Battery::SaadcInit() {
void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) { void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) {
const float battery_max = 4.18; // maximum voltage of battery ( max charging voltage is 4.21 ) const uint16_t battery_max = 4180; // maximum voltage of battery ( max charging voltage is 4.21 )
const float battery_min = 3.20; // minimum voltage of battery before shutdown ( depends on the battery ) const uint16_t battery_min = 3200; // minimum voltage of battery before shutdown ( depends on the battery )
if (p_event->type == NRFX_SAADC_EVT_DONE) { if (p_event->type == NRFX_SAADC_EVT_DONE) {
APP_ERROR_CHECK(nrfx_saadc_buffer_convert(&saadc_value, 1)); APP_ERROR_CHECK(nrfx_saadc_buffer_convert(&saadc_value, 1));
voltage = (static_cast<float>(p_event->data.done.p_buffer[0]) * 2.04f) / (1024 / 3.0f); // A hardware voltage divider divides the battery voltage by 2
voltage = roundf(voltage * 100) / 100; // ADC gain is 1/5
// thus adc_voltage = battery_voltage / 2 * gain = battery_voltage / 10
// reference_voltage is 0.6V
// p_event->data.done.p_buffer[0] = (adc_voltage / reference_voltage) * 1024
voltage = p_event->data.done.p_buffer[0] * 6000 / 1024;
percentRemaining = static_cast<int>(((voltage - battery_min) / (battery_max - battery_min)) * 100); percentRemaining = (voltage - battery_min) * 100 / (battery_max - battery_min);
percentRemaining = std::max(percentRemaining, 0); percentRemaining = std::max(percentRemaining, 0);
percentRemaining = std::min(percentRemaining, 100); percentRemaining = std::min(percentRemaining, 100);

View File

@ -50,7 +50,7 @@ namespace Pinetime {
return percentRemainingBuffer.GetAverage(); return percentRemainingBuffer.GetAverage();
} }
float Voltage() const { uint16_t Voltage() const {
return voltage; return voltage;
} }
@ -71,7 +71,7 @@ namespace Pinetime {
static constexpr uint32_t chargingPin = 12; static constexpr uint32_t chargingPin = 12;
static constexpr uint32_t powerPresentPin = 19; static constexpr uint32_t powerPresentPin = 19;
static constexpr nrf_saadc_input_t batteryVoltageAdcInput = NRF_SAADC_INPUT_AIN7; static constexpr nrf_saadc_input_t batteryVoltageAdcInput = NRF_SAADC_INPUT_AIN7;
float voltage = 0.0f; uint16_t voltage = 0;
int percentRemaining = -1; int percentRemaining = -1;
bool isCharging = false; bool isCharging = false;
@ -86,4 +86,4 @@ namespace Pinetime {
uint8_t samples = 0; uint8_t samples = 0;
}; };
} }
} }

View File

@ -46,16 +46,9 @@ BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Cont
lv_label_set_align(percent, LV_LABEL_ALIGN_LEFT); lv_label_set_align(percent, LV_LABEL_ALIGN_LEFT);
lv_obj_align(percent, nullptr, LV_ALIGN_CENTER, 0, -60); lv_obj_align(percent, nullptr, LV_ALIGN_CENTER, 0, -60);
// hack to not use the flot functions from printf
uint8_t batteryVoltageBytes[2];
batteryVoltageBytes[1] = static_cast<uint8_t>(batteryVoltage); // truncate whole numbers
batteryVoltageBytes[0] =
static_cast<uint8_t>((batteryVoltage - batteryVoltageBytes[1]) * 100); // remove whole part of flt and shift 2 places over
//
voltage = lv_label_create(lv_scr_act(), nullptr); voltage = lv_label_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_text_color(voltage, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xC6A600)); lv_obj_set_style_local_text_color(voltage, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xC6A600));
lv_label_set_text_fmt(voltage, "%1i.%02i volts", batteryVoltageBytes[1], batteryVoltageBytes[0]); lv_label_set_text_fmt(voltage, "%1i.%02i volts", batteryVoltage / 1000, batteryVoltage % 1000 / 10);
lv_label_set_align(voltage, LV_LABEL_ALIGN_CENTER); lv_label_set_align(voltage, LV_LABEL_ALIGN_CENTER);
lv_obj_align(voltage, nullptr, LV_ALIGN_CENTER, 0, 95); lv_obj_align(voltage, nullptr, LV_ALIGN_CENTER, 0, 95);
@ -129,13 +122,7 @@ void BatteryInfo::UpdateScreen() {
} }
lv_obj_align(status, charging_bar, LV_ALIGN_OUT_BOTTOM_MID, 0, 20); lv_obj_align(status, charging_bar, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);
// hack to not use the flot functions from printf lv_label_set_text_fmt(voltage, "%1i.%02i volts", batteryVoltage / 1000, batteryVoltage % 1000 / 10);
uint8_t batteryVoltageBytes[2];
batteryVoltageBytes[1] = static_cast<uint8_t>(batteryVoltage); // truncate whole numbers
batteryVoltageBytes[0] =
static_cast<uint8_t>((batteryVoltage - batteryVoltageBytes[1]) * 100); // remove whole part of flt and shift 2 places over
//
lv_label_set_text_fmt(voltage, "%1i.%02i volts", batteryVoltageBytes[1], batteryVoltageBytes[0]);
} }
bool BatteryInfo::Refresh() { bool BatteryInfo::Refresh() {

View File

@ -37,7 +37,7 @@ namespace Pinetime {
int8_t animation = 0; int8_t animation = 0;
int8_t batteryPercent = -1; int8_t batteryPercent = -1;
float batteryVoltage = 0.0f; uint16_t batteryVoltage = 0;
}; };
} }
} }

View File

@ -104,8 +104,6 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen1() {
std::unique_ptr<Screen> SystemInfo::CreateScreen2() { std::unique_ptr<Screen> SystemInfo::CreateScreen2() {
auto batteryPercent = static_cast<uint8_t>(batteryController.PercentRemaining()); auto batteryPercent = static_cast<uint8_t>(batteryController.PercentRemaining());
float batteryVoltage = batteryController.Voltage();
auto resetReason = [this]() { auto resetReason = [this]() {
switch (watchdog.ResetReason()) { switch (watchdog.ResetReason()) {
case Drivers::Watchdog::ResetReasons::Watchdog: case Drivers::Watchdog::ResetReasons::Watchdog:
@ -144,18 +142,13 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen2() {
uptimeSeconds = uptimeSeconds % secondsInAMinute; uptimeSeconds = uptimeSeconds % secondsInAMinute;
// TODO handle more than 100 days of uptime // TODO handle more than 100 days of uptime
// hack to not use the flot functions from printf
uint8_t batteryVoltageBytes[2];
batteryVoltageBytes[1] = static_cast<uint8_t>(batteryVoltage); // truncate whole numbers
batteryVoltageBytes[0] = static_cast<uint8_t>((batteryVoltage - batteryVoltageBytes[1]) * 100); // remove whole part of flt and shift 2 places over
lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_recolor(label, true); lv_label_set_recolor(label, true);
lv_label_set_text_fmt(label, lv_label_set_text_fmt(label,
"#444444 Date# %02d/%02d/%04d\n" "#444444 Date# %02d/%02d/%04d\n"
"#444444 Time# %02d:%02d:%02d\n" "#444444 Time# %02d:%02d:%02d\n"
"#444444 Uptime#\n %02lud %02lu:%02lu:%02lu\n" "#444444 Uptime#\n %02lud %02lu:%02lu:%02lu\n"
"#444444 Battery# %d%%/%1i.%02iv\n" "#444444 Battery# %d%%/%03imV\n"
"#444444 Backlight# %s\n" "#444444 Backlight# %s\n"
"#444444 Last reset# %s\n" "#444444 Last reset# %s\n"
"#444444 Accel.# %s\n", "#444444 Accel.# %s\n",
@ -170,8 +163,7 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen2() {
uptimeMinutes, uptimeMinutes,
uptimeSeconds, uptimeSeconds,
batteryPercent, batteryPercent,
batteryVoltageBytes[1], batteryController.Voltage(),
batteryVoltageBytes[0],
brightnessController.ToString(), brightnessController.ToString(),
resetReason, resetReason,
ToString(motionController.DeviceType())); ToString(motionController.DeviceType()));