fix: short 50ms LED blink, RX brightness scaled by SNR
- LED blink is now 50ms (was waiting for 1s timer tick) - RX blink: green brightness scaled by SNR (-20dB→dim, +15dB→bright) - TX blink: fixed red brightness - Blink is self-contained (on→50ms delay→off) instead of timer-based - V3 white LED: any non-zero = on, so SNR scaling is invisible but V4 WS2812 will show green intensity varying with signal quality
This commit is contained in:
1 file changed
+17
-6
+17
-6
@@ -76,6 +76,14 @@ impl DisplayState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Map SNR (dB) to LED brightness (4..64). Stronger signal = brighter.
|
||||||
|
fn snr_brightness(snr: Option<i16>) -> u8 {
|
||||||
|
let snr = snr.unwrap_or(-10);
|
||||||
|
let clamped = snr.clamp(-20, 15) as i32;
|
||||||
|
// -20 → 4, +15 → 64
|
||||||
|
((clamped + 20) * 60 / 35 + 4) as u8
|
||||||
|
}
|
||||||
|
|
||||||
/// Render the appropriate screen for the current state into the display buffer.
|
/// Render the appropriate screen for the current state into the display buffer.
|
||||||
fn render_current(
|
fn render_current(
|
||||||
display: &mut impl DrawTarget<Color = BinaryColor>,
|
display: &mut impl DrawTarget<Color = BinaryColor>,
|
||||||
@@ -160,18 +168,24 @@ pub async fn display_task(
|
|||||||
if tx_packet {
|
if tx_packet {
|
||||||
state.record_tx();
|
state.record_tx();
|
||||||
}
|
}
|
||||||
|
let last_snr = radio_status.last_snr;
|
||||||
state.last_status = radio_status;
|
state.last_status = radio_status;
|
||||||
|
|
||||||
if state.display_on {
|
if state.display_on {
|
||||||
render_current(&mut display, &state, &board_info);
|
render_current(&mut display, &state, &board_info);
|
||||||
let _ = display.flush().await;
|
let _ = display.flush().await;
|
||||||
|
|
||||||
// Blink LED: green on RX, red on TX
|
// Brief LED blink: red on TX, green scaled by SNR on RX
|
||||||
if let Some(ref mut led) = led {
|
if let Some(ref mut led) = led {
|
||||||
if tx_packet {
|
if tx_packet {
|
||||||
led.set_rgb(32, 0, 0).await;
|
led.set_rgb(32, 0, 0).await;
|
||||||
|
Timer::after_millis(50).await;
|
||||||
|
led.set_rgb(0, 0, 0).await;
|
||||||
} else if rx_packet {
|
} else if rx_packet {
|
||||||
led.set_rgb(0, 32, 0).await;
|
let b = snr_brightness(last_snr);
|
||||||
|
led.set_rgb(0, b, 0).await;
|
||||||
|
Timer::after_millis(50).await;
|
||||||
|
led.set_rgb(0, 0, 0).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -205,11 +219,8 @@ pub async fn display_task(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Either3::Third(()) => {
|
Either3::Third(()) => {
|
||||||
// Timer tick: advance sparkline slot, turn off LED blink
|
// Timer tick: advance sparkline slot
|
||||||
state.advance_slot();
|
state.advance_slot();
|
||||||
if let Some(ref mut led) = led {
|
|
||||||
led.set_rgb(0, 0, 0).await;
|
|
||||||
}
|
|
||||||
if state.display_on && state.is_active() {
|
if state.display_on && state.is_active() {
|
||||||
render_current(&mut display, &state, &board_info);
|
render_current(&mut display, &state, &board_info);
|
||||||
let _ = display.flush().await;
|
let _ = display.flush().await;
|
||||||
|
|||||||
Reference in new issue
Block a user