From 42110ae86f1d5c10fa956e54a72c38b9f39c1f9d Mon Sep 17 00:00:00 2001 From: Ran Bao Date: Wed, 13 Dec 2023 22:43:05 +1300 Subject: [PATCH] Add configurable DP --- src/charge_mode.cpp | 50 ++++++++++++++++------ src/charge_mode.h | 7 ++- src/cleanup_mode.cpp | 15 +++++-- src/common.c | 20 +++++++++ src/common.h | 6 +++ src/html/dashboard.html | 9 ++++ src/mui_menu.c | 78 ++++++++++++++++++++++++++-------- tests/config_html_rest_test.py | 2 +- 8 files changed, 152 insertions(+), 35 deletions(-) diff --git a/src/charge_mode.cpp b/src/charge_mode.cpp index 4ecc842..5a4a8cb 100644 --- a/src/charge_mode.cpp +++ b/src/charge_mode.cpp @@ -24,7 +24,6 @@ uint8_t charge_weight_digits[] = {0, 0, 0, 0, 0}; -// PID related charge_mode_config_t charge_mode_config; // Scale related @@ -39,6 +38,8 @@ const eeprom_charge_mode_data_t default_charge_mode_data = { .set_point_sd_margin = 0.02, .set_point_mean_margin = 0.02, + .decimal_places = DP_2, + // LED related .neopixel_normal_charge_colour = urgb_u32(0, 0xFF, 0), // green .neopixel_under_charge_colour = urgb_u32(0xFF, 0xFF, 0), // yellow @@ -63,7 +64,7 @@ typedef enum { void scale_measurement_render_task(void *p) { - char current_weight_string[5]; + char current_weight_string[WEIGHT_STRING_LEN]; u8g2_t * display_handler = get_display_handler(); @@ -83,8 +84,8 @@ void scale_measurement_render_task(void *p) { // current weight (only show values > -10) memset(current_weight_string, 0x0, sizeof(current_weight_string)); float scale_measurement = scale_get_current_measurement(); - if (scale_measurement > -10) { - sprintf(current_weight_string, "%0.02f", scale_measurement); + if (scale_measurement > -1.0) { + float_to_string(current_weight_string, scale_measurement, charge_mode_config.eeprom_charge_mode_data.decimal_places); } else { strcpy(current_weight_string, "---"); @@ -165,9 +166,12 @@ ChargeModeState_t charge_mode_wait_for_complete(ChargeModeState_t prev_state) { ); // Update current status + char target_weight_string[WEIGHT_STRING_LEN]; + float_to_string(target_weight_string, charge_mode_config.target_charge_weight, charge_mode_config.eeprom_charge_mode_data.decimal_places); + snprintf(title_string, sizeof(title_string), - "Target: %.02f", - charge_mode_config.target_charge_weight); + "Target: %s", + target_weight_string); // Read trickling parameter from the current profile profile_t * current_profile = profile_get_selected(); @@ -385,11 +389,26 @@ uint8_t charge_mode_menu() { neopixel_led_set_colour(NEOPIXEL_LED_DEFAULT_COLOUR, NEOPIXEL_LED_DEFAULT_COLOUR, NEOPIXEL_LED_DEFAULT_COLOUR, true); // Create target weight - charge_mode_config.target_charge_weight = charge_weight_digits[4] * 100 + \ - charge_weight_digits[3] * 10 + \ - charge_weight_digits[2] + \ - charge_weight_digits[1] * 0.1 + \ - charge_weight_digits[0] * 0.01; + switch (charge_mode_config.eeprom_charge_mode_data.decimal_places) { + case DP_2: + charge_mode_config.target_charge_weight = charge_weight_digits[4] * 100 + \ + charge_weight_digits[3] * 10 + \ + charge_weight_digits[2] * 1 + \ + charge_weight_digits[1] * 0.1 + \ + charge_weight_digits[0] * 0.01; + break; + case DP_3: + charge_mode_config.target_charge_weight = charge_weight_digits[4] * 10 + \ + charge_weight_digits[3] * 1 + \ + charge_weight_digits[2] * 0.1 + \ + charge_weight_digits[1] * 0.01 + \ + charge_weight_digits[0] * 0.001; + break; + default: + charge_mode_config.target_charge_weight = 0; + break; + } + printf("Target Charge Weight: %f\n", charge_mode_config.target_charge_weight); // If the display task is never created then we shall create one, otherwise we shall resume the task @@ -502,6 +521,7 @@ bool http_rest_charge_mode_config(struct fs_file *file, int num_params, char *pa // c6 (float): fine_stop_threshold // c7 (float): set_point_sd_margin // c8 (float): set_point_mean_margin + // c9 (int): decimal point enum // ee (bool): save to eeprom @@ -522,6 +542,9 @@ bool http_rest_charge_mode_config(struct fs_file *file, int num_params, char *pa else if (strcmp(params[idx], "c8") == 0) { charge_mode_config.eeprom_charge_mode_data.set_point_mean_margin = strtof(values[idx], NULL); } + else if (strcmp(params[idx], "c9") == 0) { + charge_mode_config.eeprom_charge_mode_data.decimal_places = (decimal_places_t) atoi(values[idx]); + } // LED related settings else if (strcmp(params[idx], "c1") == 0) { @@ -550,7 +573,7 @@ bool http_rest_charge_mode_config(struct fs_file *file, int num_params, char *pa snprintf(charge_mode_json_buffer, sizeof(charge_mode_json_buffer), "{\"c1\":\"#%06x\",\"c2\":\"#%06x\",\"c3\":\"#%06x\",\"c4\":\"#%06x\"," - "\"c5\":%.3f,\"c6\":%.3f,\"c7\":%.3f,\"c8\":%.3f}", + "\"c5\":%.3f,\"c6\":%.3f,\"c7\":%.3f,\"c8\":%.3f,\"c9\":%d}", charge_mode_config.eeprom_charge_mode_data.neopixel_normal_charge_colour, charge_mode_config.eeprom_charge_mode_data.neopixel_under_charge_colour, charge_mode_config.eeprom_charge_mode_data.neopixel_over_charge_colour, @@ -559,7 +582,8 @@ bool http_rest_charge_mode_config(struct fs_file *file, int num_params, char *pa charge_mode_config.eeprom_charge_mode_data.coarse_stop_threshold, charge_mode_config.eeprom_charge_mode_data.fine_stop_threshold, charge_mode_config.eeprom_charge_mode_data.set_point_sd_margin, - charge_mode_config.eeprom_charge_mode_data.set_point_mean_margin); + charge_mode_config.eeprom_charge_mode_data.set_point_mean_margin, + charge_mode_config.eeprom_charge_mode_data.decimal_places); size_t data_length = strlen(charge_mode_json_buffer); file->data = charge_mode_json_buffer; diff --git a/src/charge_mode.h b/src/charge_mode.h index 1b59b11..701689f 100644 --- a/src/charge_mode.h +++ b/src/charge_mode.h @@ -3,9 +3,12 @@ #include #include "http_rest.h" +#include "common.h" -#define EEPROM_CHARGE_MODE_DATA_REV 6 // 16 byte +#define EEPROM_CHARGE_MODE_DATA_REV 7 // 16 byte + +#define WEIGHT_STRING_LEN 8 typedef struct { uint16_t charge_mode_data_rev; @@ -16,6 +19,8 @@ typedef struct { float set_point_sd_margin; float set_point_mean_margin; + decimal_places_t decimal_places; + // LED related settings uint32_t neopixel_normal_charge_colour; uint32_t neopixel_under_charge_colour; diff --git a/src/cleanup_mode.cpp b/src/cleanup_mode.cpp index bcae865..d604255 100644 --- a/src/cleanup_mode.cpp +++ b/src/cleanup_mode.cpp @@ -10,10 +10,14 @@ #include "motors.h" #include "scale.h" #include "display.h" -# +#include "common.h" +#include "charge_mode.h" +// Memory from other modules extern QueueHandle_t encoder_event_queue; +extern charge_mode_config_t charge_mode_config; + static char title_string[30]; TaskHandle_t cleanup_render_task_handler = NULL; @@ -50,7 +54,12 @@ void cleanup_render_task(void *p) { // Draw charge weight float current_weight = scale_get_current_measurement(); memset(buf, 0x0, sizeof(buf)); - sprintf(buf, "Weight: %0.02f", current_weight); + + // Convert to weight string with given decimal places + char weight_string[WEIGHT_STRING_LEN]; + float_to_string(weight_string, current_weight, charge_mode_config.eeprom_charge_mode_data.decimal_places); + + sprintf(buf, "Weight: %s", weight_string); u8g2_SetFont(display_handler, u8g2_font_profont11_tf); u8g2_DrawStr(display_handler, 5, 25, buf); @@ -60,7 +69,7 @@ void cleanup_render_task(void *p) { float flow_rate = weight_diff / 0.02; // 20 ms per sampling period, see below memset(buf, 0x0, sizeof(buf)); - sprintf(buf, "Flow: %0.2f/s", flow_rate); + sprintf(buf, "Flow: %0.3f/s", flow_rate); u8g2_SetFont(display_handler, u8g2_font_profont11_tf); u8g2_DrawStr(display_handler, 5, 35, buf); diff --git a/src/common.c b/src/common.c index 19f1d46..c5adf08 100644 --- a/src/common.c +++ b/src/common.c @@ -1,6 +1,8 @@ #include #include #include +#include + #include "common.h" #include "pico/time.h" @@ -29,4 +31,22 @@ bool string_to_boolean(char * s) { } return var; +} + + +int float_to_string(char * output_decimal_str, float var, decimal_places_t decimal_places) { + int return_value = 0; + + switch (decimal_places) { + case DP_2: + return_value = sprintf(output_decimal_str, "%0.02f", var); + break; + case DP_3: + return_value = sprintf(output_decimal_str, "%0.03f", var); + break; + default: + break; + } + + return return_value; } \ No newline at end of file diff --git a/src/common.h b/src/common.h index ca30693..5fdd41d 100644 --- a/src/common.h +++ b/src/common.h @@ -4,6 +4,11 @@ #include #include +typedef enum { + DP_2 = 0, + DP_3 = 1, +} decimal_places_t; + #ifdef __cplusplus extern "C" { @@ -18,6 +23,7 @@ void delay_ms(uint32_t ms, BaseType_t scheduler_state); const char * boolean_to_string(bool var); bool string_to_boolean(char * s); +int float_to_string(char * output_decimal_str, float var, decimal_places_t decimal_places); #ifdef __cplusplus } diff --git a/src/html/dashboard.html b/src/html/dashboard.html index 27df216..135fb55 100644 --- a/src/html/dashboard.html +++ b/src/html/dashboard.html @@ -378,6 +378,15 @@

