From aa2b43cea9d397c96b92cfd749bdaef4ebd1fcb6 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Sun, 20 Jun 2021 18:09:30 +0300 Subject: [PATCH 1/2] Change voltage float to millivolt integer --- src/components/battery/BatteryController.cpp | 9 ++++----- src/components/battery/BatteryController.h | 6 +++--- src/displayapp/screens/BatteryInfo.cpp | 17 ++--------------- src/displayapp/screens/BatteryInfo.h | 2 +- src/displayapp/screens/SystemInfo.cpp | 12 ++---------- 5 files changed, 12 insertions(+), 34 deletions(-) diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index bc14645796..d3a68d9f83 100644 --- a/src/components/battery/BatteryController.cpp +++ b/src/components/battery/BatteryController.cpp @@ -55,17 +55,16 @@ void Battery::SaadcInit() { 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 float battery_min = 3.20; // minimum voltage of battery before shutdown ( depends on the battery ) + const uint16_t battery_max = 4180; // maximum voltage of battery ( max charging voltage is 4.21 ) + const uint16_t battery_min = 3200; // minimum voltage of battery before shutdown ( depends on the battery ) if (p_event->type == NRFX_SAADC_EVT_DONE) { APP_ERROR_CHECK(nrfx_saadc_buffer_convert(&saadc_value, 1)); - voltage = (static_cast(p_event->data.done.p_buffer[0]) * 2.04f) / (1024 / 3.0f); - voltage = roundf(voltage * 100) / 100; + voltage = p_event->data.done.p_buffer[0] * 2000 / 341; - percentRemaining = static_cast(((voltage - battery_min) / (battery_max - battery_min)) * 100); + percentRemaining = (voltage - battery_min) * 100 / (battery_max - battery_min); percentRemaining = std::max(percentRemaining, 0); percentRemaining = std::min(percentRemaining, 100); diff --git a/src/components/battery/BatteryController.h b/src/components/battery/BatteryController.h index 04bcf6b899..26e24938bc 100644 --- a/src/components/battery/BatteryController.h +++ b/src/components/battery/BatteryController.h @@ -50,7 +50,7 @@ namespace Pinetime { return percentRemainingBuffer.GetAverage(); } - float Voltage() const { + uint16_t Voltage() const { return voltage; } @@ -71,7 +71,7 @@ namespace Pinetime { static constexpr uint32_t chargingPin = 12; static constexpr uint32_t powerPresentPin = 19; static constexpr nrf_saadc_input_t batteryVoltageAdcInput = NRF_SAADC_INPUT_AIN7; - float voltage = 0.0f; + uint16_t voltage = 0; int percentRemaining = -1; bool isCharging = false; @@ -86,4 +86,4 @@ namespace Pinetime { uint8_t samples = 0; }; } -} \ No newline at end of file +} diff --git a/src/displayapp/screens/BatteryInfo.cpp b/src/displayapp/screens/BatteryInfo.cpp index 1ab8b0ad5e..87c8b4bb02 100644 --- a/src/displayapp/screens/BatteryInfo.cpp +++ b/src/displayapp/screens/BatteryInfo.cpp @@ -46,16 +46,9 @@ BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Cont lv_label_set_align(percent, LV_LABEL_ALIGN_LEFT); 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(batteryVoltage); // truncate whole numbers - batteryVoltageBytes[0] = - static_cast((batteryVoltage - batteryVoltageBytes[1]) * 100); // remove whole part of flt and shift 2 places over - // - 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_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_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); - // hack to not use the flot functions from printf - uint8_t batteryVoltageBytes[2]; - batteryVoltageBytes[1] = static_cast(batteryVoltage); // truncate whole numbers - batteryVoltageBytes[0] = - static_cast((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]); + lv_label_set_text_fmt(voltage, "%1i.%02i volts", batteryVoltage / 1000, batteryVoltage % 1000 / 10); } bool BatteryInfo::Refresh() { diff --git a/src/displayapp/screens/BatteryInfo.h b/src/displayapp/screens/BatteryInfo.h index 8805db5868..346dc5715c 100644 --- a/src/displayapp/screens/BatteryInfo.h +++ b/src/displayapp/screens/BatteryInfo.h @@ -37,7 +37,7 @@ namespace Pinetime { int8_t animation = 0; int8_t batteryPercent = -1; - float batteryVoltage = 0.0f; + uint16_t batteryVoltage = 0; }; } } diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp index 0b16d63396..2d153cf82c 100644 --- a/src/displayapp/screens/SystemInfo.cpp +++ b/src/displayapp/screens/SystemInfo.cpp @@ -101,8 +101,6 @@ std::unique_ptr SystemInfo::CreateScreen1() { std::unique_ptr SystemInfo::CreateScreen2() { auto batteryPercent = static_cast(batteryController.PercentRemaining()); - float batteryVoltage = batteryController.Voltage(); - auto resetReason = [this]() { switch (watchdog.ResetReason()) { case Drivers::Watchdog::ResetReasons::Watchdog: @@ -144,18 +142,13 @@ std::unique_ptr SystemInfo::CreateScreen2() { if (batteryPercent == -1) batteryPercent = 0; - // hack to not use the flot functions from printf - uint8_t batteryVoltageBytes[2]; - batteryVoltageBytes[1] = static_cast(batteryVoltage); // truncate whole numbers - batteryVoltageBytes[0] = static_cast((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_label_set_recolor(label, true); lv_label_set_text_fmt(label, "#444444 Date# %02d/%02d/%04d\n" "#444444 Time# %02d:%02d:%02d\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 Last reset# %s\n" "#444444 Accel.# %s\n", @@ -170,8 +163,7 @@ std::unique_ptr SystemInfo::CreateScreen2() { uptimeMinutes, uptimeSeconds, batteryPercent, - batteryVoltageBytes[1], - batteryVoltageBytes[0], + batteryController.Voltage(), brightnessController.ToString(), resetReason, ToString(motionController.DeviceType())); From 76aa83ddf44022939b4457a79ece8f2790290738 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Sun, 20 Jun 2021 18:52:23 +0300 Subject: [PATCH 2/2] Explain the ADC to milliVolts conversion --- src/components/battery/BatteryController.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index d3a68d9f83..0c299b03e2 100644 --- a/src/components/battery/BatteryController.cpp +++ b/src/components/battery/BatteryController.cpp @@ -62,7 +62,12 @@ void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) { APP_ERROR_CHECK(nrfx_saadc_buffer_convert(&saadc_value, 1)); - voltage = p_event->data.done.p_buffer[0] * 2000 / 341; + // A hardware voltage divider divides the battery voltage by 2 + // 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 = (voltage - battery_min) * 100 / (battery_max - battery_min);