Add fan/speed controls to bambu

This commit is contained in:
suchmememanyskill
2024-12-21 22:04:51 +01:00
parent 4dd70aa3ea
commit 093dd5efff
10 changed files with 140 additions and 47 deletions

View File

@@ -10,15 +10,13 @@ enum BambuSpeedProfile
BambuSpeedProfileNormal = 2, BambuSpeedProfileNormal = 2,
BambuSpeedProfileSport = 3, BambuSpeedProfileSport = 3,
BambuSpeedProfileLudicrous = 4, BambuSpeedProfileLudicrous = 4,
} };
class BambuPrinter : public BasePrinter class BambuPrinter : public BasePrinter
{ {
private: private:
unsigned int last_error = 0; unsigned int last_error = 0;
unsigned int ignore_error = 0; unsigned int ignore_error = 0;
bool publish_mqtt_command(const char* command);
BambuSpeedProfile speed_profile = 2;
unsigned long print_start; unsigned long print_start;
union { union {
@@ -37,6 +35,10 @@ class BambuPrinter : public BasePrinter
Files parse_files(WiFiClientSecure& client, int max_files); Files parse_files(WiFiClientSecure& client, int max_files);
public: public:
float aux_fan_speed;
float chamber_fan_speed;
BambuSpeedProfile speed_profile = BambuSpeedProfileNormal;
BambuPrinter(int index) : BasePrinter(index) BambuPrinter(int index) : BasePrinter(index)
{ {
supported_features = PrinterFeatureHome supported_features = PrinterFeatureHome
@@ -59,6 +61,8 @@ class BambuPrinter : public BasePrinter
bambu_misc = 0; bambu_misc = 0;
printer_data.error_screen_features = PrinterFeatureRetryError | PrinterFeatureIgnoreError | PrinterFeatureContinueError; printer_data.error_screen_features = PrinterFeatureRetryError | PrinterFeatureIgnoreError | PrinterFeatureContinueError;
print_start = millis(); print_start = millis();
init_ui_panels();
} }
bool move_printer(const char* axis, float amount, bool relative); bool move_printer(const char* axis, float amount, bool relative);
@@ -79,6 +83,7 @@ class BambuPrinter : public BasePrinter
bool set_target_temperature(PrinterTemperatureDevice device, unsigned int temperature); bool set_target_temperature(PrinterTemperatureDevice device, unsigned int temperature);
bool send_gcode(const char* gcode, bool wait = true); bool send_gcode(const char* gcode, bool wait = true);
void receive_data(unsigned char* data, unsigned int length); void receive_data(unsigned char* data, unsigned int length);
bool publish_mqtt_command(const char* command);
}; };
enum BambuConnectionStatus { enum BambuConnectionStatus {

View File

@@ -6,78 +6,137 @@
const char* speed_profiles[] = { "Silent (50%)", "Normal (100%)", "Sport (124%)", "Ludicrous (166%)" }; const char* speed_profiles[] = { "Silent (50%)", "Normal (100%)", "Sport (124%)", "Ludicrous (166%)" };
const BambuSpeedProfile speed_profile_values[] = { BambuSpeedProfileSilent, BambuSpeedProfileNormal, BambuSpeedProfileSport, BambuSpeedProfileLudicrous }; const BambuSpeedProfile speed_profile_values[] = { BambuSpeedProfileSilent, BambuSpeedProfileNormal, BambuSpeedProfileSport, BambuSpeedProfileLudicrous };
const char* COMMAND_SET_PRINT_SPEED = "{\"print\":{\"command\":\"print_speed\",\"param\":\"%d\"}}";
// TODO: Move to common enum FanIndex
static void set_fan_speed_text(lv_event_t * e) { {
PartFan = 1,
AuxFan = 2,
ChamberFan = 3,
};
static void set_fan_speed_text(lv_event_t* e, FanIndex index)
{
lv_obj_t * label = lv_event_get_target(e); lv_obj_t * label = lv_event_get_target(e);
char data[16]; char data[16];
sprintf(data, "Fan: %.0f%%", get_current_printer_data()->fan_speed * 100);
float fan_speed = 0;
const char* fan_type = "";
switch (index)
{
case PartFan:
fan_speed = get_current_printer_data()->fan_speed;
fan_type = "P.Fan";
break;
case AuxFan:
fan_speed = ((BambuPrinter*)get_current_printer)->aux_fan_speed;
fan_type = "A.Fan";
break;
case ChamberFan:
fan_speed = ((BambuPrinter*)get_current_printer)->chamber_fan_speed;
fan_type = "C.Fan";
break;
}
sprintf(data, "%s: %.0f%%", fan_type, get_current_printer_data()->fan_speed * 100);
lv_label_set_text(label, data); lv_label_set_text(label, data);
} }
static void set_fan_speed(lv_event_t * e){ static void set_fan_speed(lv_event_t* e, FanIndex index)
{
int speed = (int)lv_event_get_user_data(e); int speed = (int)lv_event_get_user_data(e);
int actual_speed = fan_percent_to_byte(speed);
BambuPrinter* printer = (BambuPrinter*)get_current_printer(); // TODO: pass by ref BambuPrinter* printer = (BambuPrinter*)get_current_printer(); // TODO: pass by ref
// TODO: Implement char buff[20];
sprintf(buff, "M106 P%d S%d", index, actual_speed);
printer->send_gcode(buff);
} }
FAN_SPEED_COLUMN(set_fan_speed, fan_speed_columns) static void set_part_fan_speed_text(lv_event_t * e)
{
static void set_aux_fan_speed_text(lv_event_t * e) { set_fan_speed_text(e, FanIndex::PartFan);
// TODO: Implement
lv_obj_t * label = lv_event_get_target(e);
char data[16];
sprintf(data, "Fan: %.0f%%", get_current_printer_data()->fan_speed * 100);
lv_label_set_text(label, data);
} }
static void set_aux_fan_speed(lv_event_t * e){ static void set_part_fan_speed(lv_event_t * e)
int speed = (int)lv_event_get_user_data(e); {
BambuPrinter* printer = (BambuPrinter*)get_current_printer(); // TODO: pass by ref set_fan_speed(e, FanIndex::PartFan);
// TODO: Implement }
FAN_SPEED_COLUMN(set_part_fan_speed, part_fan_speed_columns)
static void set_aux_fan_speed_text(lv_event_t * e)
{
set_fan_speed_text(e, FanIndex::AuxFan);
}
static void set_aux_fan_speed(lv_event_t * e)
{
set_fan_speed(e, FanIndex::AuxFan);
} }
FAN_SPEED_COLUMN(set_aux_fan_speed, aux_fan_speed_columns) FAN_SPEED_COLUMN(set_aux_fan_speed, aux_fan_speed_columns)
static void set_chamber_fan_speed_text(lv_event_t * e)
{
set_fan_speed_text(e, FanIndex::ChamberFan);
}
static void set_chamber_fan_speed(lv_event_t * e)
{
set_fan_speed(e, FanIndex::ChamberFan);
}
FAN_SPEED_COLUMN(set_chamber_fan_speed, chamber_fan_speed_columns)
// TODO: move to common // TODO: move to common
static void set_speed_mult_text(lv_event_t * e){ static void set_speed_mult_text(lv_event_t * e){
lv_obj_t * label = lv_event_get_target(e); lv_obj_t * label = lv_event_get_target(e);
char data[16]; char buff[16];
sprintf(data, "Speed: %.0f%%", get_current_printer_data()->speed_mult * 100); sprintf(buff, "Speed: %.0f%%", get_current_printer_data()->speed_mult * 100);
lv_label_set_text(label, data); lv_label_set_text(label, buff);
} }
static void set_speed_mult(lv_event_t * e) static void set_speed_mult(lv_event_t * e)
{ {
BambuSpeedProfile speed = (BambuSpeedProfile)lv_event_get_user_data(e); BambuSpeedProfile speed = (BambuSpeedProfile)((int)lv_event_get_user_data(e));
BambuPrinter* printer = (BambuPrinter*)get_current_printer(); // TODO: pass by ref BambuPrinter* printer = (BambuPrinter*)get_current_printer(); // TODO: pass by ref
// TODO: Implement char buff[128];
sprintf(buff, COMMAND_SET_PRINT_SPEED, speed);
printer->publish_mqtt_command(buff);
} }
lv_button_column_t speed_profile_columns[] = { lv_button_column_t speed_profile_columns[] = {
{ set_speed_mult, speed_profiles, (const void**)speed_profile_values, 4}, { set_speed_mult, speed_profiles, (const void**)speed_profile_values, 4},
}; };
static void open_fan_speed_panel(lv_event_t * e){ static void open_part_fan_speed_panel(lv_event_t * e){
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_fan_speed_text, fan_speed_columns, 3); lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_part_fan_speed_text, part_fan_speed_columns, 3);
} }
static void open_aux_fan_speed_panel(lv_event_t * e){ static void open_aux_fan_speed_panel(lv_event_t * e){
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_aux_fan_speed_text, aux_fan_speed_columns, 3); lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_aux_fan_speed_text, aux_fan_speed_columns, 3);
} }
static void open_chamber_fan_speed_panel(lv_event_t * e){
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_chamber_fan_speed_text, chamber_fan_speed_columns, 3);
}
static void open_speed_mult_panel(lv_event_t * e){ static void open_speed_mult_panel(lv_event_t * e){
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_speed_mult_text, speed_profile_columns, 1); lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_speed_mult_text, speed_profile_columns, 1);
} }
static PrinterUiPanel bambu_ui_panels[3] { static PrinterUiPanel bambu_ui_panels[4] {
{ .set_label = (void*)set_fan_speed_text, .open_panel = (void*)open_fan_speed_panel },
{ .set_label = (void*)set_aux_fan_speed_text, .open_panel = (void*)open_aux_fan_speed_panel },
{ .set_label = (void*)set_speed_mult_text, .open_panel = (void*)open_speed_mult_panel }, { .set_label = (void*)set_speed_mult_text, .open_panel = (void*)open_speed_mult_panel },
{ .set_label = (void*)set_part_fan_speed_text, .open_panel = (void*)open_part_fan_speed_panel },
{ .set_label = (void*)set_chamber_fan_speed_text, .open_panel = (void*)open_chamber_fan_speed_panel },
{ .set_label = (void*)set_aux_fan_speed_text, .open_panel = (void*)open_aux_fan_speed_panel },
}; };
void BambuPrinter::init_ui_panels() void BambuPrinter::init_ui_panels()
{ {
custom_menus_count = 3; custom_menus_count = 4;
custom_menus = bambu_ui_panels; custom_menus = bambu_ui_panels;
} }

