Skip to content

Commit

Permalink
Add custom filament support
Browse files Browse the repository at this point in the history
  • Loading branch information
bkerler committed Apr 29, 2024
1 parent 0de68b8 commit 877110a
Show file tree
Hide file tree
Showing 26 changed files with 697 additions and 21 deletions.
21 changes: 21 additions & 0 deletions doc/prusa_printer_settings.ini
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,24 @@ hostname = buddy-a.connect.prusa3d.com
token = 1234567890
port = 443
tls = yes

[custom_filament]
name_1=PCTG
nozzle_preheat_1=170
nozzle_1=260
heatbed_1=100

name_2=PHA
nozzle_preheat_2=170
nozzle_2=210
heatbed_2=0

name_3=NGEN
nozzle_preheat_3=170
nozzle_3=240
heatbed_3=90

name_4=CPE
nozzle_preheat_4=275
nozzle_4=210
heatbed_4=90
3 changes: 2 additions & 1 deletion src/common/client_response.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,8 @@ class ClientResponses {
static constexpr PhaseResponses PreheatResponses[] = {
{}, // initial
{ Response::Abort, Response::Cooldown, Response::PLA, Response::PETG,
Response::ASA, Response::ABS, Response::PC, Response::FLEX, Response::HIPS, Response::PP, Response::PVB, Response::PA }, // UserTempSelection
Response::ASA, Response::ABS, Response::PC, Response::FLEX, Response::HIPS, Response::PP, Response::PVB, Response::PA,
Response::CUSTOM_1, Response::CUSTOM_2, Response::CUSTOM_3, Response::CUSTOM_4 }, // UserTempSelection
};
static_assert(std::size(ClientResponses::PreheatResponses) == CountPhases<PhasesPreheat>());

