mirror of
https://github.com/pelgraine/Meck.git
synced 2026-03-28 17:42:44 +01:00
Compare commits
6 Commits
red-LED-fi
...
txt-reader
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af9f41a541 | ||
|
|
0a746cdca5 | ||
|
|
3a5c48f440 | ||
|
|
e40d9ced4a | ||
|
|
b8de2d0d16 | ||
|
|
9fbc3202f6 |
@@ -8,11 +8,11 @@
|
||||
#define FIRMWARE_VER_CODE 8
|
||||
|
||||
#ifndef FIRMWARE_BUILD_DATE
|
||||
#define FIRMWARE_BUILD_DATE "2 Feb 2026"
|
||||
#define FIRMWARE_BUILD_DATE "7 Feb 2026"
|
||||
#endif
|
||||
|
||||
#ifndef FIRMWARE_VERSION
|
||||
#define FIRMWARE_VERSION "Meck v0.6.1"
|
||||
#define FIRMWARE_VERSION "Meck v0.6.3"
|
||||
#endif
|
||||
|
||||
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
static uint8_t composeChannelIdx = 0; // Which channel to send to
|
||||
static unsigned long lastComposeRefresh = 0;
|
||||
static bool composeNeedsRefresh = false;
|
||||
#define COMPOSE_REFRESH_INTERVAL 250 // ms between e-ink refreshes while typing
|
||||
#define COMPOSE_REFRESH_INTERVAL 600 // ms between e-ink refreshes while typing (refresh takes ~650ms)
|
||||
|
||||
void initKeyboard();
|
||||
void handleKeyboardInput();
|
||||
@@ -646,8 +646,6 @@ void drawComposeScreen() {
|
||||
void sendComposedMessage() {
|
||||
if (composePos == 0) return;
|
||||
|
||||
MESH_DEBUG_PRINTLN("Sending message to channel %d: %s", composeChannelIdx, composeBuffer);
|
||||
|
||||
// Get the selected channel
|
||||
ChannelDetails channel;
|
||||
if (the_mesh.getChannel(composeChannelIdx, channel)) {
|
||||
@@ -657,8 +655,6 @@ void sendComposedMessage() {
|
||||
if (the_mesh.sendGroupMessage(timestamp, channel.channel,
|
||||
the_mesh.getNodePrefs()->node_name,
|
||||
composeBuffer, composePos)) {
|
||||
MESH_DEBUG_PRINTLN("Message sent to channel %s", channel.name);
|
||||
|
||||
// Add the sent message to local channel history so we can see what we sent
|
||||
ui_task.addSentChannelMessage(composeChannelIdx,
|
||||
the_mesh.getNodePrefs()->node_name,
|
||||
@@ -671,11 +667,9 @@ void sendComposedMessage() {
|
||||
|
||||
ui_task.showAlert("Sent!", 1500);
|
||||
} else {
|
||||
MESH_DEBUG_PRINTLN("Failed to send message");
|
||||
ui_task.showAlert("Send failed!", 1500);
|
||||
}
|
||||
} else {
|
||||
MESH_DEBUG_PRINTLN("Could not get channel %d", composeChannelIdx);
|
||||
ui_task.showAlert("No channel!", 1500);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,29 +104,53 @@ class HomeScreen : public UIScreen {
|
||||
|
||||
|
||||
void renderBatteryIndicator(DisplayDriver& display, uint16_t batteryMilliVolts) {
|
||||
// Convert millivolts to percentage
|
||||
const int minMilliVolts = 3000; // Minimum voltage (e.g., 3.0V)
|
||||
const int maxMilliVolts = 4200; // Maximum voltage (e.g., 4.2V)
|
||||
int batteryPercentage = ((batteryMilliVolts - minMilliVolts) * 100) / (maxMilliVolts - minMilliVolts);
|
||||
if (batteryPercentage < 0) batteryPercentage = 0; // Clamp to 0%
|
||||
if (batteryPercentage > 100) batteryPercentage = 100; // Clamp to 100%
|
||||
// Try to get accurate SOC from BQ27220 fuel gauge first
|
||||
uint8_t batteryPercentage = board.getBatteryPercent();
|
||||
|
||||
// Fall back to voltage-based estimation if fuel gauge returns 0
|
||||
if (batteryPercentage == 0 && batteryMilliVolts > 0) {
|
||||
const int minMilliVolts = 3000;
|
||||
const int maxMilliVolts = 4200;
|
||||
int pct = ((batteryMilliVolts - minMilliVolts) * 100) / (maxMilliVolts - minMilliVolts);
|
||||
if (pct < 0) pct = 0;
|
||||
if (pct > 100) pct = 100;
|
||||
batteryPercentage = (uint8_t)pct;
|
||||
}
|
||||
|
||||
// battery icon
|
||||
int iconWidth = 22;
|
||||
int iconHeight = 8;
|
||||
int iconX = display.width() - iconWidth - 5; // Position the icon near the top-right corner
|
||||
int iconY = 0;
|
||||
display.setColor(DisplayDriver::GREEN);
|
||||
|
||||
// battery icon dimensions (smaller to match tiny percentage text)
|
||||
int iconWidth = 16;
|
||||
int iconHeight = 6;
|
||||
|
||||
// measure percentage text width to position icon + text together at right edge
|
||||
display.setTextSize(0);
|
||||
char pctStr[5];
|
||||
sprintf(pctStr, "%d%%", batteryPercentage);
|
||||
uint16_t textWidth = display.getTextWidth(pctStr);
|
||||
|
||||
// layout: [icon 16px][cap 2px][gap 2px][text][margin 2px]
|
||||
int totalWidth = iconWidth + 2 + 2 + textWidth + 2;
|
||||
int iconX = display.width() - totalWidth;
|
||||
int iconY = 0; // vertically align with node name text
|
||||
|
||||
// battery outline
|
||||
display.drawRect(iconX, iconY, iconWidth, iconHeight);
|
||||
|
||||
// battery "cap"
|
||||
display.fillRect(iconX + iconWidth, iconY + (iconHeight / 4), 3, iconHeight / 2);
|
||||
display.fillRect(iconX + iconWidth, iconY + (iconHeight / 4), 2, iconHeight / 2);
|
||||
|
||||
// fill the battery based on the percentage
|
||||
int fillWidth = (batteryPercentage * (iconWidth - 4)) / 100;
|
||||
display.fillRect(iconX + 2, iconY + 2, fillWidth, iconHeight - 4);
|
||||
|
||||
// draw percentage text after the battery cap, offset upward to center with icon
|
||||
// (setCursor adds +5 internally for baseline, so compensate for the tiny font)
|
||||
int textX = iconX + iconWidth + 2 + 2; // after cap + gap
|
||||
int textY = iconY - 3; // offset up to vertically center with icon
|
||||
display.setCursor(textX, textY);
|
||||
display.print(pctStr);
|
||||
display.setTextSize(1); // restore default text size
|
||||
}
|
||||
|
||||
CayenneLPP sensors_lpp;
|
||||
|
||||
@@ -84,6 +84,10 @@ void GxEPDDisplay::startFrame(Color bkg) {
|
||||
void GxEPDDisplay::setTextSize(int sz) {
|
||||
display_crc.update<int>(sz);
|
||||
switch(sz) {
|
||||
case 0: // Tiny - built-in 6x8 pixel font
|
||||
display.setFont(NULL);
|
||||
display.setTextSize(1);
|
||||
break;
|
||||
case 1: // Small - use 9pt (was 9pt)
|
||||
display.setFont(&FreeSans9pt7b);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user