Skip to content

Commit

Permalink
Refactor scale class to be more generic and allow more scale implemet…
Browse files Browse the repository at this point in the history
…nation
  • Loading branch information
eamars committed Aug 15, 2023
1 parent 8ff662b commit c6c726b
Show file tree
Hide file tree
Showing 6 changed files with 244 additions and 169 deletions.
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
"cmake.generator": "Ninja",
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
"files.associations": {
"neopixel_led.h": "c"
"neopixel_led.h": "c",
"app.h": "c",
"queue.h": "c"
}
}
167 changes: 14 additions & 153 deletions src/and_scale.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

#include <FreeRTOS.h>
#include <queue.h>
#include <stdlib.h>
Expand Down Expand Up @@ -27,26 +26,29 @@ typedef union {
} scale_standard_data_format_t;


// In this case we will only use eeprom data format to store information
eeprom_scale_data_t scale_data;
// Forward declaration
void scale_listener_task(void *p);
void scale_write(char * command, size_t len);
extern scale_config_t scale_config;

// Instance of the scale handle for A&D FXi series
scale_handle_t and_fxi_scale_handle = {
.read_loop_task = scale_listener_task,
.write = scale_write
};

// Statics (to be shared between multiple tasks)
static float current_scale_measurement = NAN;
SemaphoreHandle_t scale_measurement_ready;
SemaphoreHandle_t scale_serial_write_access_mutex = NULL;


static inline void _take_mutex(BaseType_t scheduler_state) {
if (scheduler_state != taskSCHEDULER_NOT_STARTED){
xSemaphoreTake(scale_serial_write_access_mutex, portMAX_DELAY);
xSemaphoreTake(scale_config.scale_serial_write_access_mutex, portMAX_DELAY);
}
}


static inline void _give_mutex(BaseType_t scheduler_state) {
if (scheduler_state != taskSCHEDULER_NOT_STARTED){
xSemaphoreGive(scale_serial_write_access_mutex);
xSemaphoreGive(scale_config.scale_serial_write_access_mutex);
}
}

Expand All @@ -72,50 +74,6 @@ float _decode_measurement_msg(scale_standard_data_format_t * msg) {
return weight;
}

bool scale_init() {
bool is_ok;

uart_init(SCALE_UART, SCALE_UART_BAUDRATE);

gpio_set_function(SCALE_UART_TX, GPIO_FUNC_UART);
gpio_set_function(SCALE_UART_RX, GPIO_FUNC_UART);

// Read config from EEPROM
is_ok = eeprom_read(EEPROM_SCALE_CONFIG_BASE_ADDR, (uint8_t *) &scale_data, sizeof(eeprom_scale_data_t));
if (!is_ok) {
printf("Unable to read from EEPROM at address %x\n", EEPROM_SCALE_CONFIG_BASE_ADDR);
return false;
}

// If the revision doesn't match then re-initialize the config
if (scale_data.scale_data_rev != EEPROM_SCALE_DATA_REV) {
scale_data.scale_data_rev = EEPROM_SCALE_DATA_REV;
scale_data.scale_unit = SCALE_UNIT_GRAIN;

// Write data back
is_ok = scale_config_save();
if (!is_ok) {
printf("Unable to write to %x\n", EEPROM_SCALE_CONFIG_BASE_ADDR);
return false;
}
}

// Create control variables
// Semaphore to indicate the availability of new measurement.
scale_measurement_ready = xSemaphoreCreateBinary();

// Mutex to control the access to the serial port write
scale_serial_write_access_mutex = xSemaphoreCreateMutex();

return is_ok;
}


bool scale_config_save() {
bool is_ok = eeprom_write(EEPROM_SCALE_CONFIG_BASE_ADDR, (uint8_t *) &scale_data, sizeof(eeprom_scale_data_t));
return is_ok;
}


