New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serial wait #1922

Merged
merged 7 commits into from May 11, 2015

Conversation

Projects
None yet
6 participants
@Wurstnase
Contributor

Wurstnase commented Apr 16, 2015

backup for a swallowed 'ok' on a serial connection

Show outdated Hide outdated Marlin/Marlin_main.cpp
@@ -263,6 +263,7 @@ static millis_t max_inactive_time = 0;
static millis_t stepper_inactive_time = DEFAULT_STEPPER_DEACTIVE_TIME * 1000L;
millis_t print_job_start_ms = 0; ///< Print job start time
millis_t print_job_stop_ms = 0; ///< Print job stop time
static millis_t last_command_time = 0;

This comment has been minimized.

@thinkyhead

thinkyhead Apr 16, 2015

Member

If this is only going to be used in get_command, you can put this static inside that function.

@thinkyhead

thinkyhead Apr 16, 2015

Member

If this is only going to be used in get_command, you can put this static inside that function.

This comment has been minimized.

@nophead

nophead Apr 16, 2015

Contributor

Does this endless print wait every second when there is no serial activity?
There was a PR to do this with OK that was rejected because the host should
time out waiting for OK and send the command again.

On 16 April 2015 at 14:59, Scott Lahteine notifications@github.com wrote:

In Marlin/Marlin_main.cpp
#1922 (comment):

@@ -263,6 +263,7 @@ static millis_t max_inactive_time = 0;
static millis_t stepper_inactive_time = DEFAULT_STEPPER_DEACTIVE_TIME * 1000L;
millis_t print_job_start_ms = 0; ///< Print job start time
millis_t print_job_stop_ms = 0; ///< Print job stop time
+static millis_t last_command_time = 0;

If this is only going to be used in get_command, you can put this static
inside that function.

Reply to this email directly or view it on GitHub
https://github.com/MarlinFirmware/Marlin/pull/1922/files#r28511493.

@nophead

nophead Apr 16, 2015

Contributor

Does this endless print wait every second when there is no serial activity?
There was a PR to do this with OK that was rejected because the host should
time out waiting for OK and send the command again.

On 16 April 2015 at 14:59, Scott Lahteine notifications@github.com wrote:

In Marlin/Marlin_main.cpp
#1922 (comment):

@@ -263,6 +263,7 @@ static millis_t max_inactive_time = 0;
static millis_t stepper_inactive_time = DEFAULT_STEPPER_DEACTIVE_TIME * 1000L;
millis_t print_job_start_ms = 0; ///< Print job start time
millis_t print_job_stop_ms = 0; ///< Print job stop time
+static millis_t last_command_time = 0;

If this is only going to be used in get_command, you can put this static
inside that function.

Reply to this email directly or view it on GitHub
https://github.com/MarlinFirmware/Marlin/pull/1922/files#r28511493.

This comment has been minimized.

@Wurstnase

Wurstnase Apr 16, 2015

Contributor

It's not needed to send the command again because it's already send. Else the firmware should send a resend. The communication can fail because of different length of usb-plugs or other things.

When the firmware sends a wait, it only communicate that it has nothing to do.

@Wurstnase

Wurstnase Apr 16, 2015

Contributor

It's not needed to send the command again because it's already send. Else the firmware should send a resend. The communication can fail because of different length of usb-plugs or other things.

When the firmware sends a wait, it only communicate that it has nothing to do.

@nophead

This comment has been minimized.

Show comment
Hide comment
@nophead

nophead Apr 16, 2015

Contributor

It will be annoying that the serial log gets filled with wait, especially as I never get any serial errors, so don't need a retry mechanism.

Also the existing retry mechanism works as the host repeats the last command since it doesn't know if the firmware got it or not. If it did it will reply that it is expecting the next line and the host can then move on. If it didn't it will reply OK and the host moves on. I.e. there is already an established protocol retry mechanism. It is a master - slave protocol and in such protocols slaves only reply when spoken to.

Contributor

nophead commented Apr 16, 2015

It will be annoying that the serial log gets filled with wait, especially as I never get any serial errors, so don't need a retry mechanism.

Also the existing retry mechanism works as the host repeats the last command since it doesn't know if the firmware got it or not. If it did it will reply that it is expecting the next line and the host can then move on. If it didn't it will reply OK and the host moves on. I.e. there is already an established protocol retry mechanism. It is a master - slave protocol and in such protocols slaves only reply when spoken to.

