Skip to content

gcode: Add serial information for M862.x for P and Q parameters#4777

Open
bkerler wants to merge 5 commits intoprusa3d:masterfrom
bkerler:fix_m862_print
Open

gcode: Add serial information for M862.x for P and Q parameters#4777
bkerler wants to merge 5 commits intoprusa3d:masterfrom
bkerler:fix_m862_print

Conversation

@bkerler
Copy link

@bkerler bkerler commented Aug 25, 2025

This partly solves #4157.

  1. When being run remotely, the M862.x P commands should return a response whether it is being compatible or not.
  2. M862.3 P "MK3S" and M862.3 P"MK3S" both should work, but didn't. This behaviour was fixed as well.

@bkerler bkerler marked this pull request as draft August 25, 2025 23:43
@bkerler bkerler changed the title gcode: Add serial information for M862.2 and M862.3 gcode: Add serial information for M862.x Aug 26, 2025
@bkerler bkerler marked this pull request as ready for review August 26, 2025 14:50
@bkerler bkerler changed the title gcode: Add serial information for M862.x gcode: Add serial information for M862.x for P and Q parameters Aug 26, 2025
@bkerler bkerler force-pushed the fix_m862_print branch 2 times, most recently from 26a748c to cc2ffeb Compare August 26, 2025 15:39
@bkerler bkerler marked this pull request as draft August 26, 2025 15:40
@bkerler bkerler marked this pull request as ready for review August 26, 2025 17:03
Copy link
Contributor

@CZDanol CZDanol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still not a full review, sorry, not much time and this PR is on the bigger side.

Besides from nitpick/comments in the review, there is also a higher-level problem that we're duplicating here what GCodeInfo does. And GCodeInfo does it in a completely different way, so we could end up with a situation where the gcode outputs are telling us one thing and the GCodeInfo is reporting something else.

The way things are implemented in GCodeInfo currently is terrible, because it basically parses the gcodes "by hand". But to allow this extension of the gcodes, we might first need to clean up the GCodeInfo to make things consistent (which would be a big task).

I am not sure.

if (compatibility.is_compatible) {
SERIAL_ECHO("Compatibility mode: ");
if (compatibility.mk3_compatibility_mode) {
SERIAL_ECHOLN("MK3");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like by putting this on separate lines, these will be rather hard to parse by a machine

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, changed that.

return;
}

if (p.option<bool>('Q').value_or(false)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick/tip: == true would work as well (but value_or is also fine)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done :)


if (parser.boolval('P')) {
setup_gcode_compatibility(PrinterModelInfo::from_gcode_check_code(parser.value_int()));
if (const auto gcode = p.option<int>('P').value_or(0)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, value_or is not fine. Technically speaking, 0 could also be a valid printer model. The point of the parser returning std::optional is to avoid these double meanings.

if (const auto gcode = p.option<int>('P')) {
print_compatibility(setup_gcode_compatibility(PrinterModelInfo::from_gcode_check_code(*gcode)));
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed that as well, good point.


setup_gcode_compatibility(PrinterModelInfo::from_id_str(std::string_view(arg, arg_end)));
std::array<char, 64> id_str;
if (const auto opt = p.option<std::string_view>('P', id_str)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good usage here 👍

setup_gcode_compatibility(PrinterModelInfo::from_id_str(std::string_view(arg, arg_end)));
std::array<char, 64> id_str;
if (const auto opt = p.option<std::string_view>('P', id_str)) {
print_compatibility(setup_gcode_compatibility(PrinterModelInfo::from_id_str(opt->data())));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::string_view does not guarantee null termination, you cannot just pass the data from it.

from_id_str already takes std::string_view, so there is no need to take the const char* pointer from the view and cast it back to std::string_view. You can just do print_compatibility(setup_gcode_compatibility(PrinterModelInfo::from_id_str(*opt))));

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

found = true;
break;
}
#if ENABLED(PRUSA_MMU2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, sorry, this is way too much code duplication. This MMU3/Phase stepping conditioning should all be implemented on a single place.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed for now.

bool found = false;
SERIAL_ECHOPAIR("\"", opt->data(), "\"");
for (auto &feature : GCodeInfo::supported_features) {
if (opt->find(feature) != std::string_view::npos) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Find? Find is finding a substring. The match should either be 1:1 or there should be some clearly documented separators.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed for now.

}

if (const std::optional<double> requested_nozzle_diameter = p.option<float>('P')) {
if (requested_nozzle_diameter.value() < 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be auto-checked by passing a min value to p.option. Also, what is the point of even checking this? If the user enters a negative value, he would get a mismatch anyway.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, you're right, negative testing doesn't make sense as we force it to be bigger than 0.1

SERIAL_EOL();
}

if (const std::optional<int> req_gcode_level = p.option<int>('P')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: auto would be nicer

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree


if (const std::optional<int> req_gcode_level = p.option<int>('P')) {
SERIAL_ECHO("Gcode level ");
if (req_gcode_level == (int)GCodeInfo::gcode_level) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: Why cast to int here? Would it be better to take the P option as the same type as gcode_level?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally right. Changed that.

@bkerler bkerler force-pushed the fix_m862_print branch 2 times, most recently from 39b9106 to f7583f2 Compare September 9, 2025 09:54
@bkerler bkerler requested a review from CZDanol September 9, 2025 09:54
@bkerler
Copy link
Author

bkerler commented Sep 9, 2025

I think you are right regarding the redesign and also not happy about the way the mmu3 and feature output/check is happening in M862_6. In order to allow the other fixes to happen, I decided that M862_6 isn't put in this PR, but instead in a separate PR (either with proper changes or after full gcodeinfo patches happened).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants