mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-04 14:47:37 +03:00
Merge d192043853 into 78d6e5931c
This commit is contained in:
commit
4637f68c81
47
src/Battery.cpp
Normal file
47
src/Battery.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#include "Battery.h"
|
||||||
|
|
||||||
|
void BatteryPercentageRingBuffer::init(uint8_t v) {
|
||||||
|
for (size_t i = 0; i < MAX_SAMPLES; i++) {
|
||||||
|
buf[i] = v;
|
||||||
|
}
|
||||||
|
sum = v * MAX_SAMPLES;
|
||||||
|
prev_val = v;
|
||||||
|
head = 0;
|
||||||
|
was_charging = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BatteryPercentageRingBuffer::update(uint8_t v) {
|
||||||
|
// Previous percentage is set > 100 only if buffer was constructed but not initialized yet
|
||||||
|
if (prev_val > 100) {
|
||||||
|
init(v);
|
||||||
|
was_charging = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer was reintilialized with readout values while charging (can be too high values), reinit with new readout
|
||||||
|
// after charging
|
||||||
|
if (was_charging) {
|
||||||
|
init(v);
|
||||||
|
was_charging = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recalculate rolling sum
|
||||||
|
sum -= buf[head];
|
||||||
|
buf[head] = v;
|
||||||
|
sum += v;
|
||||||
|
|
||||||
|
// Shift head
|
||||||
|
head++;
|
||||||
|
if (head >= MAX_SAMPLES) head = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t BatteryPercentageRingBuffer::evaluate() {
|
||||||
|
uint8_t new_val = (sum + MAX_SAMPLES / 2) / MAX_SAMPLES;
|
||||||
|
|
||||||
|
// Battery percentage should not increase when not charging so we just cap it to be lower than the last value
|
||||||
|
if (new_val < prev_val) {
|
||||||
|
prev_val = new_val;
|
||||||
|
return new_val;
|
||||||
|
} else {
|
||||||
|
return prev_val;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,22 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <BatteryMonitor.h>
|
#include <BatteryMonitor.h>
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
#define BAT_GPIO0 0 // Battery voltage
|
#define BAT_GPIO0 0 // Battery voltage
|
||||||
|
|
||||||
static BatteryMonitor battery(BAT_GPIO0);
|
static BatteryMonitor battery(BAT_GPIO0);
|
||||||
|
|
||||||
|
struct BatteryPercentageRingBuffer {
|
||||||
|
static constexpr uint8_t MAX_SAMPLES = 10;
|
||||||
|
|
||||||
|
uint8_t buf[MAX_SAMPLES];
|
||||||
|
uint8_t head = 0;
|
||||||
|
uint16_t sum = 0;
|
||||||
|
uint8_t prev_val = 161;
|
||||||
|
bool was_charging = false;
|
||||||
|
|
||||||
|
void init(uint8_t value);
|
||||||
|
void update(uint8_t value);
|
||||||
|
uint8_t evaluate();
|
||||||
|
};
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#include "ScreenComponents.h"
|
#include "ScreenComponents.h"
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
#include <GfxRenderer.h>
|
#include <GfxRenderer.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -8,10 +9,24 @@
|
|||||||
#include "Battery.h"
|
#include "Battery.h"
|
||||||
#include "fontIds.h"
|
#include "fontIds.h"
|
||||||
|
|
||||||
|
BatteryPercentageRingBuffer ScreenComponents::batteryBuffer;
|
||||||
|
|
||||||
void ScreenComponents::drawBattery(const GfxRenderer& renderer, const int left, const int top,
|
void ScreenComponents::drawBattery(const GfxRenderer& renderer, const int left, const int top,
|
||||||
const bool showPercentage) {
|
const bool showPercentage) {
|
||||||
|
const bool charging = (digitalRead(20) == HIGH);
|
||||||
|
|
||||||
// Left aligned battery icon and percentage
|
// Left aligned battery icon and percentage
|
||||||
const uint16_t percentage = battery.readPercentage();
|
uint16_t percentage = battery.readPercentage();
|
||||||
|
|
||||||
|
if (charging) {
|
||||||
|
// If charging reinitialize buffer with current percentage and display this value
|
||||||
|
batteryBuffer.init(percentage);
|
||||||
|
} else {
|
||||||
|
// Else update buffer with new percentage and return smoothed validated percentage to display
|
||||||
|
batteryBuffer.update(percentage);
|
||||||
|
percentage = batteryBuffer.evaluate();
|
||||||
|
}
|
||||||
|
|
||||||
const auto percentageText = showPercentage ? std::to_string(percentage) + "%" : "";
|
const auto percentageText = showPercentage ? std::to_string(percentage) + "%" : "";
|
||||||
renderer.drawText(SMALL_FONT_ID, left + 20, top, percentageText.c_str());
|
renderer.drawText(SMALL_FONT_ID, left + 20, top, percentageText.c_str());
|
||||||
|
|
||||||
@ -34,12 +49,38 @@ void ScreenComponents::drawBattery(const GfxRenderer& renderer, const int left,
|
|||||||
renderer.drawLine(x + batteryWidth - 0, y + 4, x + batteryWidth - 0, y + batteryHeight - 5);
|
renderer.drawLine(x + batteryWidth - 0, y + 4, x + batteryWidth - 0, y + batteryHeight - 5);
|
||||||
|
|
||||||
// The +1 is to round up, so that we always fill at least one pixel
|
// The +1 is to round up, so that we always fill at least one pixel
|
||||||
int filledWidth = percentage * (batteryWidth - 5) / 100 + 1;
|
constexpr int maxFillWidth = batteryWidth - 5;
|
||||||
if (filledWidth > batteryWidth - 5) {
|
int filledWidth = percentage * maxFillWidth / 100 + 1;
|
||||||
filledWidth = batteryWidth - 5; // Ensure we don't overflow
|
if (filledWidth > maxFillWidth) {
|
||||||
|
filledWidth = maxFillWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When charging, ensure minimum fill so lightning bolt is fully visible
|
||||||
|
constexpr int minFillForBolt = 8; // Bolt extends 6px wide, needs padding
|
||||||
|
if (charging && filledWidth < minFillForBolt) {
|
||||||
|
filledWidth = minFillForBolt;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.fillRect(x + 2, y + 2, filledWidth, batteryHeight - 4);
|
renderer.fillRect(x + 2, y + 2, filledWidth, batteryHeight - 4);
|
||||||
|
|
||||||
|
// Draw lightning bolt when charging (white/inverted on black fill for visibility)
|
||||||
|
if (charging) {
|
||||||
|
// Lightning bolt: 6px wide, 8px tall, centered in battery
|
||||||
|
const int boltX = x + 4;
|
||||||
|
const int boltY = y + 2;
|
||||||
|
|
||||||
|
// Draw bolt in white (state=false) for visibility on black fill
|
||||||
|
// Upper diagonal pointing right
|
||||||
|
renderer.drawLine(boltX + 4, boltY + 0, boltX + 5, boltY + 0, false);
|
||||||
|
renderer.drawLine(boltX + 3, boltY + 1, boltX + 4, boltY + 1, false);
|
||||||
|
renderer.drawLine(boltX + 2, boltY + 2, boltX + 5, boltY + 2, false); // Wide middle
|
||||||
|
renderer.drawLine(boltX + 3, boltY + 3, boltX + 4, boltY + 3, false);
|
||||||
|
// Lower diagonal pointing left
|
||||||
|
renderer.drawLine(boltX + 2, boltY + 4, boltX + 3, boltY + 4, false);
|
||||||
|
renderer.drawLine(boltX + 1, boltY + 5, boltX + 4, boltY + 5, false); // Wide middle
|
||||||
|
renderer.drawLine(boltX + 2, boltY + 6, boltX + 3, boltY + 6, false);
|
||||||
|
renderer.drawLine(boltX + 1, boltY + 7, boltX + 2, boltY + 7, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenComponents::PopupLayout ScreenComponents::drawPopup(const GfxRenderer& renderer, const char* message) {
|
ScreenComponents::PopupLayout ScreenComponents::drawPopup(const GfxRenderer& renderer, const char* message) {
|
||||||
|
|||||||
@ -4,6 +4,8 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Battery.h"
|
||||||
|
|
||||||
class GfxRenderer;
|
class GfxRenderer;
|
||||||
|
|
||||||
struct TabInfo {
|
struct TabInfo {
|
||||||
@ -15,6 +17,8 @@ class ScreenComponents {
|
|||||||
public:
|
public:
|
||||||
static const int BOOK_PROGRESS_BAR_HEIGHT = 4;
|
static const int BOOK_PROGRESS_BAR_HEIGHT = 4;
|
||||||
|
|
||||||
|
static BatteryPercentageRingBuffer batteryBuffer;
|
||||||
|
|
||||||
struct PopupLayout {
|
struct PopupLayout {
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user