@thinkyhead

This comment has been minimized.

Show comment
Hide comment
@thinkyhead

thinkyhead Apr 16, 2015

Member

Perhaps you want to print "wait" only once, then only say it once again after some activity has happened.

Member

thinkyhead commented Apr 16, 2015

Perhaps you want to print "wait" only once, then only say it once again after some activity has happened.

@Wurstnase

This comment has been minimized.

Show comment
Hide comment
@Wurstnase

Wurstnase Apr 16, 2015

Contributor

I have a lot oft issues with serial connections. Sometimes the OK isn't send and marlin did nothing and wait forever.

And the wait is only send when there is no serial activity and there is nothing in the buffer.

Contributor

Wurstnase commented Apr 16, 2015

I have a lot oft issues with serial connections. Sometimes the OK isn't send and marlin did nothing and wait forever.

And the wait is only send when there is no serial activity and there is nothing in the buffer.

@Wurstnase

This comment has been minimized.

Show comment
Hide comment
@Wurstnase

Wurstnase Apr 16, 2015

Contributor

btw, Pronterface, RepetierHost and when I remember correctly Octoprint filter the 'wait' in standard-config.

Contributor

Wurstnase commented Apr 16, 2015

btw, Pronterface, RepetierHost and when I remember correctly Octoprint filter the 'wait' in standard-config.

@nophead

This comment has been minimized.

Show comment
Hide comment
@nophead

nophead Apr 16, 2015

Contributor

If the OK is lost the host should timeout waiting for it and resend. It is
correct that Marlin sits and waits forever, it is the slave. You seem to
have a broken host if the comms stops.

On 16 April 2015 at 17:19, Wurstnase notifications@github.com wrote:

btw, Pronterface, RepetierHost and when I remember correctly Octoprint
filter the 'wait' in standard-config.

Reply to this email directly or view it on GitHub
#1922 (comment)
.

Contributor

nophead commented Apr 16, 2015

If the OK is lost the host should timeout waiting for it and resend. It is
correct that Marlin sits and waits forever, it is the slave. You seem to
have a broken host if the comms stops.

On 16 April 2015 at 17:19, Wurstnase notifications@github.com wrote:

btw, Pronterface, RepetierHost and when I remember correctly Octoprint
filter the 'wait' in standard-config.

Reply to this email directly or view it on GitHub
#1922 (comment)
.

@Wurstnase

This comment has been minimized.

Show comment
Hide comment
@Wurstnase

Wurstnase Apr 16, 2015

Contributor

Pronterface, Octoprint and RepetierHost are all broken then.

Contributor

Wurstnase commented Apr 16, 2015

Pronterface, Octoprint and RepetierHost are all broken then.

@daid

This comment has been minimized.

Show comment
Hide comment
@daid

daid Apr 16, 2015

Contributor

Yes they are.

Cura does do a resend when it detects it does not get data in a timely fashion. Adding a message from the firmware won't do shit, as the hosts still won't act on it.

Contributor

daid commented Apr 16, 2015

Yes they are.

Cura does do a resend when it detects it does not get data in a timely fashion. Adding a message from the firmware won't do shit, as the hosts still won't act on it.

@nophead

This comment has been minimized.

Show comment
Hide comment
@nophead

nophead Apr 16, 2015

Contributor

My understanding is Octoprint does do timeouts and resends.

On 16 April 2015 at 18:47, daid notifications@github.com wrote:

Yes they are.

Cura does do a resend when it detects it does not get data in a timely
fashion. Adding a message from the firmware won't do shit, as the hosts
still won't act on it.

Reply to this email directly or view it on GitHub
#1922 (comment)
.

Contributor

nophead commented Apr 16, 2015

My understanding is Octoprint does do timeouts and resends.

On 16 April 2015 at 18:47, daid notifications@github.com wrote:

Yes they are.

Cura does do a resend when it detects it does not get data in a timely
fashion. Adding a message from the firmware won't do shit, as the hosts
still won't act on it.

Reply to this email directly or view it on GitHub
#1922 (comment)
.

@Wurstnase

This comment has been minimized.

Show comment
Hide comment
@Wurstnase