View File

@@ -6,6 +6,18 @@
#define BIT_Y_AXIS_HOMED BIT(1) #define BIT_Y_AXIS_HOMED BIT(1)
#define BIT_Z_AXIS_HOMED BIT(2) #define BIT_Z_AXIS_HOMED BIT(2)
float convert_fan_speed(const char* in)
{
if (in == NULL || strlen(in) <= 0)
{
return 0;
}
int part_value = atoi(in);
float percentage = (part_value / 15.0f) * 100;
return round(percentage / 10) / 10;
}
void BambuPrinter::parse_state(JsonDocument& in) void BambuPrinter::parse_state(JsonDocument& in)
{ {
if (!in.containsKey("print")) if (!in.containsKey("print"))
@@ -83,7 +95,7 @@ void BambuPrinter::parse_state(JsonDocument& in)
if (print.containsKey("spd_lvl")) if (print.containsKey("spd_lvl"))
{ {
int speed_profile_int = print["spd_lvl"] int speed_profile_int = print["spd_lvl"];
speed_profile = (BambuSpeedProfile)speed_profile_int; speed_profile = (BambuSpeedProfile)speed_profile_int;
switch (speed_profile) switch (speed_profile)
@@ -201,6 +213,21 @@ void BambuPrinter::parse_state(JsonDocument& in)
} }
} }
if (print.containsKey("cooling_fan_speed"))
{
printer_data.fan_speed = convert_fan_speed(print["cooling_fan_speed"]);
}
if (print.containsKey("big_fan1_speed"))
{
aux_fan_speed = convert_fan_speed(print["big_fan1_speed"]);
}
if (print.containsKey("big_fan2_speed"))
{
chamber_fan_speed = convert_fan_speed(print["big_fan2_speed"]);
}
printer_data.extrude_mult = 1; printer_data.extrude_mult = 1;
} }