void scale_listener_task(void *p) {
char string_buf[20];
Expand All @@ -131,11 +89,11 @@ void scale_listener_task(void *p) {
// If we have received 17 bytes then we can decode the message
if (string_buf_idx == 17) {
// Data is ready, send to decode
current_scale_measurement = _decode_measurement_msg((scale_standard_data_format_t *) string_buf);
scale_config.current_scale_measurement = _decode_measurement_msg((scale_standard_data_format_t *) string_buf);

// Signal the data is ready
if (scale_measurement_ready) {
xSemaphoreGive(scale_measurement_ready);
if (scale_config.scale_measurement_ready) {
xSemaphoreGive(scale_config.scale_measurement_ready);
}

// Reset
Expand All @@ -153,17 +111,6 @@ void scale_listener_task(void *p) {
}


float scale_get_current_measurement() {
return current_scale_measurement;
}

float scale_block_wait_for_next_measurement() {
// You can only call this once the scheduler starts
xSemaphoreTake(scale_measurement_ready, portMAX_DELAY);
return scale_get_current_measurement();
}


void scale_press_re_zero_key() {
char cmd[] = "Z\r\n";
scale_write(cmd, strlen(cmd));
Expand Down Expand Up @@ -209,89 +156,3 @@ void scale_display_on() {
// AppState_t scale_enable_fast_report(AppState_t prev_state) {
// // TODO: Finish this
// }


const char * get_scale_unit_string(bool is_short_string) {
const char * scale_unit_string = NULL;

switch (scale_data.scale_unit) {
case SCALE_UNIT_GRAIN:
if (is_short_string) {
scale_unit_string = "gn";
}
else {
scale_unit_string = "grain";
}

break;
case SCALE_UNIT_GRAM:
if (is_short_string) {
scale_unit_string = "g";
}
else {
scale_unit_string = "gram";
}

break;
default:
break;
}

return scale_unit_string;
}

void set_scale_unit(scale_unit_t scale_unit) {
scale_data.scale_unit = scale_unit;
}


bool http_rest_scale_weight(struct fs_file *file, int num_params, char *params[], char *values[]) {
static char scale_weight_to_json_buffer[32];

snprintf(scale_weight_to_json_buffer,
sizeof(scale_weight_to_json_buffer),
"{\"weight\":%0.3f}",
scale_get_current_measurement());

size_t data_length = strlen(scale_weight_to_json_buffer);
file->data = scale_weight_to_json_buffer;
file->len = data_length;
file->index = data_length;
file->flags = FS_FILE_FLAGS_HEADER_INCLUDED;

return true;
}


bool http_rest_scale_config(struct fs_file *file, int num_params, char *params[], char *values[]) {
static char scale_config_to_json_buffer[32];

// Set value
for (int idx = 0; idx < num_params; idx += 1) {
if (strcmp(params[idx], "unit") == 0) {
if (strcmp(values[idx], "grain") == 0) {
set_scale_unit(SCALE_UNIT_GRAIN);
}
else if (strcmp(values[idx], "gram") == 0) {
set_scale_unit(SCALE_UNIT_GRAM);
scale_data.scale_unit = SCALE_UNIT_GRAM;
}
}
}

// Convert config to string
const char * scale_unit_string = get_scale_unit_string(false);

snprintf(scale_config_to_json_buffer,
sizeof(scale_config_to_json_buffer),
"{\"unit\":\"%s\"}",
scale_unit_string);

size_t data_length = strlen(scale_config_to_json_buffer);
file->data = scale_config_to_json_buffer;
file->len = data_length;
file->index = data_length;
file->flags = FS_FILE_FLAGS_HEADER_INCLUDED;

return true;
}
1 change: 0 additions & 1 deletion src/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ int main()
#error "Unpported platform"
#endif // RASPBERRYPI_PICO_W
xTaskCreate(menu_task, "Menu Task", configMINIMAL_STACK_SIZE, NULL, 6, NULL);
xTaskCreate(scale_listener_task, "Scale Task", configMINIMAL_STACK_SIZE, NULL, 9, NULL);
// xTaskCreate(motor_task, "Motor Task", configMINIMAL_STACK_SIZE, NULL, 8, NULL);

vTaskStartScheduler();
Expand Down
4 changes: 2 additions & 2 deletions src/mui_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ extern AppState_t exit_state;
extern charge_mode_config_t charge_mode_config;

// Imported from and_scale module
extern eeprom_scale_data_t scale_data;
extern scale_config_t scale_config;



Expand Down Expand Up @@ -154,7 +154,7 @@ muif_t muif_list[] = {
MUIF_VARIABLE("LV", &exit_state, mui_u8g2_btn_exit_wm_fi),

// Unit selection
MUIF_VARIABLE("UN",&scale_data.scale_unit, mui_u8g2_u8_opt_line_wa_mud_pi),
MUIF_VARIABLE("UN",&scale_config.persistent_config.scale_unit, mui_u8g2_u8_opt_line_wa_mud_pi),

// Render unit
MUIF_RO("SU", render_scale_unit),
Expand Down
Loading

0 comments on commit c6c726b

Please sign in to comment.