#include "dashboard.h" #include "font.h" //#include "monomaniacone12pt.h" #include "monomaniacone14pt.h" #include "monomaniacone20pt.h" #include "monomaniacone72pt.h" #include void run_dashboard_loop() { init(); uint32_t i = 0; while (1) { draw_battery(654, i * 100 / 4, 1321, 343); draw_speed(i * 1000 / 2); HAL_Delay(100); if (i == 200) { i = 0; } else { i++; } } } void init() { LCD_Init(); draw_init(); } void update_values() { // UART send 0201 04 4084 03 } void update_values_setup() { // UART send 0201 2F D58D 03 } void update_adc() { // UART send 0201 20 2462 03 } void LCD_DrawHollowRoundRect( uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint8_t radius_top, uint8_t radius_bottom, uint8_t border_width, uint16_t color, uint16_t fill_color, uint8_t do_fill); void draw_init() { LCD_Fill_Screen(COLOR_OFF, 1); LCD_Fill_Screen(COLOR_BG, 0); // GFX_DrawChar(40, 40, '!', &monomaniacone20pt, COLOR_PRIMARY, COLOR_BG); // GFX_DrawChar(60, 40, '2', &monomaniacone20pt, COLOR_PRIMARY, COLOR_BG); // GFX_DrawChar(80, 40, '3', &monomaniacone20pt, COLOR_SECONDARY, COLOR_BG); // GFX_DrawChar(100, 40, '4', &monomaniacone20pt, COLOR_SECONDARY, COLOR_BG); // GFX_DrawChar(120, 40, '5', &monomaniacone20pt, COLOR_ERROR, COLOR_BG); // GFX_DrawText(LCD_WIDTH / 2, 50, "Bonjour Monsieur !", &monomaniacone12pt, // COLOR_SECONDARY, COLOR_BG, 1, -2); // GFX_DrawText(LCD_WIDTH / 2, 70, "Bonjour Monsieur !", &monomaniacone14pt, // COLOR_SECONDARY, COLOR_BG, 1, -2); // GFX_DrawText(LCD_WIDTH / 2, 100, "Bonjour MONSieur !", &monomaniacone20pt, // COLOR_SUCCESS, COLOR_BG, 1, -2); // Draw a rectangle with different top/bottom radii // LCD_DrawHollowRoundRect(10, 10, 100, 50, 10, 0, 4, BLACK, COLOR_PRIMARY, 1); //// Draw a pill-shaped rectangle (same radius for all corners) // LCD_DrawHollowRoundRect(20, 70, 80, 30, 15, 15, 2, COLOR_SUCCESS, 0, 0); //// Draw a square with rounded corners // LCD_DrawHollowRoundRect(50, 100, 60, 60, 10, 10, 6, COLOR_ERROR, 0, 0); // LCD_DrawHollowRoundRect(130, 100, 60, 60, 10, 10, 0, 0, COLOR_ERROR, 1); // LCD_DrawHollowRoundRect(136, 106, 48, 48, 4, 4, 0, 0, COLOR_PRIMARY, 1); // // LCD_DrawHollowRoundRect(200, 100, 4, 20, 6, 6, 0, 0, COLOR_PRIMARY, 1); // LCD_DrawHollowRoundRect(200, 125, 6, 20, 6, 6, 0, 0, COLOR_PRIMARY, 1); // LCD_DrawHollowRoundRect(200, 150, 8, 20, 6, 6, 0, 0, COLOR_PRIMARY, 1); } // Displays the battery voltage and percent, with the trip and life distances // Input voltage from COMM_GET_VALUES, scale 10 // battery percent (level) from COMM_GET_VALUES_SETUP, scale 100 // trip distance from COMM_GET_VALUES_SETUP, scale 100 // life distance (odometer) from COMM_GET_VALUES_SETUP int16_t last_voltage = 0; int32_t last_percent = 0; int32_t last_trip_dist = 0; void draw_battery( int16_t voltage, int32_t percent, int32_t trip_dist, uint32_t life_dist) { if (voltage == last_voltage && percent/100 == last_percent/100 && trip_dist/10 == last_trip_dist/10) { return; } last_voltage = voltage; last_percent = percent; last_trip_dist = trip_dist; uint16_t bar_width = LCD_WIDTH - 12; uint16_t bar_height = 22; uint16_t filled_bar_width = (((float) (percent / 100)) / 100.0) * bar_width; if (filled_bar_width < 6) { filled_bar_width = 6;// Must be at least the size of the border radius. } uint16_t filled_bar_end_x = 4 + 2 + filled_bar_width; uint16_t text_y_12 = LCD_HEIGHT - 6 - (22 - 16) / 2; uint16_t text_y_14 = LCD_HEIGHT - 6 - (22 - 18) / 2; char voltage_text[8]; sprintf(voltage_text, "%.1fV", ((float) voltage) / 10.0); char percent_text[6]; sprintf(percent_text, "%lu%%", percent / 100); char distances_text[20]; sprintf(distances_text, "%.1fKm / %luKm", ((float) trip_dist) / 100.0, life_dist); // Drawing the bars LCD_DrawHollowRoundRect(4, LCD_HEIGHT - (bar_height + 4) - 4, bar_width + 4, bar_height + 4, 8, 8, 2, COLOR_FG, COLOR_BG, 1); if (filled_bar_width > 0) { LCD_DrawHollowRoundRect(4 + 2, LCD_HEIGHT - (bar_height + 2) - 4, filled_bar_width, bar_height, 6, 6, 0, 0, COLOR_SUCCESS, 1); } // Drawing the values uint16_t left_x = 10; uint16_t right_x = LCD_WIDTH - 10; if (percent > 20 * 100) { // Drawing the voltage to the left left_x = 10 + GFX_DrawText(left_x, text_y_14, voltage_text, &monomaniacone14pt, COLOR_BG, COLOR_SUCCESS, 0, -2); } else { // Drawing the voltage to the right right_x = -10 + GFX_DrawText(right_x, text_y_14, voltage_text, &monomaniacone14pt, COLOR_FG, COLOR_BG, 2, -2); } if (percent > 50 * 100) { // Drawing the distances on the left GFX_DrawText(left_x, text_y_14, distances_text, &monomaniacone14pt, COLOR_BG, COLOR_SUCCESS, 0, -3); } else { // Drawing the distances on the right GFX_DrawText(right_x, text_y_14, distances_text, &monomaniacone14pt, COLOR_FG, COLOR_BG, 2, -3); } if (percent > 80 * 100) { // Drawing the distances on the left GFX_DrawText(filled_bar_end_x - 4, text_y_14, percent_text, &monomaniacone14pt, COLOR_BG, COLOR_SUCCESS, 2, 0); } else { // Drawing the distances on the right GFX_DrawText(filled_bar_end_x + 4, text_y_14, percent_text, &monomaniacone14pt, COLOR_FG, COLOR_BG, 0, 0); } } // Displays the power bars at the top // Duty from COMM_GET_VALUES, scale 1000 void draw_power_bars(int16_t duty) { uint16_t offset = LCD_WIDTH / 2; uint16_t max_width = LCD_WIDTH / 2; uint16_t width = (duty / 100) * max_width / 10; } // Displays the huge speed counter with avg and max values. // Speed from COMM_GET_VALUES_SETUP, scale 1000 uint32_t last_speed = 0; uint32_t max_speed = 0; uint32_t last_avg_speed = 0; uint32_t avg_speed_tot = 0;// You need to ride super fast for a super long time for it to overflow ;) uint32_t avg_speed_count = 0; void draw_speed(int32_t speedd) { uint16_t erase_width = 90;// width to erase from center uint32_t speed = speedd < 0 ? -speedd/1000 : speedd/1000; if (speed >= 100) { speed = 99; } // update max speed uint8_t update_stats = 0; if (speed > max_speed) { max_speed = speed; update_stats = 1; } // update avg speed avg_speed_tot += speed; avg_speed_count += 1; uint32_t avg_speed = avg_speed_tot / avg_speed_count; if (last_avg_speed != avg_speed) { last_avg_speed = avg_speed; update_stats = 1; } // Draw if (last_speed != speed) { last_speed = speed; char speed_text[4]; sprintf(speed_text, "%lu", speed); LCD_Draw_Rectangle(LCD_WIDTH / 2 - erase_width, 22, 2 * erase_width, 110, COLOR_BG); GFX_DrawText(LCD_WIDTH / 2, 32 + 95, speed_text, &monomaniacone72pt, COLOR_FG, COLOR_BG, 1, -5); } if (update_stats) { char stats_text[20]; sprintf(stats_text, "avg: %lu max: %lu", avg_speed, max_speed); LCD_Draw_Rectangle(LCD_WIDTH / 2 - erase_width, 140, 2 * erase_width, 25, COLOR_BG); GFX_DrawText(LCD_WIDTH / 2, 159, stats_text, &monomaniacone14pt, COLOR_SECONDARY, COLOR_BG, 1, -3); } } // Displays Current, Duty, Watts // Current from COMM_GET_VALUES, scale 100 // Duty from COMM_GET_VALUES, scale 1000 // Input voltage from COMM_GET_VALUES, scale 10 void draw_power(int32_t amps, int16_t duty, int16_t voltage) { } // Displays the two ADS voltages // 2 voltages from COMM_GET_DECODED_ADC, scale 1 000 000 void draw_adc(int32_t adc1, int32_t adc2) { } // Displays the controller and motor temperatures // 2 temperatures from COMM_GET_VALUES_SETUP, scale 10 void draw_temps(int16_t temp_fet, int16_t temp_motor) { }