fix: separate logger from dashboard output

Logger writes to stderr so it doesn't corrupt the dashboard on stdout.
Dashboard tracks its own line count and uses cursor-up instead of home
so log messages appear cleanly before/after instead of interleaved.
This commit is contained in:
2026-06-14 23:12:41 +02:00
parent 1db5fdb374
commit f1e4e1b61d
3 changed files with 32 additions and 17 deletions
-7
View File
@@ -1,7 +0,0 @@
Implement all TODOs in the codebase.
write test first follow @AGENTS.md, commit when implemented one at a time and it passes.
git push when implemented.
You need to able to run telemetry on COM14 and start receiving data from TX module.
+1 -1
View File
@@ -2,5 +2,5 @@
#include <stdio.h> #include <stdio.h>
void cel_log_write(char const* msg) { void cel_log_write(char const* msg) {
printf("%s\n", msg); fprintf(stderr, "%s\n", msg);
} }
+31 -9
View File
@@ -57,7 +57,7 @@ static void sleep_ms(int ms) {
} }
/* --------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------- */
/* ANSI helpers */ /* ANSI helpers — all go to stdout so dashboard owns it */
/* --------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------- */
static void ansi_reset(void) { printf("\033[0m"); } static void ansi_reset(void) { printf("\033[0m"); }
@@ -67,7 +67,12 @@ static void ansi_yellow(void) { printf("\033[33m"); }
static void ansi_bold(void) { printf("\033[1m"); } static void ansi_bold(void) { printf("\033[1m"); }
static void ansi_dim(void) { printf("\033[2m"); } static void ansi_dim(void) { printf("\033[2m"); }
static void ansi_clear_line(void) { printf("\033[2K"); } static void ansi_clear_line(void) { printf("\033[2K"); }
static void ansi_home(void) { printf("\033[H"); }
static void ansi_cursor_up(int n) {
char buf[16];
snprintf(buf, sizeof(buf), "\033[%dA", n);
printf("%s", buf);
}
/* --------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------- */
/* Status helpers */ /* Status helpers */
@@ -223,17 +228,21 @@ static void rssi_color(double dbm) {
} }
/* --------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------- */
/* Dashboard render */ /* Dashboard render — tracks line count for in-place redraw */
/* --------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------- */
static void render_dashboard(dashboard_t const* d, static void render_dashboard(dashboard_t const* d,
char const* port, int baud, char const* port, int baud,
double elapsed) { double elapsed, int* lines) {
double now = (double)time(NULL); double now = (double)time(NULL);
status_t status = compute_status(now, d->link_t, d->fc_t); status_t status = compute_status(now, d->link_t, d->fc_t);
ansi_home(); /* Return to top of dashboard if already drawn */
ansi_clear_line(); if (*lines > 0) {
ansi_cursor_up(*lines);
}
int n = 0;
/* Title */ /* Title */
ansi_bold(); ansi_bold();
@@ -241,10 +250,12 @@ static void render_dashboard(dashboard_t const* d,
ansi_reset(); ansi_reset();
printf(" %s @ %d baud up %.0fs\n", printf(" %s @ %d baud up %.0fs\n",
port, baud, elapsed); port, baud, elapsed);
n++;
/* Status line */ /* Status */
print_status_label(status); print_status_label(status);
printf("\n"); printf("\n");
n++;
/* LINK */ /* LINK */
ansi_bold(); printf(" LINK "); ansi_reset(); ansi_bold(); printf(" LINK "); ansi_reset();
@@ -267,6 +278,7 @@ static void render_dashboard(dashboard_t const* d,
ansi_dim(); printf("waiting..."); ansi_reset(); ansi_dim(); printf("waiting..."); ansi_reset();
} }
printf("\n"); printf("\n");
n++;
/* BATT */ /* BATT */
ansi_bold(); printf(" BATT "); ansi_reset(); ansi_bold(); printf(" BATT "); ansi_reset();
@@ -280,6 +292,7 @@ static void render_dashboard(dashboard_t const* d,
ansi_dim(); printf("waiting..."); ansi_reset(); ansi_dim(); printf("waiting..."); ansi_reset();
} }
printf("\n"); printf("\n");
n++;
/* IMU */ /* IMU */
ansi_bold(); printf(" IMU "); ansi_reset(); ansi_bold(); printf(" IMU "); ansi_reset();
@@ -293,6 +306,7 @@ static void render_dashboard(dashboard_t const* d,
ansi_dim(); printf("waiting..."); ansi_reset(); ansi_dim(); printf("waiting..."); ansi_reset();
} }
printf("\n"); printf("\n");
n++;
/* MODE */ /* MODE */
ansi_bold(); printf(" MODE "); ansi_reset(); ansi_bold(); printf(" MODE "); ansi_reset();
@@ -303,13 +317,16 @@ static void render_dashboard(dashboard_t const* d,
ansi_dim(); printf("waiting..."); ansi_reset(); ansi_dim(); printf("waiting..."); ansi_reset();
} }
printf("\n"); printf("\n");
n++;
/* Footer */ /* Footer */
ansi_dim(); ansi_dim();
printf(" rx=%d ignored=%d", d->rx_frames, d->unknown); printf(" rx=%d ignored=%d", d->rx_frames, d->unknown);
ansi_reset(); ansi_reset();
printf("\n"); printf("\n");
n++;
*lines = n;
fflush(stdout); fflush(stdout);
} }
@@ -401,7 +418,7 @@ int main(int argc, char const* argv[]) {
/* Verify module responds to CRSF ping */ /* Verify module responds to CRSF ping */
if (verify_connection(port) != 0) { if (verify_connection(port) != 0) {
cel_log_warn("Continuing anyway - telemetry may not arrive"); cel_log_warn("Continuing anyway telemetry may not arrive");
} }
/* Create CRSF stream for incremental parsing */ /* Create CRSF stream for incremental parsing */
@@ -425,6 +442,7 @@ int main(int argc, char const* argv[]) {
uint8_t read_buf[256]; uint8_t read_buf[256];
time_t t_start = time(NULL); time_t t_start = time(NULL);
int rc_count = 0; int rc_count = 0;
int d_lines = 0; /* dashboard line count for cursor tracking */
while (s_running) { while (s_running) {
/* Read available data */ /* Read available data */
@@ -454,12 +472,16 @@ int main(int argc, char const* argv[]) {
/* Redraw dashboard every 100 ms */ /* Redraw dashboard every 100 ms */
if (rc_count % 5 == 0) { if (rc_count % 5 == 0) {
double elapsed = difftime(time(NULL), t_start); double elapsed = difftime(time(NULL), t_start);
render_dashboard(&dash, port_path, actual_baud, elapsed); render_dashboard(&dash, port_path, actual_baud, elapsed, &d_lines);
} }
sleep_ms(20); sleep_ms(20);
} }
/* Move cursor past dashboard before shutdown message */
if (d_lines > 0) {
printf("\n");
}
cel_log_info("Shutting down..."); cel_log_info("Shutting down...");
cel_crsf_stream_destroy(stream); cel_crsf_stream_destroy(stream);
cel_serial_close(port); cel_serial_close(port);