Wurstnase Apr 17, 2015

Contributor

Can't say anything about Cura. Don't see any Host which could help with debugging.

Anyway, I don't see any good argument why a slave shouldn't say, that it has nothing to do. It doesn't take any decision in that case.

How long will the hosts wait for the ok? Is there any configuration possible?

Contributor

Wurstnase commented Apr 17, 2015

Can't say anything about Cura. Don't see any Host which could help with debugging.

Anyway, I don't see any good argument why a slave shouldn't say, that it has nothing to do. It doesn't take any decision in that case.

How long will the hosts wait for the ok? Is there any configuration possible?

@nophead

This comment has been minimized.

Show comment
Hide comment
@nophead

nophead Apr 17, 2015

Contributor

It is a configurable setting on OctoPrint.

Contributor

nophead commented Apr 17, 2015

It is a configurable setting on OctoPrint.

@daid

This comment has been minimized.

Show comment
Hide comment
@daid

daid Apr 17, 2015

Contributor

It's a fixed timeout in Cura (something like 30 seconds or so), it's just for when everything else went wrong, and to reboot the communication instead of having your print fail. It hardly ever happens in Cura, but it's better to be safe then sorry.

Contributor

daid commented Apr 17, 2015

It's a fixed timeout in Cura (something like 30 seconds or so), it's just for when everything else went wrong, and to reboot the communication instead of having your print fail. It hardly ever happens in Cura, but it's better to be safe then sorry.

@Wurstnase

This comment has been minimized.

Show comment
Hide comment
@Wurstnase

Wurstnase Apr 17, 2015

Contributor

So, in this solution here, the firmware fires a wait when the buffer goes empty. In my tests this can happen on a bad usb cable every hour once. In that case (tested with RepetierHost) the print only have a pause of 1 second and after that it has no problem anymore. So I think it's a workable solution.

The next part will be a 'ok' followed by the last line number. So the host can see if there was just a missing ok over the serial connection and can continue sending commands. But this will be a new pull request.

Contributor

Wurstnase commented Apr 17, 2015

So, in this solution here, the firmware fires a wait when the buffer goes empty. In my tests this can happen on a bad usb cable every hour once. In that case (tested with RepetierHost) the print only have a pause of 1 second and after that it has no problem anymore. So I think it's a workable solution.

The next part will be a 'ok' followed by the last line number. So the host can see if there was just a missing ok over the serial connection and can continue sending commands. But this will be a new pull request.

@nophead

This comment has been minimized.

Show comment
Hide comment
@nophead

nophead Apr 17, 2015

Contributor

This is completely wrong. If you want a maximum pause of one second the host timeout should be set to one second and then it just works. I.e. the protocol already has a standard master slave retry mechanism.

As soon as you break the master slave relationship you have race conditions. The slave might send wait, or OK just has the host happens to send a command.

Contributor

nophead commented Apr 17, 2015

This is completely wrong. If you want a maximum pause of one second the host timeout should be set to one second and then it just works. I.e. the protocol already has a standard master slave retry mechanism.

As soon as you break the master slave relationship you have race conditions. The slave might send wait, or OK just has the host happens to send a command.

@daid

This comment has been minimized.

Show comment
Hide comment
@daid

daid Apr 17, 2015

Contributor

Note, in something I'm working on, I added "N[line number]" and "P[planner buffer space]" to every OK. This really helps on the host side, as you have much more information to work with. You also know for sure your commands will almost never block, as you only send a G0/G1 command when there is room in the planner buffer.

Missed OKs will be fixed by the N numbering, as well as missed newlines.

Contributor

daid commented Apr 17, 2015

Note, in something I'm working on, I added "N[line number]" and "P[planner buffer space]" to every OK. This really helps on the host side, as you have much more information to work with. You also know for sure your commands will almost never block, as you only send a G0/G1 command when there is room in the planner buffer.

Missed OKs will be fixed by the N numbering, as well as missed newlines.

@Wurstnase

This comment has been minimized.

Show comment
Hide comment
@Wurstnase

Wurstnase Apr 17, 2015

Contributor

There will only be a wait if and only if there is nothing in the serial buffer and nothing in the command buffer. So I don't see any race conditions.

daid, you are right. This is what I've described one post before.

Contributor

Wurstnase commented Apr 17, 2015