View File

@@ -1,15 +1,15 @@
#include "constants.h" #include "constants.h"
const char* fan_speeds_col_1[] = { "On", "Off" }; const char* fan_speeds_col_1[] = { "On", "Off" };
const int fan_speeds_col_1_values[] = { 0, 100 }; const int fan_speeds_col_1_values[] = { 100, 0 };
const char* fan_speeds_col_2[] = { "10%", "20%", "30%", "40%"}; const char* fan_speeds_col_2[] = { "10%", "20%", "30%", "40%", "50%"};
const int fan_speeds_col_2_values[] = { 10, 20, 30, 40 }; const int fan_speeds_col_2_values[] = { 10, 20, 30, 40, 50 };
const char* fan_speeds_col_3[] = { "50%", "60%", "70%", "80%"}; const char* fan_speeds_col_3[] = { "60%", "70%", "80%", "90%"};
const int fan_speeds_col_3_values[] = { 50, 60, 70, 80 }; const int fan_speeds_col_3_values[] = { 60, 70, 80, 90 };
char fan_percent_to_byte(int percent) unsigned char fan_percent_to_byte(int percent)
{ {
return percent * 255 / 100; return percent * 255 / 100;
} }

View File

@@ -11,4 +11,4 @@ extern const int fan_speeds_col_3_values[];
unsigned char fan_percent_to_byte(int percent); unsigned char fan_percent_to_byte(int percent);
#define FAN_SPEED_COLUMN(set_fan_speed, column_name) lv_button_column_t column_name[] = {{ set_fan_speed, fan_speeds_col_2, (const void**)fan_speeds_col_2_values, 4},{ set_fan_speed, fan_speeds_col_3, (const void**)fan_speeds_col_3_values, 4}, { set_fan_speed, fan_speeds_col_1, (const void**)fan_speeds_col_1_values, 2}}; #define FAN_SPEED_COLUMN(set_fan_speed, column_name) lv_button_column_t column_name[] = {{ set_fan_speed, fan_speeds_col_2, (const void**)fan_speeds_col_2_values, 5},{ set_fan_speed, fan_speeds_col_3, (const void**)fan_speeds_col_3_values, 4}, { set_fan_speed, fan_speeds_col_1, (const void**)fan_speeds_col_1_values, 2}};

