ui changes

speedometer: digit color now changes gradually with speed
odometer: the last digit is now aligned to bottom
This commit is contained in:
2026-09-12 21:02:29 +03:00
parent f2007b7e9b
commit 2073575f54

59
main.c
View File

@@ -381,6 +381,14 @@ bool speed_measure_timer_callback(repeating_timer_t *rt) {
return true;
}
uint16_t color565_lerp(uint16_t a, uint16_t b, uint alphaPercent) {
uint alphaComplement = 100 - alphaPercent;
uint16_t red = ((b >> 11) * alphaPercent + (a >> 11) * alphaComplement) / 100;
uint16_t green = (((b >> 5) & 0x3F) * alphaPercent + ((a >> 5) & 0x3F) * alphaComplement) / 100;
uint16_t blue = ((b & 0x1F) * alphaPercent + (a & 0x1F) * alphaComplement) / 100;
return blue | (green << 5) | (red << 11);
}
// speed is in "2.1" decimal fixed-point, in km/h
void draw_speed(uint value) {
#define DIGITS_START_X 20
@@ -391,24 +399,23 @@ void draw_speed(uint value) {
if (value > 999)
value = 999;
uint16_t color;
if (value >= 300)
color = 0xfd04;
else if (value >= 200)
color = 0xfe84;
else if (value >= 150)
color = 0xdfe4;
else if (value >= 100)
color = 0x6fe4;
else if (value >= 50)
color = 0x27fb;
else
color = 0x04ff;
const uint16_t speedToColorX[] = {0, 50, 100, 150, 200, 300};
const uint16_t speedToColorY[] = {0x04ff, 0x27fb, 0x6fe4, 0xdfe4, 0xfe84, 0xfd04};
const size_t speedToColorPointCount = 6;
lcd_draw_digit(value / 100, DIGITS_START_X, DIGITS_START_Y, color, 0x0000);
lcd_draw_digit((value / 10) % 10, DIGITS_START_X + DIGIT_WIDTH + DIGIT_SPACING, DIGITS_START_Y, color, 0x0000);
uint16_t color = speedToColorY[speedToColorPointCount - 1];
for (int i = 1; i < speedToColorPointCount; ++i) {
if (value <= speedToColorX[i]) {
color = color565_lerp(speedToColorY[i - 1], speedToColorY[i],
(value - speedToColorX[i - 1]) * 100 / (speedToColorX[i] - speedToColorX[i - 1]));
break;
}
}
lcd_draw_digit(value / 100, DIGITS_START_X, DIGITS_START_Y, color, 0x528a);
lcd_draw_digit((value / 10) % 10, DIGITS_START_X + DIGIT_WIDTH + DIGIT_SPACING, DIGITS_START_Y, color, 0x528a);
lcd_draw_decimal_point(DIGITS_START_X + DIGIT_WIDTH * 2 + DIGIT_SPACING, DIGITS_START_Y + 101, color);
lcd_draw_digit(value % 10, DIGITS_START_X + DIGIT_WIDTH * 2 + DIGIT_SPACING * 2 + 5, DIGITS_START_Y, color, 0x0000);
lcd_draw_digit(value % 10, DIGITS_START_X + DIGIT_WIDTH * 2 + DIGIT_SPACING * 2 + 5, DIGITS_START_Y, color, 0x528a);
#undef DIGITS_START_X
#undef DIGITS_START_Y
@@ -417,11 +424,11 @@ void draw_speed(uint value) {
}
// distance is in "2.3" decimal fixed-point, in kilometers
void draw_distance(uint value) {
void draw_short_term_distance(uint value) {
#define DIGITS_START_X 20
#define DIGITS_START_Y 37
#define SMALL_DIGITS_Y_OFFSET 28
#define XSMALL_DIGITS_Y_OFFSET 28
#define XSMALL_DIGITS_Y_OFFSET 60
#define DIGIT_WIDTH 64
#define SMALL_DIGIT_WIDTH 48
#define XSMALL_DIGIT_WIDTH 30
@@ -432,19 +439,19 @@ void draw_distance(uint value) {
if (value > 99999)
value = 99999;
lcd_draw_digit(value / 10000, DIGITS_START_X, DIGITS_START_Y, 0xffff, 0x0000);
lcd_draw_digit((value / 1000) % 10, DIGITS_START_X + DIGIT_WIDTH + DIGIT_SPACING, DIGITS_START_Y, 0xffff, 0x0000);
lcd_draw_digit(value / 10000, DIGITS_START_X, DIGITS_START_Y, 0xffff, 0x528a);
lcd_draw_digit((value / 1000) % 10, DIGITS_START_X + DIGIT_WIDTH + DIGIT_SPACING, DIGITS_START_Y, 0xffff, 0x528a);
lcd_draw_decimal_point(DIGITS_START_X + DIGIT_WIDTH * 2 + DIGIT_SPACING, DIGITS_START_Y + 101, 0xffff);
lcd_draw_small_digit((value / 100) % 10, DIGITS_START_X + DIGIT_WIDTH * 2 + DIGIT_SPACING * 2 + 10,
DIGITS_START_Y + SMALL_DIGITS_Y_OFFSET, 0xffff, 0x0000);
DIGITS_START_Y + SMALL_DIGITS_Y_OFFSET, 0xffff, 0x528a);
lcd_draw_small_digit((value / 10) % 10,
DIGITS_START_X + DIGIT_WIDTH * 2 + DIGIT_SPACING * 2 + SMALL_DIGIT_WIDTH + SMALL_DIGIT_SPACING +
10,
DIGITS_START_Y + SMALL_DIGITS_Y_OFFSET, 0xffff, 0x0000);
DIGITS_START_Y + SMALL_DIGITS_Y_OFFSET, 0xffff, 0x528a);
lcd_draw_xsmall_digit(value % 10,
DIGITS_START_X + DIGIT_WIDTH * 2 + DIGIT_SPACING * 2 + SMALL_DIGIT_WIDTH * 2 +
SMALL_DIGIT_SPACING + XSMALL_DIGIT_SPACING + 10,
DIGITS_START_Y + XSMALL_DIGITS_Y_OFFSET, 0xffff, 0x0000);
SMALL_DIGIT_SPACING * 2 + 10,
DIGITS_START_Y + XSMALL_DIGITS_Y_OFFSET, 0xffff, 0x528a);
#undef DIGITS_START_X
#undef DIGITS_START_Y
@@ -467,9 +474,9 @@ void update_lcd() {
lcd_write_string("км/ч", 241, 126, 0xffff, 0x0000);
} else if (guiState.screenState.mainScreen.displayMode == DISPLAY_MODE_DISTANCE) {
uint convertedDistance = totalTicks * cmPerTick / 100;
draw_distance(convertedDistance);
draw_short_term_distance(convertedDistance);
lcd_write_string("Расстояние", 20, 0, 0xffff, 0x0000);
lcd_write_string("км", 280, 126, 0xffff, 0x0000);
lcd_write_string("км", 280, 37, 0xffff, 0x0000);
}
char timeDisplay[6];