There will only be a wait if and only if there is nothing in the serial buffer and nothing in the command buffer. So I don't see any race conditions.

daid, you are right. This is what I've described one post before.

@daid

This comment has been minimized.

Show comment
Hide comment
@daid

daid Apr 17, 2015

Contributor

Yes, and I tell you, it works wonders. Also because I have the communication line open all the time.

For example, I also added an M401, which empties the planner buffer, and throwing away the currently planned block. Which allows for a quick abort, instead of the abort still finishing the 16 moves in the buffer. Position is lost, so homing is needed afterwards, but no issues with hotends cooling down because the print is canceled, but the printer head still printing long moves.

Contributor

daid commented Apr 17, 2015

Yes, and I tell you, it works wonders. Also because I have the communication line open all the time.

For example, I also added an M401, which empties the planner buffer, and throwing away the currently planned block. Which allows for a quick abort, instead of the abort still finishing the 16 moves in the buffer. Position is lost, so homing is needed afterwards, but no issues with hotends cooling down because the print is canceled, but the printer head still printing long moves.

@thinkyhead

This comment has been minimized.

Show comment
Hide comment
@thinkyhead

thinkyhead Apr 18, 2015

Member

M401 👍

Member

thinkyhead commented Apr 18, 2015

M401 👍

@thinkyhead

This comment has been minimized.

Show comment
Hide comment
@thinkyhead

thinkyhead Apr 19, 2015

Member

@daid #1941

M401 was taken, so it's changed to M410. But maybe other codes should be changed instead. M401 (Deploy Servo Z Probe) and M402 (Stow Servo Z Probe) could be combined as a single command, M402 S1 and M402 S0 instead.

Member

thinkyhead commented Apr 19, 2015

@daid #1941

M401 was taken, so it's changed to M410. But maybe other codes should be changed instead. M401 (Deploy Servo Z Probe) and M402 (Stow Servo Z Probe) could be combined as a single command, M402 S1 and M402 S0 instead.

@daid

This comment has been minimized.

Show comment
Hide comment
@daid

daid Apr 19, 2015

Contributor

M410 is also fine, the list is a mess anyhow. I recommend against changing codes, as that will cause compatibility issues, which is highly annoying for users.

Contributor

daid commented Apr 19, 2015

M410 is also fine, the list is a mess anyhow. I recommend against changing codes, as that will cause compatibility issues, which is highly annoying for users.

@Wurstnase

This comment has been minimized.

Show comment
Hide comment
@Wurstnase

Wurstnase Apr 20, 2015

Contributor

I've implemented the idea from @daid with 'ok N_xxx_ P_x_'
It's not tested atm.

Contributor

Wurstnase commented Apr 20, 2015

I've implemented the idea from @daid with 'ok N_xxx_ P_x_'
It's not tested atm.

@Wurstnase

This comment has been minimized.

Show comment
Hide comment
@Wurstnase

Wurstnase May 8, 2015

Contributor

@daid @kliment @foosel
I've took a look inside RepetierCode. Just for compare:
He send the 'wait' like this code. It's really the same.

But the last line-number should be discussed again. RepetierFirmware sends a 'ok 123'. The first lines of the new 'standard'-protocol said something of 'ok N123'. Should we go in different ways? Should we use the same syntax?

Contributor

Wurstnase commented May 8, 2015

@daid @kliment @foosel
I've took a look inside RepetierCode. Just for compare:
He send the 'wait' like this code. It's really the same.

But the last line-number should be discussed again. RepetierFirmware sends a 'ok 123'. The first lines of the new 'standard'-protocol said something of 'ok N123'. Should we go in different ways? Should we use the same syntax?

@foosel

This comment has been minimized.

Show comment
Hide comment
@foosel

foosel May 8, 2015

Contributor

From a personal point of view I like the "ok N..." part better, especially together with the planner buffer state. Allows a clear distinction both for human an computer which is which, makes parsing easier. I wasn't aware that Repetier actually did send line numbers already, interesting to know.

I love the M410. I already had users complain about them having to wait so long for the buffer to empty on a cancel and this will really help in the long term, especially since OctoPrint now got configurable code snippets for events such as print start, cancel, success etc.

FWIW, I just pushed a commit to OctoPrint that reintroduces the fast recovery on wait while printing. That used to be in there already for quite a bit (due to Repetier supporting that) but fell victim to a recent refactoring I did in the communication code.