View File

@@ -20,7 +20,7 @@ static void set_fan_speed(lv_event_t * e){
printer->send_gcode(gcode); printer->send_gcode(gcode);
} }
FAN_SPEED_COLUMN(set_fan_speed, fan_speed_columns) FAN_SPEED_COLUMN(set_fan_speed, klipper_fan_speed_columns)
static void set_zoffset_text(lv_event_t * e) { static void set_zoffset_text(lv_event_t * e) {
lv_obj_t * label = lv_event_get_target(e); lv_obj_t * label = lv_event_get_target(e);
@@ -145,7 +145,7 @@ lv_button_column_t extrude_mult_columns[] = {
}; };
static void open_fan_speed_panel(lv_event_t * e){ static void open_fan_speed_panel(lv_event_t * e){
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_fan_speed_text, fan_speed_columns, 2); lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_fan_speed_text, klipper_fan_speed_columns, 2);
} }
static void open_zoffset_panel(lv_event_t * e){ static void open_zoffset_panel(lv_event_t * e){

View File

@@ -59,11 +59,11 @@ static void set_fan_speed(lv_event_t * e)
((OctoPrinter*)get_current_printer())->send_gcode(buff); ((OctoPrinter*)get_current_printer())->send_gcode(buff);
} }
FAN_SPEED_COLUMN(set_fan_speed, fan_speed_columns) FAN_SPEED_COLUMN(set_fan_speed, octo_fan_speed_columns)
static void open_fan_speed_panel(lv_event_t * e) static void open_fan_speed_panel(lv_event_t * e)
{ {
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_fan_speed_text, fan_speed_columns, 3); lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_fan_speed_text, octo_fan_speed_columns, 3);
} }
static void set_speed_mult(lv_event_t * e) static void set_speed_mult(lv_event_t * e)

