MarlinFirmware / Marlin

Marlin is an optimized firmware for RepRap 3D printers based on the Arduino platform. Many commercial 3D printers come with Marlin installed. Check with your vendor if you need source code for your specific machine.
https://marlinfw.org
GNU General Public License v3.0
16.16k stars 19.21k forks source link

[FR] USB serial & successive gcode reception #20367

Closed EYHJ59 closed 3 years ago

EYHJ59 commented 3 years ago

Bug Description

I am making some program as like simple octoprint. If command buffer is empty, it sends Marlin gcode in every 250ms until command buffer is full . At first steps, it want send gcode until command buffer has 5 gcode.

C>> : N1 M82 56 C>> : N2 G21 56 C>> : N3 G90 51 C>> : N4 M82 61 C>> : N5 M104 S200 66 <<M: ok N1 P127 B31 C>> : N6 M140 S60 117 <<M: ok N2 P127 B31 ................

Problem & Steps to Reproduce

  1. Marlin make 'checksum' error. After error, Marlin cannot recover. Marlin cannot clear buffer(usb serial buffer)
  2. As I know, when some data is received, get_serial_commands() function bring data(gcode) and save it to command buffer. But if Marlin receive successive 5 gcode, time duration to bring data is longer because serial_data_available() returns false continuously.
  3. So command buffer's number is not reduced.
  4. (I think) Because of longer time duraion, planner buffer doesn't be full and motor doesn't move smooth.

Configuration Files

Required: Include a ZIP file containing Configuration.h and Configuration_adv.h.

  1. board : BTT SKR pro board
  2. configuration.h,

    define SERIAL_PORT -1

    //#define SERIAL_PORT_2 1

    define BAUDRATE 1000000

    configuration_adv.h,

    define ADVANCED_OK

    define BLOCK_BUFFER_SIZE 128 //16

    define BUFSIZE 32 //4

    define TX_BUFFER_SIZE 32 //0

If you've made any other modifications describe them in detail here.

Steps to Reproduce

Expected behavior:

If command buffer is full with data, parsing more gcode, planner buffer will full with data. I think this makes motor move more smooth.

Actual behavior:

Marlin make 'checksum' error and cannot recover. And motor move makes worse.

I want to know USB serial(USB CDC) is not good for my use or not. As I know, every 3D printer don't use USB serial port. Why do not they use USB serial?

My test result says that Marlin can handle 3 successive gcode. Over 3, Marlin makes problem. Why?

Additional Information

thisiskeithb commented 3 years ago

Have you looked into M808 - Repeat Marker?

EYHJ59 commented 3 years ago

What is M808?

thisiskeithb commented 3 years ago

Click the link.

EYHJ59 commented 3 years ago

Marlin has no M808 and I'm testing USB serial print not SD print.

thisiskeithb commented 3 years ago

Marlin has no M808 and I'm testing USB serial print not SD print.

You'd need to run the latest bugfix-2.0.x, but yes, it's for SD printing.

This seems like something that would be handled on the host side then.

EYHJ59 commented 3 years ago

M808 run 1 gcode but 5 times. -> 1 command buffer and (maybe) 5 planner buffer My problem is Marlin receive 5 gcodes -> Marlin have to move it to command buffer. But Marlin doesn't do it. I think when received data number is over some amount, Marlin have difficulty moving data(gcode) to command buffer from usb serial buffer. -> 5 usb serial buffers but only 1 command buffer So M808 and my case are different.

Thank you for your reply.

EYHJ59 commented 3 years ago

I think serial_data_available() function return 0 even if serial buffer have data.(ex. 5 gcode) I don't know why this function return 0.

DerAndere1 commented 3 years ago

Have a look at the source code of the open source G-code senders like Printrun (https://github.com/kliment/Printrun ) or mecode (https://github.com/jminardi/mecode). Both work well with Marlin.

X-Ryl669 commented 3 years ago

The issue you're describing is logical and there is nothing Marlin could do to fix it. You're storing more data than what Marlin could handle in its own buffers (there's only 4 pending buffers in Marlin). There is no code to deal with hardware flow, or XON/XOFF, to limit/stop the host from submitting data. So the buffer overflow must be dealt by software.

The host software should have some limit and should not submit too many new commands until it has received the ok answer from previous command.

Right now, a possible mitigation would be to reject GCode command when there are too much (by replying an error instantly), but this would mean reserving one of the 4 slots for this. This would break many of the GCode sending software that are not written to parse such error coming asynchronously.

What's the point anyway ? Marlin will not go faster than it can, so if you submitted 400 GCode command at once and Marlin was able to accept them, you'd still have to wait for the 400 commands to happen. Having more than a buffer is useful to prevent waiting for serial processing, but more than 3 is somehow useless (one is being process, the second one is currently receiving, and then you swap both).

It's much better to just fix the host software that's usually not resource constrained. If you are too limited by the serial bandwidth, you might want to check MeatPack stuff. It might work.

EYHJ59 commented 3 years ago

Thank you for your reply. Increasing BUFSIZE(command buffer size) is not solution to resolve it?

X-Ryl669 commented 3 years ago

It might adjust with a host software having exactly N pending buffers, but it's not a solution if the host does not have the logic to throttle the serial message. You'd use a host software that's not submitting too much buffers, like those in @DerAndere1 answer or Octoprint for example...

EYHJ59 commented 3 years ago

Thank you for your kindness. I think the root cause is that serial data(host -> Marlin) is not transferred to command buffer quickly. You mean this is Marlin's limitation and host software have to use ping pong protocol. Am I right? If so, when very small segment(size is same as MIN_STEPS_PER_SEGMENT) is sent to Marlin successively, Marlin's motor movement is not smooth. At that time, DEFAULT_MINSEGMENTTIME's adjustment is only solution?

Thank you in advance.

X-Ryl669 commented 3 years ago

I think the root cause is that serial data(host -> Marlin) is not transferred to command buffer quickly.

It's not a question of speed. It's a question of receiving capacity that's overflowed. In the current code, if you send a byte to Marlin and Marlin's buffer are full, the byte is lost silently by Marlin. This then breaks the logic in the code that's calling 'serial.available()' to check for progress (and there can't be any since the byte is lost).

You mean this is Marlin's limitation and host software have to use ping pong protocol. Am I right?

Yes. Marlin is a low-level system with very limited resources. It'd be close to impossible to implement high-level buffer management in it. So, yes, the higher level software must limit the number of message until Marlin told it to send more of them via ok XXX.

If so, when very small segment(size is same as MIN_STEPS_PER_SEGMENT) is sent to Marlin successively, Marlin's motor movement is not smooth. At that time, DEFAULT_MINSEGMENTTIME's adjustment is only solution?

It depends. If the small segment are made from your slicer's arc linearization, there is now arc processing G-code in Marlin that'll just compute the segments by itself without overloading the serial process.

Else, I guess you'll have to either slow the printing process to keep the rate as what Marlin is able to process, or change your board to something more powerful. Default minimum segment time is one parameter you can play with, but it's not the root cause of the issue and will not fix it 100%, it just improves a bit...

EYHJ59 commented 3 years ago

Thank you for your kindness and reply.

If slicer is supported to G2/G3, Marlin can handle it. Am I right? Except DEFAULT_MINSEGMENTTIME, what parameter(or method?) can overcome small segment problem?

(Thank you) * 1000000000

thinkyhead commented 3 years ago

Closing as a non-firmware issue. OctoPrint plugins can do some amazing things.

github-actions[bot] commented 3 years ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.