Add battery level reporting (Kconfig-gated) and display orientation
Build and push server image / build-and-push (push) Successful in 32s
Build and push server image / build-and-push (push) Successful in 32s
Battery (firmware + server, disabled by default): new battery.c reads a 2x200k voltage divider via ADC oneshot with curve-fitting calibration (the ESP32-C6's scheme), maps through a piecewise LiPo discharge curve, and restores the pin to button duty after each read -- the settled XIAO ESP32-C6 design shares the back button's GPIO0/A0, time-shared per wake. Skipped entirely when on mains (a 2x100k VBUS divider into a spare digital pin -- the 5V pin is dead on battery power, so presence = mains, where the charging voltage would read misleadingly full) or when the reading is implausible. The manage overlay gains a battery region (static outline glyph + "NN%", below the manage QR, all menu levels), and the device POSTs to the new /frame/battery endpoint after a successful fetch; the server stores percent + as-of timestamp, exposed via /api/queue and shown in the web UI. FRAME_BATTERY_ADC_GPIO / FRAME_VBUS_SENSE_GPIO default to -1 (fully inert on the dev board); compile-verified both disabled and enabled, hardware bring-up deferred until the ordered XIAO + batteries arrive. Orientation (server-side only): new config setting + web UI dropdown (landscape / portrait / landscape_flipped / portrait_flipped). Photos are composed/cropped at the logical hanging shape (portrait crops at 480x800, so face-aware crops match how the frame actually hangs), then rotated losslessly into the panel's native 800x480 byte layout after dithering -- the device never knows. Face-label anchors are transformed through the same rotation (logical_to_native()) so they stay attached to faces on rotated frames. Known documented limitation: the on-device manage overlay still renders in native orientation, so it appears sideways on a portrait-hung frame (QRs scan at any rotation; text reads sideways).
This commit is contained in:
@@ -4,15 +4,15 @@
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
/* 4 fixed corner regions (manage QR, location, date, share QR) plus up
|
||||
* to MANAGE_FACE_LABELS_MAX arbitrary-position named-face labels (see
|
||||
* manage_face_label_t below). MANAGE_FACE_LABELS_MAX is capped small
|
||||
* deliberately, not arbitrarily -- each label is its own malloc'd
|
||||
* buffer, and the 4 fixed regions alone already use a meaningful chunk
|
||||
* of the ESP32-C6's limited RAM; this keeps worst-case overlay memory
|
||||
* well clear of what the WiFi/HTTP stack needs alongside it. */
|
||||
/* 5 fixed regions (manage QR, battery indicator, location, date, share
|
||||
* QR) plus up to MANAGE_FACE_LABELS_MAX arbitrary-position named-face
|
||||
* labels (see manage_face_label_t below). MANAGE_FACE_LABELS_MAX is
|
||||
* capped small deliberately, not arbitrarily -- each label is its own
|
||||
* malloc'd buffer, and the fixed regions alone already use a meaningful
|
||||
* chunk of the ESP32-C6's limited RAM; this keeps worst-case overlay
|
||||
* memory well clear of what the WiFi/HTTP stack needs alongside it. */
|
||||
#define MANAGE_FACE_LABELS_MAX 4
|
||||
#define MANAGE_OVERLAY_MAX_REGIONS (4 + MANAGE_FACE_LABELS_MAX)
|
||||
#define MANAGE_OVERLAY_MAX_REGIONS (5 + MANAGE_FACE_LABELS_MAX)
|
||||
|
||||
typedef struct {
|
||||
uint8_t *buf; /* malloc'd (w/2)*h bytes, packed 2px/byte; owned by the region */
|
||||
@@ -38,6 +38,7 @@ typedef struct {
|
||||
const char *share_url; /* bottom-left QR + "SCAN TO"/"DOWNLOAD" caption; NULL/empty skips this region */
|
||||
const manage_face_label_t *face_labels; /* named-face labels ("level 2" menu); NULL/empty count skips these */
|
||||
int face_label_count; /* clamped to MANAGE_FACE_LABELS_MAX internally */
|
||||
int battery_percent; /* 0-100 shows an icon + percent below the manage QR; -1 skips it */
|
||||
} manage_overlay_content_t;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user