View File

@@ -467,10 +467,10 @@ void choose_printer_type()
lv_obj_t * label = lv_label_create(root); lv_obj_t * label = lv_label_create(root);
lv_label_set_text(label, "Choose printer type"); lv_label_set_text(label, "Choose printer type");
create_printer_type_button(root, "Klipper", printer_type_klipper); create_printer_type_button(root, "Klipper (Wifi)", printer_type_klipper);
create_printer_type_button(root, "Klipper (Serial/USB)", printer_type_serial_klipper, false); create_printer_type_button(root, "Klipper (Serial/USB)", printer_type_serial_klipper, false);
create_printer_type_button(root, "Bambu (Local)", printer_type_bambu_local); create_printer_type_button(root, "Bambu (Wifi, Local) [BETA]", printer_type_bambu_local);
create_printer_type_button(root, "Octoprint", printer_type_octoprint); create_printer_type_button(root, "Octoprint (Wifi) [BETA]", printer_type_octoprint);
if (global_config.wifi_configuration_skipped) if (global_config.wifi_configuration_skipped)
{ {

View File

@@ -90,7 +90,8 @@ void lv_create_fullscreen_button_matrix_popup(lv_obj_t * root, lv_event_cb_t tit
for (int j = 0; j < columns[i].length; j++){ for (int j = 0; j < columns[i].length; j++){
lv_obj_t * btn = lv_btn_create(column); lv_obj_t * btn = lv_btn_create(column);
lv_obj_set_size(btn, column_width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); lv_obj_set_width(btn, column_width);
lv_obj_set_flex_grow(btn, 1);
lv_obj_add_event_cb(btn, columns[i].event, LV_EVENT_CLICKED, (void*)columns[i].data[j]); lv_obj_add_event_cb(btn, columns[i].event, LV_EVENT_CLICKED, (void*)columns[i].data[j]);
label = lv_label_create(btn); label = lv_label_create(btn);

View File

@@ -120,6 +120,7 @@ static void wifi_btn_settings(lv_event_t * e){
lv_obj_t * btn = lv_btn_create(panel); lv_obj_t * btn = lv_btn_create(panel);
lv_obj_add_event_cb(btn, reset_btn_event_handler, LV_EVENT_CLICKED, NULL); lv_obj_add_event_cb(btn, reset_btn_event_handler, LV_EVENT_CLICKED, NULL);
lv_obj_set_style_radius(btn, 0, 0);
lv_obj_set_size(btn, LV_PCT(100), CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); lv_obj_set_size(btn, LV_PCT(100), CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_t * label = lv_label_create(btn); lv_obj_t * label = lv_label_create(btn);