Expand Down
20 changes: 20 additions & 0 deletions src/common/client_response_texts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,26 @@ inline constexpr const char *get_response_text(Response response) {
return N_("CONTINUE");
case Response::Cooldown:
return N_("COOLDOWN");
#ifdef TEST
case Response::CUSTOM_1:
return config_store().custom_filament_name_1.get_c_str();
case Response::CUSTOM_2:
return config_store().custom_filament_name_2.get_c_str();
case Response::CUSTOM_3:
return config_store().custom_filament_name_3.get_c_str();
case Response::CUSTOM_4:
return config_store().custom_filament_name_4.get_c_str();
#else
case Response::CUSTOM_1:
return "CUSTOM_1";
case Response::CUSTOM_2:
return "CUSTOM_2";
case Response::CUSTOM_3:
return "CUSTOM_3";
case Response::CUSTOM_4:
return "CUSTOM_4";
#endif

case Response::Disable:
return N_("DISABLE");
case Response::Done:
Expand Down
61 changes: 49 additions & 12 deletions src/common/filament.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ constexpr filament::Description filaments[size_t(filament::Type::_last) + 1] = {
{ 240, FLEX_NOZZLE_PREHEAT, 50, Response::FLEX },
};

filament::Description custom_filaments[config_store_ns::max_custom_filament_slots] = {
{ 215, 170, 60, Response::CUSTOM_1 },
{ 215, 170, 60, Response::CUSTOM_2 },
{ 215, 170, 60, Response::CUSTOM_3 },
{ 215, 170, 60, Response::CUSTOM_4 }
};

static_assert(sizeof(filaments) / sizeof(filaments[0]) == size_t(filament::Type::_last) + 1, "Filament count error.");

constexpr bool temperatures_are_within_spec(filament::Description filament) {
Expand All @@ -39,30 +46,60 @@ constexpr bool temperatures_are_within_spec(filament::Description filament) {

static_assert(std::ranges::all_of(filaments, temperatures_are_within_spec));

filament::Type filament::get_type(const char *name, size_t name_len) {
// first name is not valid ("---")
for (size_t i = size_t(filament::Type::NONE) + 1; i <= size_t(filament::Type::_last); ++i) {
const char *filament_name = get_response_text(filaments[i].response);
if ((strlen(filament_name) == name_len) && (!strncmp(name, filament_name, name_len))) {
return static_cast<filament::Type>(i);
}
}
return filament::Type::NONE;
}

filament::Type filament::get_type(Response resp) {
for (size_t i = size_t(filament::Type::NONE); i <= size_t(filament::Type::_last); ++i) {
if (filaments[i].response == resp) {
return static_cast<filament::Type>(i);
}
}
for (size_t i = 0; i <= size_t(custom_filaments); ++i) {
if (custom_filaments[i].response == resp) {
return static_cast<filament::Type>(size_t(filament::Type::_last) + 1 + i);
}
}
return filament::Type::NONE;
}

const filament::Description &filament::get_description(filament::Type filament) {
const filament::Description &filament::get_description(const filament::Type filament) {
if (filament == filament::Type::CUSTOM_1) {
custom_filaments[0].nozzle = config_store().custom_filament_nozzle_1.get();
custom_filaments[0].nozzle_preheat = config_store().custom_filament_nozzle_preheat_1.get();
custom_filaments[0].heatbed = config_store().custom_filament_heatbed_1.get();
const filament::Description &filamentsetting = custom_filaments[0];
return filamentsetting;
} else if (filament == filament::Type::CUSTOM_2) {
custom_filaments[1].nozzle = config_store().custom_filament_nozzle_2.get();
custom_filaments[1].nozzle_preheat = config_store().custom_filament_nozzle_preheat_2.get();
custom_filaments[1].heatbed = config_store().custom_filament_heatbed_2.get();
const filament::Description &filamentsetting = custom_filaments[1];
return filamentsetting;
} else if (filament == filament::Type::CUSTOM_3) {
custom_filaments[2].nozzle = config_store().custom_filament_nozzle_3.get();
custom_filaments[2].nozzle_preheat = config_store().custom_filament_nozzle_preheat_3.get();
custom_filaments[2].heatbed = config_store().custom_filament_heatbed_3.get();
const filament::Description &filamentsetting = custom_filaments[2];
return filamentsetting;
} else if (filament == filament::Type::CUSTOM_4) {
custom_filaments[3].nozzle = config_store().custom_filament_nozzle_4.get();
custom_filaments[3].nozzle_preheat = config_store().custom_filament_nozzle_preheat_4.get();
custom_filaments[3].heatbed = config_store().custom_filament_heatbed_4.get();
const filament::Description &filamentsetting = custom_filaments[3];
return filamentsetting;
}
return filaments[size_t(filament)];
}

filament::Type filament::get_type(const char *name, size_t name_len) {
// first name is not valid ("---")
for (size_t i = size_t(filament::Type::NONE) + 1; i <= size_t(filament::Type::_last); ++i) {
const char *filament_name = get_response_text(filaments[i].response);
if ((strlen(filament_name) == name_len) && (!strncmp(name, filament_name, name_len))) {
return static_cast<filament::Type>(i);
}
}
return static_cast<filament::Type>(filament::Type::NONE);
}

const char *filament::get_name(Type type) {
if (type == Type::NONE) {
return "---";
Expand Down
4 changes: 4 additions & 0 deletions src/common/filament.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ enum class Type : uint8_t {
PP,
FLEX,
PA,
CUSTOM_1,
CUSTOM_2,
CUSTOM_3,
CUSTOM_4,
_last = PA
};

Expand Down
2 changes: 1 addition & 1 deletion src/common/gcode/gcode_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class GCodeInfo {
static constexpr size_t search_first_x_gcodes = 200;

using time_buff = std::array<char, 16>;
using filament_buff = std::array<char, 8>;
using filament_buff = std::array<char, config_store_ns::max_filament_name_size>;

struct ExtruderInfo {
struct Colour {
Expand Down
4 changes: 4 additions & 0 deletions src/common/general_response.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ constexpr std::pair<Response, const char *> response_str[] = {
R(Change),
R(Continue),
R(Cooldown),
R(CUSTOM_1),
R(CUSTOM_2),
R(CUSTOM_3),
R(CUSTOM_4),
R(Disable),
R(Done),
R(Filament),
Expand Down
4 changes: 4 additions & 0 deletions src/common/general_response.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ enum class Response : uint8_t {
Change,
Continue,
Cooldown,
CUSTOM_1,
CUSTOM_2,
CUSTOM_3,
CUSTOM_4,
Disable,
Done,
Filament,
Expand Down
16 changes: 16 additions & 0 deletions src/common/str_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,22 @@ void StringBuilder::append_string(const char *str) {
*current_pos_ = '\0';
}

void StringBuilder::append_string_view(string_view_utf8 str) {

while (true) {
if (is_problem()) {
return;
}

char b = str.getbyte();
if (b == '\0') {
return;
}

append_char(b);
}
}

void StringBuilder::append_printf(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
Expand Down
3 changes: 3 additions & 0 deletions src/common/str_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <cstdint>
#include <algorithm>
#include <assert.h>
#include "../lang/string_view_utf8.hpp"

inline constexpr char CHAR_SPACE = ' ';
inline constexpr char CHAR_NBSP = '\xA0'; /// Non Breaking Space
Expand Down Expand Up @@ -384,6 +385,8 @@ class StringBuilder {

void append_string(const char *str);

void append_string_view(string_view_utf8 str);

/// Appends text to the builder, using vsnprintf under the hood.
void __attribute__((format(__printf__, 2, 3)))
append_printf(const char *fmt, ...);
Expand Down
2 changes: 2 additions & 0 deletions src/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ endif()
target_sources(
firmware
PRIVATE box_unfinished_selftest.cpp
custom_filament_tools.cpp
file_sort.cpp
fonts.cpp
frame_qr_layout.cpp
Expand Down Expand Up @@ -50,6 +51,7 @@ target_sources(
screen_menu_cancel_object.cpp
screen_menu_connect.cpp
screen_menu_control.cpp
screen_menu_custom_filament.cpp
screen_menu_eeprom.cpp
screen_menu_eeprom_diagnostics.cpp
screen_menu_enclosure.cpp
Expand Down
34 changes: 29 additions & 5 deletions src/gui/MItem_menus.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "MItem_menus.hpp"
#include "ScreenHandler.hpp"
#include "str_utils.hpp"
#include "custom_filament_tools.hpp"
#include <option/buddy_enable_connect.h>
#if BUDDY_ENABLE_CONNECT()
#include <connect/marlin_printer.hpp>
Expand Down Expand Up @@ -55,6 +57,7 @@
#include "screen_menu_factory_reset.hpp"
#include "screen_menu_error_test.hpp"
#include "screen_menu_input_shaper.hpp"
#include "screen_menu_custom_filament.hpp"

#if PRINTER_IS_PRUSA_MK3_5 || PRINTER_IS_PRUSA_MINI
#include <screen_menu_bed_level_correction.hpp>
Expand Down Expand Up @@ -411,16 +414,29 @@ MI_LOAD_SETTINGS::MI_LOAD_SETTINGS()
}

void MI_LOAD_SETTINGS::click(IWindowMenu & /*window_menu*/) {
// FIXME: Some error handling/reporting
// TODO: Loading other things than just network
if (netdev_load_ini_to_eeprom()) {

auto build_message = [](StringBuilder &msg_builder, string_view_utf8 name, bool ok) {
msg_builder.append_string_view(name);
msg_builder.append_string(": ");
msg_builder.append_string_view(ok ? _("Ok") : _("Failed"));
msg_builder.append_char('\n');
};
std::array<char, 150> msg;
StringBuilder msg_builder(msg);
msg_builder.append_string_view(_("\nLoading settings finished.\n\n"));

const bool network_settings_loaded = netdev_load_ini_to_eeprom();
if (network_settings_loaded) {
notify_reconfigure();
}
build_message(msg_builder, _("Network"), network_settings_loaded);

// FIXME: Error handling
#if BUDDY_ENABLE_CONNECT()
connect_client::MarlinPrinter::load_cfg_from_ini();
build_message(msg_builder, _("Connect"), connect_client::MarlinPrinter::load_cfg_from_ini());
#endif
build_message(msg_builder, _("Custom Filament"), custom_filament_tools::load_cfg_from_ini());

MsgBoxInfo(string_view_utf8::MakeRAM((const uint8_t *)msg.data()), Responses_Ok);
}

/**********************************************************************************************/
Expand Down Expand Up @@ -676,3 +692,11 @@ void MI_BED_LEVEL_CORRECTION::click(IWindowMenu & /*window_menu*/) {
Screens::Access()->Open(ScreenFactory::Screen<ScreenMenuBedLevelCorrection>);
}
#endif

MI_CUSTOM_FILAMENT::MI_CUSTOM_FILAMENT()
: IWindowMenuItem(_(label), nullptr, is_enabled_t::yes, is_hidden_t::no, expands_t::yes) {
}

void MI_CUSTOM_FILAMENT::click(IWindowMenu & /*window_menu*/) {
Screens::Access()->Open(ScreenFactory::Screen<ScreenMenuCustomFilament>);
}
10 changes: 10 additions & 0 deletions src/gui/MItem_menus.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -546,3 +546,13 @@ class MI_BED_LEVEL_CORRECTION : public IWindowMenuItem {
virtual void click(IWindowMenu &window_menu) override;
};
#endif

class MI_CUSTOM_FILAMENT : public IWindowMenuItem {
constexpr static const char *label = N_("Custom Filament");

public:
MI_CUSTOM_FILAMENT();

protected:
virtual void click(IWindowMenu &windowMenu) override;
};
36 changes: 36 additions & 0 deletions src/gui/MItem_tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "config.h"
#include "menu_spin_config.hpp"
#include "time_tools.hpp"
#include "custom_filament_tools.hpp"
#include "footer_eeprom.hpp"
#include "version.h"
#include "../../common/PersistentStorage.h"
Expand Down Expand Up @@ -863,3 +864,38 @@ void MI_COLD_PULL::click([[maybe_unused]] IWindowMenu &window_menu) {
marlin_client::gcode("M1702");
}
#endif

/*****************************************************************************/
// MI_CUSTOM_FILAMENT_SLOT
/*****************************************************************************/
MI_CUSTOM_FILAMENT_SLOT::MI_CUSTOM_FILAMENT_SLOT()
: WI_SWITCH_t<4>(static_cast<uint8_t>(custom_filament_tools::GetCurrentSlot()), _(label), nullptr, is_enabled_t::yes, is_hidden_t::no, _(custom_filament_tools::GetSlotName(0)), _(custom_filament_tools::GetSlotName(1)), _(custom_filament_tools::GetSlotName(2)), _(custom_filament_tools::GetSlotName(3))) {}

void MI_CUSTOM_FILAMENT_SLOT::OnChange([[maybe_unused]] size_t old_index) {
custom_filament_tools::SetCurrentSlot((int8_t)index);
Screens::Access()->WindowEvent(GUI_event_t::CHILD_CLICK, (void *)&index);
}

/*****************************************************************************/
// MI_CUSTOM_FILAMENT_NOZZLE_TEMP
MI_CUSTOM_FILAMENT_NOZZLE_TEMP::MI_CUSTOM_FILAMENT_NOZZLE_TEMP()
: WiSpinInt(custom_filament_tools::GetSlotTemp(custom_filament_tools::CustomFilamentTemperatures::nozzle), SpinCnf::nozzle, _(label), nullptr, is_enabled_t::yes, is_hidden_t::no) {}
void MI_CUSTOM_FILAMENT_NOZZLE_TEMP::OnClick() {
custom_filament_tools::SetSlotTemp(custom_filament_tools::CustomFilamentTemperatures::nozzle, GetVal());
}

/*****************************************************************************/
// MI_CUSTOM_FILAMENT_NOZZLE_PREHEAT_TEMP
MI_CUSTOM_FILAMENT_NOZZLE_PREHEAT_TEMP::MI_CUSTOM_FILAMENT_NOZZLE_PREHEAT_TEMP()
: WiSpinInt(custom_filament_tools::GetSlotTemp(custom_filament_tools::CustomFilamentTemperatures::nozzle_preheat), SpinCnf::nozzle, _(label), nullptr, is_enabled_t::yes, is_hidden_t::no) {}
void MI_CUSTOM_FILAMENT_NOZZLE_PREHEAT_TEMP::OnClick() {
custom_filament_tools::SetSlotTemp(custom_filament_tools::CustomFilamentTemperatures::nozzle_preheat, GetVal());
}

/*****************************************************************************/
// MI_CUSTOM_FILAMENT_HEATBED_TEMP
MI_CUSTOM_FILAMENT_HEATBED_TEMP::MI_CUSTOM_FILAMENT_HEATBED_TEMP()
: WiSpinInt(custom_filament_tools::GetSlotTemp(custom_filament_tools::CustomFilamentTemperatures::heatbed), SpinCnf::bed, _(label), nullptr, is_enabled_t::yes, is_hidden_t::no) {}
void MI_CUSTOM_FILAMENT_HEATBED_TEMP::OnClick() {
custom_filament_tools::SetSlotTemp(custom_filament_tools::CustomFilamentTemperatures::heatbed, GetVal());
}
Loading

0 comments on commit 877110a

Please sign in to comment.