Compare commits

...

2 Commits

Author SHA1 Message Date
Clément Grennerat
2c419094ae Setup variable refresh time for different UI components 2025-09-16 23:52:53 +02:00
Clément Grennerat
93a3dd8afd Fixing last UART interface bugs 2025-09-16 23:40:00 +02:00
2 changed files with 102 additions and 33 deletions

View File

@ -3,7 +3,7 @@
#include "LCD_driver.h" #include "LCD_driver.h"
#define COLOR_PRIMARY 0xfdaa #define COLOR_PRIMARY 0xfd01
#define COLOR_SECONDARY 0x667f #define COLOR_SECONDARY 0x667f
#define COLOR_SUCCESS 0x3766 #define COLOR_SUCCESS 0x3766
#define COLOR_ERROR 0xf226 #define COLOR_ERROR 0xf226
@ -11,11 +11,16 @@
#define COLOR_BG 0x0000 #define COLOR_BG 0x0000
#define COLOR_OFF 0x0000 #define COLOR_OFF 0x0000
#define FAULT_CODE_MAX 27
void run_dashboard_loop(); void run_dashboard_loop();
void init(); void init();
void update_values_setup(); // refresh_slow = 0 if it should not refresh the low-refresh rate information.
// refresh_mid = 0 if it should not refresh the mid-refresh rate information.
void update_values(uint8_t refresh_slow, uint8_t refresh_mid);
void update_adc(); void update_adc();
@ -36,7 +41,7 @@ void draw_power_bars(int16_t duty);
// Displays the huge speed counter with avg and max values. // Displays the huge speed counter with avg and max values.
// Speed from COMM_GET_VALUES_SETUP, scale 1000 // Speed from COMM_GET_VALUES_SETUP, scale 1000
void draw_speed(int32_t speed); void draw_speed(int32_t speed, uint8_t fault_code);
// Displays Current, Duty, Watts // Displays Current, Duty, Watts
// Current from COMM_GET_VALUES, scale 100 // Current from COMM_GET_VALUES, scale 100

View File