Contributor

foosel commented May 8, 2015

From a personal point of view I like the "ok N..." part better, especially together with the planner buffer state. Allows a clear distinction both for human an computer which is which, makes parsing easier. I wasn't aware that Repetier actually did send line numbers already, interesting to know.

I love the M410. I already had users complain about them having to wait so long for the buffer to empty on a cancel and this will really help in the long term, especially since OctoPrint now got configurable code snippets for events such as print start, cancel, success etc.

FWIW, I just pushed a commit to OctoPrint that reintroduces the fast recovery on wait while printing. That used to be in there already for quite a bit (due to Repetier supporting that) but fell victim to a recent refactoring I did in the communication code.

@Wurstnase

This comment has been minimized.

Show comment
Hide comment
@Wurstnase

Wurstnase May 8, 2015

Contributor

How should the plan buffer state work? Should it return the remaining buffer or the buffer state?

Contributor

Wurstnase commented May 8, 2015

How should the plan buffer state work? Should it return the remaining buffer or the buffer state?

@foosel

This comment has been minimized.

Show comment
Hide comment
@foosel

foosel May 8, 2015

Contributor
Contributor

foosel commented May 8, 2015

@Wurstnase

This comment has been minimized.

Show comment
Hide comment
@Wurstnase

Wurstnase May 8, 2015

Contributor

Ok, i will rework this PR this weekend.

Contributor

Wurstnase commented May 8, 2015

Ok, i will rework this PR this weekend.

Wurstnase added some commits May 8, 2015

advanced 'ok'
ok N(linenumber) P(bufferremaining)
the host can use this to send the data much faster.

Some pseudo code:
If (bufferremaining > 0)  send command
## as long there is free buffer send command

Also
if (linenumber > lastsend - bufferremaining) send command
## as long last linenumber received is bigger than lastsend (host) - last bufferremaining received
@Wurstnase

This comment has been minimized.

Show comment
Hide comment
@Wurstnase

Wurstnase May 8, 2015

Contributor

there it is. keep in mind that you switch off ping-pong. :) I forget this first while testing.

Contributor

Wurstnase commented May 8, 2015

there it is. keep in mind that you switch off ping-pong. :) I forget this first while testing.

Show outdated Hide outdated Marlin/Marlin_main.cpp
SERIAL_PROTOCOLPGM(" N"); SERIAL_PROTOCOL(gcode_LastN);
SERIAL_PROTOCOLPGM(" P"); SERIAL_PROTOCOL(BUFSIZE - commands_in_queue);
#endif
SERIAL_PROTOCOLLNPGM("");

This comment has been minimized.

@thinkyhead

thinkyhead May 11, 2015

Member

SERIAL_EOL is a smaller method to do SERIAL_PROTOCOLLNPGM("")

@thinkyhead

thinkyhead May 11, 2015

Member

SERIAL_EOL is a smaller method to do SERIAL_PROTOCOLLNPGM("")

@thinkyhead

This comment has been minimized.

Show comment
Hide comment
@thinkyhead

thinkyhead May 11, 2015

Member

