fix font; add separate counter for distance from power-on
This commit is contained in:
93
main.c
93
main.c
@@ -37,7 +37,8 @@ enum GUIScreen {
|
||||
|
||||
enum DisplayMode {
|
||||
DISPLAY_MODE_SPEED,
|
||||
DISPLAY_MODE_DISTANCE,
|
||||
DISPLAY_MODE_DISTANCE_FROM_POWER_ON,
|
||||
DISPLAY_MODE_TOTAL_DISTANCE,
|
||||
};
|
||||
|
||||
struct GUIState {
|
||||
@@ -51,6 +52,9 @@ struct GUIState {
|
||||
//...
|
||||
} settingsScreen;
|
||||
} screenState;
|
||||
uint8_t drawnTimeHours;
|
||||
uint8_t drawnTimeMinutes;
|
||||
uint16_t drawnTimeTextWidth;
|
||||
};
|
||||
|
||||
void on_gpio_interrupt(uint pin, uint32_t eventMask);
|
||||
@@ -112,7 +116,9 @@ uint16_t ticksPerWindow = 0;
|
||||
// critical_section_t intervalWheelTicksCritSec;
|
||||
repeating_timer_t speedMeasureTimer;
|
||||
|
||||
uint totalTicks = 0;
|
||||
// odometer counters
|
||||
uint totalWheelTicks = 0;
|
||||
uint wheelTicksFromPowerOn = 0;
|
||||
|
||||
DateTime currentDatetime;
|
||||
|
||||
@@ -289,7 +295,8 @@ int64_t hall_sensor_debounce_callback(alarm_id_t alarmId, void *userData) {
|
||||
absolute_time_t now = get_absolute_time();
|
||||
lastWheelTickTime = now;
|
||||
++intervalWheelTicks[currentInterval];
|
||||
++totalTicks;
|
||||
++totalWheelTicks;
|
||||
++wheelTicksFromPowerOn;
|
||||
|
||||
gpio_put(25, !gpio_get(25));
|
||||
hallSensorPrevState = hallSensorLastState;
|
||||
@@ -338,7 +345,9 @@ void on_button_short_press(uint button) {
|
||||
if (button == 3 && guiState.screen == MAIN_SCREEN) {
|
||||
uint oldDispMode = guiState.screenState.mainScreen.displayMode;
|
||||
if (oldDispMode == DISPLAY_MODE_SPEED)
|
||||
guiState.screenState.mainScreen.displayMode = DISPLAY_MODE_DISTANCE;
|
||||
guiState.screenState.mainScreen.displayMode = DISPLAY_MODE_DISTANCE_FROM_POWER_ON;
|
||||
else if (oldDispMode == DISPLAY_MODE_DISTANCE_FROM_POWER_ON)
|
||||
guiState.screenState.mainScreen.displayMode = DISPLAY_MODE_TOTAL_DISTANCE;
|
||||
else
|
||||
guiState.screenState.mainScreen.displayMode = DISPLAY_MODE_SPEED;
|
||||
guiState.screenState.mainScreen.displayModeChanged = true;
|
||||
@@ -457,10 +466,46 @@ void draw_short_term_distance(uint value) {
|
||||
#undef DIGITS_START_Y
|
||||
#undef DIGIT_WIDTH
|
||||
#undef DIGIT_SPACING
|
||||
#undef XSMALL_DIGITS_Y_OFFSET
|
||||
}
|
||||
|
||||
// long term distance is in "4.2" decimal fixed-point, in kilometers
|
||||
void draw_long_term_distance(uint value) {
|
||||
#define DIGITS_START_X 15
|
||||
#define DIGITS_START_Y 50
|
||||
#define XSMALL_DIGITS_Y_OFFSET 32
|
||||
#define XSMALL_DIGIT_WIDTH 30
|
||||
#define XSMALL_DIGIT_SPACING 4
|
||||
|
||||
if (value > 999999)
|
||||
value = 999999;
|
||||
|
||||
lcd_draw_small_digit(value / 100000, DIGITS_START_X, DIGITS_START_Y, 0xffff, 0x528a);
|
||||
lcd_draw_small_digit((value / 10000) % 10, DIGITS_START_X + SMALL_DIGIT_WIDTH + SMALL_DIGIT_SPACING, DIGITS_START_Y,
|
||||
0xffff, 0x528a);
|
||||
lcd_draw_small_digit((value / 1000) % 10, DIGITS_START_X + SMALL_DIGIT_WIDTH * 2 + SMALL_DIGIT_SPACING * 2,
|
||||
DIGITS_START_Y, 0xffff, 0x528a);
|
||||
lcd_draw_small_digit((value / 100) % 10, DIGITS_START_X + SMALL_DIGIT_WIDTH * 3 + SMALL_DIGIT_SPACING * 3,
|
||||
DIGITS_START_Y, 0xffff, 0x528a);
|
||||
lcd_draw_decimal_point(DIGITS_START_X + SMALL_DIGIT_WIDTH * 4 + SMALL_DIGIT_SPACING * 4 - 6, DIGITS_START_Y + 76,
|
||||
0xffff);
|
||||
lcd_draw_xsmall_digit((value / 10) % 10, DIGITS_START_X + SMALL_DIGIT_WIDTH * 4 + SMALL_DIGIT_SPACING * 4 + 10,
|
||||
DIGITS_START_Y + XSMALL_DIGITS_Y_OFFSET, 0xffff, 0x528a);
|
||||
lcd_draw_xsmall_digit(value % 10,
|
||||
DIGITS_START_X + SMALL_DIGIT_WIDTH * 4 + SMALL_DIGIT_SPACING * 4 + XSMALL_DIGIT_WIDTH +
|
||||
XSMALL_DIGIT_SPACING + 10,
|
||||
DIGITS_START_Y + XSMALL_DIGITS_Y_OFFSET, 0xffff, 0x528a);
|
||||
|
||||
#undef DIGITS_START_X
|
||||
#undef DIGITS_START_Y
|
||||
#undef XSMALL_DIGITS_Y_OFFSET
|
||||
#undef XSMALL_DIGIT_WIDTH
|
||||
#undef XSMALL_DIGIT_SPACING
|
||||
}
|
||||
|
||||
void update_lcd() {
|
||||
if (guiState.screen == MAIN_SCREEN) {
|
||||
bool forceRedrawClock = guiState.screenState.mainScreen.displayModeChanged;
|
||||
if (guiState.screenState.mainScreen.displayModeChanged) {
|
||||
// lcd_fill_rectangle(49, 27, 213, 113, 0x0000);
|
||||
st7789_fill(0x0000);
|
||||
@@ -470,29 +515,43 @@ void update_lcd() {
|
||||
if (guiState.screenState.mainScreen.displayMode == DISPLAY_MODE_SPEED) {
|
||||
uint convertedSpeed = ticksPerWindow * cmphPerTpw / 10000;
|
||||
draw_speed(convertedSpeed);
|
||||
lcd_write_string("Скорость", 20, 0, 0xffff, 0x0000);
|
||||
lcd_write_string("Скорость", 10, 0, 0xffff, 0x0000);
|
||||
lcd_write_string("км/ч", 241, 126, 0xffff, 0x0000);
|
||||
} else if (guiState.screenState.mainScreen.displayMode == DISPLAY_MODE_DISTANCE) {
|
||||
uint convertedDistance = totalTicks * cmPerTick / 100;
|
||||
} else if (guiState.screenState.mainScreen.displayMode == DISPLAY_MODE_DISTANCE_FROM_POWER_ON) {
|
||||
uint convertedDistance = wheelTicksFromPowerOn * cmPerTick / 100;
|
||||
draw_short_term_distance(convertedDistance);
|
||||
lcd_write_string("Расстояние", 20, 0, 0xffff, 0x0000);
|
||||
lcd_write_string("Текущий путь", 10, 0, 0xffff, 0x0000);
|
||||
lcd_write_string("км", 280, 37, 0xffff, 0x0000);
|
||||
} else if (guiState.screenState.mainScreen.displayMode == DISPLAY_MODE_TOTAL_DISTANCE) {
|
||||
uint convertedDistance = totalWheelTicks * cmPerTick / 1000;
|
||||
draw_long_term_distance(convertedDistance);
|
||||
lcd_write_string("Общий путь", 10, 0, 0xffff, 0x0000);
|
||||
lcd_write_string("км", 280, 37, 0xffff, 0x0000);
|
||||
}
|
||||
|
||||
char timeDisplay[6];
|
||||
memset(timeDisplay, ' ', sizeof(timeDisplay));
|
||||
timeDisplay[5] = 0;
|
||||
sprintf(timeDisplay, "%i:%02i", currentDatetime.hour, currentDatetime.minute);
|
||||
lcd_write_string(timeDisplay, 320 - 20 - lcd_string_width(timeDisplay), 0, 0xffff, 0x0000);
|
||||
lcd_fill_rectangle(320 - 160, 0, 140 - lcd_string_width(timeDisplay), 24, 0x0000);
|
||||
if (forceRedrawClock || guiState.drawnTimeHours != currentDatetime.hour ||
|
||||
guiState.drawnTimeMinutes != currentDatetime.minute) {
|
||||
lcd_fill_rectangle(305 - guiState.drawnTimeTextWidth, 0, guiState.drawnTimeTextWidth, 24, 0x0000);
|
||||
guiState.drawnTimeHours = currentDatetime.hour;
|
||||
guiState.drawnTimeMinutes = currentDatetime.minute;
|
||||
char timeDisplay[6];
|
||||
memset(timeDisplay, ' ', sizeof(timeDisplay));
|
||||
timeDisplay[5] = 0;
|
||||
sprintf(timeDisplay, "%i:%02i", currentDatetime.hour, currentDatetime.minute);
|
||||
lcd_write_string(timeDisplay, 305 - lcd_string_width(timeDisplay), 0, 0xffff, 0x0000);
|
||||
guiState.drawnTimeTextWidth = lcd_string_width(timeDisplay);
|
||||
}
|
||||
} else if (guiState.screen == SETTINGS_SCREEN) {
|
||||
}
|
||||
}
|
||||
|
||||
void gui_init(struct GUIState *state) {
|
||||
state->screen = 0;
|
||||
state->screenState.mainScreen.displayMode = DISPLAY_MODE_DISTANCE;
|
||||
state->screenState.mainScreen.displayMode = DISPLAY_MODE_DISTANCE_FROM_POWER_ON;
|
||||
state->screenState.mainScreen.displayModeChanged = true;
|
||||
state->drawnTimeTextWidth = 0;
|
||||
state->drawnTimeHours = 24;
|
||||
state->drawnTimeMinutes = 60;
|
||||
}
|
||||
|
||||
void init_button_states() {
|
||||
@@ -516,7 +575,7 @@ void save_to_rtc() {
|
||||
static uint savedDistance;
|
||||
uint8_t buffer[31];
|
||||
memset(buffer, 0, 31);
|
||||
uint newDistance = totalTicks * cmPerTick / 10;
|
||||
uint newDistance = totalWheelTicks * cmPerTick / 10;
|
||||
if (savedBefore && newDistance == savedDistance) {
|
||||
printf("skipped saving\n");
|
||||
return;
|
||||
@@ -588,7 +647,7 @@ bool load_from_rtc() {
|
||||
}
|
||||
|
||||
uint savedDistance = *(uint *)(buffer + 0);
|
||||
totalTicks = savedDistance * 10 / cmPerTick;
|
||||
totalWheelTicks = savedDistance * 10 / cmPerTick;
|
||||
#ifdef LOGGING
|
||||
printf("successfully loaded data from RTC memory\n");
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user