Profile Database

+
+ + +
+
diff --git a/src/mui_menu.c b/src/mui_menu.c index 1c7cd10..6fa406c 100644 --- a/src/mui_menu.c +++ b/src/mui_menu.c @@ -99,13 +99,12 @@ uint8_t render_profile_ver_info(mui_t *ui, uint8_t msg) { uint8_t render_profile_pid_details(mui_t *ui, uint8_t msg) { - u8g2_t *u8g2 = mui_get_U8g2(ui); switch(msg) { case MUIF_MSG_DRAW: { char buf[30]; - + u8g2_t *u8g2 = mui_get_U8g2(ui); profile_t * current_profile = profile_get_selected(); // Render Coarse @@ -141,14 +140,34 @@ uint8_t render_profile_pid_details(mui_t *ui, uint8_t msg) { } +uint8_t render_charge_mode_next_button(mui_t * ui, uint8_t msg) { + switch (msg) { + case MUIF_MSG_CURSOR_SELECT: + case MUIF_MSG_VALUE_INCREMENT: + case MUIF_MSG_VALUE_DECREMENT: + if (charge_mode_config.eeprom_charge_mode_data.decimal_places == DP_2) { + ui->arg = 11; // goto form 11 + } + else if (charge_mode_config.eeprom_charge_mode_data.decimal_places == DP_3) { + ui->arg = 12; // goto form 12 + } + return mui_u8g2_btn_goto_wm_fi(ui, msg); + default: + mui_u8g2_btn_goto_wm_fi(ui, msg); + break; + } + + return 0; +} + + uint8_t render_profile_misc_details(mui_t *ui, uint8_t msg) { - u8g2_t *u8g2 = mui_get_U8g2(ui); switch(msg) { case MUIF_MSG_DRAW: { char buf[30]; - + u8g2_t *u8g2 = mui_get_U8g2(ui); profile_t * current_profile = profile_get_selected(); // Render speed @@ -168,6 +187,7 @@ uint8_t render_profile_misc_details(mui_t *ui, uint8_t msg) { } + muif_t muif_list[] = { /* normal text style */ MUIF_U8G2_FONT_STYLE(0, u8g2_font_helvR08_tr), @@ -193,6 +213,8 @@ muif_t muif_list[] = { /* Goto Form Button where the width is equal to the size of the text, spaces can be used to extend the size */ MUIF_BUTTON("BN", mui_u8g2_btn_goto_wm_fi), + MUIF_BUTTON("B1", render_charge_mode_next_button), + // Leave MUIF_VARIABLE("LV", &exit_state, mui_u8g2_btn_exit_wm_fi), @@ -242,9 +264,20 @@ fds_t fds_data[] = { MUI_XYA("GC", 5, 49, 2) MUI_XYA("GC", 5, 61, 3) - // Menu 10: Start + // Menu 10: Select profile MUI_FORM(10) MUI_STYLE(1) + MUI_LABEL(5,10, "Select Profile") + MUI_XY("HL", 0,13) + + MUI_STYLE(0) + MUI_XYT("B1",115, 59, "Next") // Jump to form 11 or 12 + MUI_XYAT("BN",14, 59, 1, "Back") // Jump to form 1 + MUI_XYA("P0", 5, 25, 33) // Jump to form 33 (profile selection) + + // Menu 11: Charge Weight (2dp) + MUI_FORM(11) + MUI_STYLE(1) MUI_LABEL(5,10, "Select Charge Weight") MUI_XY("HL", 0,13) @@ -259,25 +292,37 @@ fds_t fds_data[] = { MUI_XY("SU", 106, 35) MUI_STYLE(0) - MUI_XYAT("BN",115, 59, 11, "Next") - MUI_XYAT("BN",14, 59, 1, "Back") + MUI_XYAT("BN",115, 59, 13, "Next") + MUI_XYAT("BN",14, 59, 10, "Back") MUI_STYLE(3) MUI_XY("N4",20, 35) - // Menu 11: Select profile - MUI_FORM(11) + // Menu 12: Charge Weight (3dp) + MUI_FORM(12) MUI_STYLE(1) - MUI_LABEL(5,10, "Select Profile") + MUI_LABEL(5,10, "Select Charge Weight") MUI_XY("HL", 0,13) + MUI_STYLE(3) + MUI_XY("N3",36, 35) + MUI_LABEL(48, 35, ".") + MUI_XY("N2",60, 35) + MUI_XY("N1",76, 35) + MUI_XY("N0",92, 35) + MUI_STYLE(0) - MUI_XYAT("BN",115, 59, 12, "Next") // Jump to form 10 - MUI_XYAT("BN",14, 59, 10, "Back") // Jump to form 12 - MUI_XYA("P0", 5, 25, 33) // Jump to form 33 (profile selection) + MUI_XY("SU", 106, 35) - // Menu 12: - MUI_FORM(12) + MUI_STYLE(0) + MUI_XYAT("BN",115, 59, 13, "Next") + MUI_XYAT("BN",14, 59, 10, "Back") + + MUI_STYLE(3) + MUI_XY("N4",20, 35) + + // Menu 13: Warning page + MUI_FORM(13) MUI_STYLE(1) MUI_LABEL(5, 10, "Warning") MUI_XY("HL", 0,13) @@ -287,9 +332,8 @@ fds_t fds_data[] = { MUI_LABEL(5, 37, "press Next to trickle") MUI_STYLE(0) - MUI_XYAT("BN",14, 59, 11, "Back") + MUI_XYAT("BN",14, 59, 10, "Back") MUI_XYAT("LV", 115, 59, 1, "Next") // APP_STATE_ENTER_CHARGE_MODE - // MUI_XYAT("BN",115, 59, 0, "Next") // Menu 20: Cleanup MUI_FORM(20) diff --git a/tests/config_html_rest_test.py b/tests/config_html_rest_test.py index 88cf432..65114b3 100644 --- a/tests/config_html_rest_test.py +++ b/tests/config_html_rest_test.py @@ -31,7 +31,7 @@ def rest_scale_config(): @app.route('/rest/charge_mode_config') def rest_charge_mode_config(): - return """{"c1":"#00ff00","c2":"#ffff00","c3":"#ff0000","c4":"#0000ff","c5":3.000,"c6":0.030,"c7":0.020,"c8":0.020}""" + return """{"c1":"#00ff00","c2":"#ffff00","c3":"#ff0000","c4":"#0000ff","c5":5.000,"c6":0.030,"c7":0.020,"c8":0.020,"c9":0}""" @app.route('/rest/wireless_config')