@Wurstnase Since this is something of a bug-fix for some people, and since it's disabled by default, I'm inclined to merge it. Just be sure to propagate any changes you make to Configuration_adv.h to all the other Configuration_adv.h files in the repo. (We'll be reducing these down to a minimum pretty soon, I think!) And once it's ready to go, I will merge it. Then we'll be able to recommend this setting when people have relevant problems.

Member

thinkyhead commented May 11, 2015

@Wurstnase Since this is something of a bug-fix for some people, and since it's disabled by default, I'm inclined to merge it. Just be sure to propagate any changes you make to Configuration_adv.h to all the other Configuration_adv.h files in the repo. (We'll be reducing these down to a minimum pretty soon, I think!) And once it's ready to go, I will merge it. Then we'll be able to recommend this setting when people have relevant problems.

@Wurstnase

This comment has been minimized.

Show comment
Hide comment
@Wurstnase

Wurstnase May 11, 2015

Contributor

@thinkyhead ready to merge

Contributor

Wurstnase commented May 11, 2015

@thinkyhead ready to merge

@@ -374,7 +374,15 @@ const unsigned int dropsegments=5; //everything with less than this number of st
//The ASCII buffer for receiving from the serial:
#define MAX_CMD_SIZE 96
#define BUFSIZE 5
#define BUFSIZE 4

This comment has been minimized.

@thinkyhead

thinkyhead May 11, 2015

Member

I'm not sure why Witbox and Hephestos have a larger number here, but this seems fine to me.

@thinkyhead

thinkyhead May 11, 2015

Member

I'm not sure why Witbox and Hephestos have a larger number here, but this seems fine to me.

thinkyhead added a commit that referenced this pull request May 11, 2015

@thinkyhead thinkyhead merged commit 8a0dc4d into MarlinFirmware:Development May 11, 2015

@ivan-galvez

This comment has been minimized.

Show comment
Hide comment
@ivan-galvez

ivan-galvez May 11, 2015

Contributor

On Witbox and Hephestos printers, we have detected situations, such as the filament change, triggered from the screen menu, in which the buffer's size needs to be 5.
In this particular case, a buffer size of 4 will avoid the printing to continue automatically, so please do not change that parameter just for the sake of it. Specially mixing that change within a different one.

Contributor

ivan-galvez commented May 11, 2015

On Witbox and Hephestos printers, we have detected situations, such as the filament change, triggered from the screen menu, in which the buffer's size needs to be 5.
In this particular case, a buffer size of 4 will avoid the printing to continue automatically, so please do not change that parameter just for the sake of it. Specially mixing that change within a different one.

@Wurstnase

This comment has been minimized.

Show comment
Hide comment
@Wurstnase

Wurstnase May 11, 2015

Contributor

Right, I don't do this just for the sake. There were no comment why this was made. Also this should be an Issue because this can also happen with other printers. Why should this patch only fix Witbox and Hephestos?
If there is a buffer-issue we should fix this, and not only increase the buffer size.

Contributor

Wurstnase commented May 11, 2015

Right, I don't do this just for the sake. There were no comment why this was made. Also this should be an Issue because this can also happen with other printers. Why should this patch only fix Witbox and Hephestos?
If there is a buffer-issue we should fix this, and not only increase the buffer size.

@ivan-galvez

This comment has been minimized.

Show comment
Hide comment
@ivan-galvez

ivan-galvez May 11, 2015

Contributor

Indeed it might have better documentation but think that these configuration files usually come from the printer manufacturer's own fork of Marlin, as it's in our case, where they are properly tested against several scenarios.
Then, applying these particular refinements or tweaks to other printers or as a generic recipe for everyone out there without proper testing can't be easily justified.
And regarding buffer issues, yes, there are, and we have several changes in our fork related to them but they are not yet properly "upstreamed" (working on it).

Contributor

ivan-galvez commented May 11, 2015

Indeed it might have better documentation but think that these configuration files usually come from the printer manufacturer's own fork of Marlin, as it's in our case, where they are properly tested against several scenarios.
Then, applying these particular refinements or tweaks to other printers or as a generic recipe for everyone out there without proper testing can't be easily justified.
And regarding buffer issues, yes, there are, and we have several changes in our fork related to them but they are not yet properly "upstreamed" (working on it).

@daid

This comment has been minimized.

Show comment
Hide comment
@daid

daid May 11, 2015

Contributor

Uhm, the P right now is not implemented as I suggested it.

It now shows the room in the command buffer (which is also nice to know). But what's really interesting to know, is the amount of space in the planner buffer. As when the planner buffer is full, a G0/G1 request will block. And blocking the communication is causing most of the issues actually, as that means long timeouts.

See my messy code at:
https://github.com/Ultimaker/Ultimaker2Marlin/blob/lite/Marlin/Marlin.h#L59
Which uses the P for the amount of room in the planner buffer.

Contributor

daid commented May 11, 2015

Uhm, the P right now is not implemented as I suggested it.

It now shows the room in the command buffer (which is also nice to know). But what's really interesting to know, is the amount of space in the planner buffer. As when the planner buffer is full, a G0/G1 request will block. And blocking the communication is causing most of the issues actually, as that means long timeouts.

See my messy code at:
https://github.com/Ultimaker/Ultimaker2Marlin/blob/lite/Marlin/Marlin.h#L59
Which uses the P for the amount of room in the planner buffer.

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