@ -8,22 +8,18 @@
#include "usart.h" #include "usart.h"
#include "crc.h" #include "crc.h"
#include "float16.h" #include "float16.h"
#include "math.h"
#include <stdio.h> #include <stdio.h>
uint8_t initialized = 0; const char *fault_code_strings[] = { "none", "over voltage", "under voltage",
void run_dashboard_loop() { "driver fault", "abs over current", "over tmp FET", "over tmp motor",
"gate drv over v", "gate drv under v", "MCU under voltage",
LCD_Init(); "boot watchdog rst", "encoder SPI error", "encoder scos min",
LCD_Fill_Screen(COLOR_OFF, 1); "encoder scos max", "flash corruption", "high ofst cur s1",
LCD_Fill_Screen(COLOR_BG, 0); "high ofst cur s2", "high ofst cur s3", "unbalanced curs", "brake fault",
HAL_Delay(1000); "resolver LOT", "resolver DOS", "resolver LOS", "app flash corupt",
while (1) { "mot flash corupt", "encoder no magnet", "encoder str magnet",
update_values_setup(); "phase filter fault" };
update_adc();
HAL_Delay(100);
}
}
void run_dashboard_loop_test() { void run_dashboard_loop_test() {
LCD_Init(); LCD_Init();
@ -34,12 +30,13 @@ void run_dashboard_loop_test() {
while (1) { while (1) {
draw_battery(654, i * 100 / 4, 1321, 343); draw_battery(654, i * 100 / 4, 1321, 343);
draw_speed(i * 1000 / 4); draw_speed(i * 1000 / 4, i % 30);
int16_t duty = 1000 - (int16_t) i * 1000 / 200; int16_t duty = 1000 - (int16_t) i * 1000 / 200;
draw_power_bars(duty); draw_power_bars(duty);
draw_power(100 * i / 20 * (duty < 0 ? -1 : 1), duty, 60 * 10); draw_power(100 * i / 20 * (duty < 0 ? -1 : 1), duty, 60 * 10);
draw_adc(i % 34, (400 - i + 16) % 34, i % 34 >= 2.5, (400 - i + 16) % 34 >= 2.5); draw_adc(i % 34, (400 - i + 16) % 34, i % 34 >= 2.5,
(400 - i + 16) % 34 >= 2.5);
draw_temps((4 * i) % 900, ((10 * i) + 450) % 900); draw_temps((4 * i) % 900, ((10 * i) + 450) % 900);
@ -53,7 +50,33 @@ void run_dashboard_loop_test() {
} }
void update_values_setup() { uint8_t initialized = 0;
void run_dashboard_loop() {
LCD_Init();
LCD_Fill_Screen(COLOR_OFF, 1);
LCD_Fill_Screen(COLOR_BG, 0);
HAL_Delay(1000);
uint8_t i = 0;
while (1) {
uint8_t refresh_slow = (i % 10) == 0;
uint8_t refresh_mid = (i % 3) == 0;
update_values(refresh_slow, refresh_mid);
update_adc();
HAL_Delay(50);
i++;
if (i == 120) {
i = 0;
}
}
}
// refresh_slow = 0 if it should not refresh the low-refresh rate information.
// refresh_mid = 0 if it should not refresh the mid-refresh rate information.
void update_values(uint8_t refresh_slow, uint8_t refresh_mid) {
// UART send 0201 2F D58D 03 // UART send 0201 2F D58D 03
uint8_t packet[1]; uint8_t packet[1];
packet[0] = 0x2F;// COMM_GET_VALUES_SETUP packet[0] = 0x2F;// COMM_GET_VALUES_SETUP
@ -91,7 +114,7 @@ void update_values_setup() {
uint32_t distance_life = USART1_ReceiveUInt32(); uint32_t distance_life = USART1_ReceiveUInt32();
USART1_ReceiveUInt32();// System time USART1_ReceiveUInt32();// System time
USART1_ReceiveUInt16(); // CRC USART1_ReceiveUInt16();// CRC
// End byte // End byte
if (USART1_ReceiveByte() != 0x03) { if (USART1_ReceiveByte() != 0x03) {
return;// Invalid packet return;// Invalid packet
@ -103,13 +126,24 @@ void update_values_setup() {
if (!initialized) { if (!initialized) {
draw_init(); draw_init();
initialized = 1; initialized = 1;
refresh_slow = 1;
refresh_mid = 1;
} }
draw_battery(input_voltage_filtered, battery_level, distance_abs,
distance_life); //speed = (int32_t) (((float) speed) / 1.609344);
//float wheel_diameter = 0.246; // in meter
//speed = ((float) rpm) * 3.14159265359 * wheel_diameter * 60 / 1000;
draw_power_bars(duty_cycle); draw_power_bars(duty_cycle);
draw_speed(speed * 10); if (refresh_mid) {
draw_power(current_in_tot, duty_cycle, input_voltage_filtered); draw_speed((int32_t) (((float) speed) * 3.6), fault_code);
draw_temps(temp_fet, temp_motor); draw_power(current_in_tot, duty_cycle, input_voltage_filtered);
}
if (refresh_slow) {
draw_battery(input_voltage_filtered, battery_level, distance_abs,
distance_life);
draw_temps(temp_fet, temp_motor);
}
} }
void update_adc() { void update_adc() {
// Replies to 0x24 0x65 for command id: 0, 1, 18, 19, 1B, 1D, C9, CA // Replies to 0x24 0x65 for command id: 0, 1, 18, 19, 1B, 1D, C9, CA
@ -179,13 +213,13 @@ void update_adc() {
uint8_t fs_state = beep_fs_state & 0b11; uint8_t fs_state = beep_fs_state & 0b11;
uint8_t adc1_en = 0; uint8_t adc1_en = 0;
uint8_t adc2_en = 0; uint8_t adc2_en = 0;
if(fs_state == 1) { if (fs_state == 1) {
if (adc1 > adc2){ if (adc1 > adc2) {
adc1_en = 1; adc1_en = 1;
} else { } else {
adc2_en = 2; adc2_en = 2;
} }
}else if(fs_state == 2) { } else if (fs_state == 2) {
adc1_en = 1; adc1_en = 1;
adc2_en = 1; adc2_en = 1;
} }
@ -381,7 +415,8 @@ uint32_t max_speed = 0;
uint32_t last_avg_speed = 30; uint32_t last_avg_speed = 30;
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_tot = 0;// You need to ride super fast for a super long time for it to overflow ;)
uint32_t avg_speed_count = 0; uint32_t avg_speed_count = 0;
void draw_speed(int32_t speedd) { uint8_t last_fault_code = 0;
void draw_speed(int32_t speedd, uint8_t fault_code) {
uint32_t speed = speedd < 0 ? -speedd / 1000 : speedd / 1000; uint32_t speed = speedd < 0 ? -speedd / 1000 : speedd / 1000;
if (speed >= 100) { if (speed >= 100) {
@ -415,9 +450,31 @@ void draw_speed(int32_t speedd) {
COLOR_FG, COLOR_BG, 1, -5); COLOR_FG, COLOR_BG, 1, -5);
} }
uint16_t erase_width = 90;// width to erase from center
if (last_fault_code != fault_code) {
last_fault_code = fault_code;
if (fault_code == 0) {
update_stats = 1;
erase_width = 100;
} else {
update_stats = 0;
char fault_text[50];// Increased size to accommodate longer strings
if (fault_code <= FAULT_CODE_MAX) {
sprintf(fault_text, "%u %s", fault_code,
fault_code_strings[fault_code]);
} else {
sprintf(fault_text, "%u unknown fault", fault_code);
}
LCD_Draw_Rectangle(LCD_WIDTH / 2 - erase_width, 140, 2 * erase_width, 25,
COLOR_BG);
GFX_DrawText(LCD_WIDTH / 2, 159, fault_text, &monomaniacone14pt,
COLOR_ERROR, COLOR_BG, 1, -3);
}
}
if (update_stats) { if (update_stats) {
char stats_text[20]; char stats_text[20];
uint16_t erase_width = 90;// width to erase from center
sprintf(stats_text, "avg: %lu max: %lu", avg_speed, max_speed); sprintf(stats_text, "avg: %lu max: %lu", avg_speed, max_speed);
LCD_Draw_Rectangle(LCD_WIDTH / 2 - erase_width, 140, 2 * erase_width, 25, LCD_Draw_Rectangle(LCD_WIDTH / 2 - erase_width, 140, 2 * erase_width, 25,
COLOR_BG); COLOR_BG);
@ -434,10 +491,13 @@ int32_t last_power = 1000;
// Duty from COMM_GET_VALUES, scale 1000 // Duty from COMM_GET_VALUES, scale 1000
// Input voltage from COMM_GET_VALUES, scale 10 // Input voltage from COMM_GET_VALUES, scale 10
void draw_power(int32_t current_i, int16_t duty_i, int16_t voltage_i) { void draw_power(int32_t current_i, int16_t duty_i, int16_t voltage_i) {
if (duty_i < 0 && current_i > 0) {
current_i = -current_i;
}
int16_t current = current_i / 100; int16_t current = current_i / 100;
uint16_t duty = duty_i < 0 ? -duty_i / 10 : duty_i / 10; uint16_t duty = duty_i < 0 ? -duty_i / 10 : duty_i / 10;
int32_t power = ((int32_t) voltage_i) * ((int32_t) current_i) / 10000 * 10; int32_t power = ((int32_t) voltage_i) * ((int32_t) current_i) / 10000 * 10;
if (power >= 1000) { if (power >= 1000) {
power = power / 100 * 100; power = power / 100 * 100;
} else if (power <= -1000) { } else if (power <= -1000) {
@ -493,7 +553,11 @@ uint8_t last_adc1_en = 0;
uint8_t last_adc2_en = 0; uint8_t last_adc2_en = 0;
// Displays the two ADC voltages // Displays the two ADC voltages
//2 voltages from reFloat - COMM_CUSTOM_APP_DATA, scale 10, adcx_en are booleans. //2 voltages from reFloat - COMM_CUSTOM_APP_DATA, scale 10, adcx_en are booleans.
void draw_adc(int32_t adc1_scaled, int32_t adc2_scaled, uint8_t adc1_en, uint8_t adc2_en) { void draw_adc(
int32_t adc1_scaled,
int32_t adc2_scaled,
uint8_t adc1_en,
uint8_t adc2_en) {
uint16_t adc1 = adc1_scaled < 0 ? -adc1_scaled : adc1_scaled; uint16_t adc1 = adc1_scaled < 0 ? -adc1_scaled : adc1_scaled;
uint16_t adc2 = adc2_scaled < 0 ? -adc2_scaled : adc2_scaled; uint16_t adc2 = adc2_scaled < 0 ? -adc2_scaled : adc2_scaled;
if (adc1 > 33) { if (adc1 > 33) {