Skip to content
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

Add filament_motion_sensor #3857

Merged
merged 30 commits into from
Mar 15, 2021
Merged

Add filament_motion_sensor #3857

merged 30 commits into from
Mar 15, 2021

Conversation

TheJoshW
Copy link
Contributor

@TheJoshW TheJoshW commented Jan 29, 2021

Add functionality to support a Filament Motion Sensor for detecting extruder jams as well as runouts. Works by an encoder toggling the switch_pin 0/1 as the filament is pulled through the sensor.

Everything seems to work ok, except I have seen some weirdness in pause_resume. When pausing, the printer runs the runout_gcode however it sometimes moves back over the print job (does not affect Z, only X (and maybe Y)). Increasing the pause_delay may resolve this.

Also pause_resume seemed a little inconsistent in how it was handled so I tried to address, not sure if this is ideal but it should resolve most issues and get people going using this plugin. I have documented this in detail in FilamentMotionSensor.md.

Resolves #1327
Resolves #886
Resolves #249
Resolves #3715

Signed-off-by: Joshua Wherrett thejoshw.code@gmail.com

Add functionality to support a Filament Motion Sensor for detecting extruder jams as well as runouts.  Works by an encoder toggling the switch_pin 0/1 as the filament is pulled through the sensor.
Addresses Issue Filament jam sensor Klipper3d#1327

Signed-off-by: Joshua Wherrett thejoshw.code@gmail.com
@Sineos
Copy link
Collaborator

Sineos commented Jan 29, 2021

Does it make sense to add some sort of calibration. E.g.:

  • Have a calibrated extruder
  • Run command CALIBRATE_FILAMENT_SENSOR SENSOR= LENGTH=50
  • Extrude 50 mm filament and return the length the sensor would have measured

E.g. https://www.aliexpress.com/item/4000269547406.html?spm=a2g0s.9042311.0.0.4bc64c4d272cF6

  • 8 slots
  • Diameter 16.9 mm
  • roughly a gear ratio of 1:1
    ==> Arc Length 6.637 mm

So the returned value needs to end up somewhere between 43,363 mm and 50 mm.
Maybe an even more precise calibration would be possible if starting directly at a slot and extruding a multiple of the theoretical arc length.

Or rather vice versa: Extrude until, e.g 8 slots have passed the sensor and return the extruded length?

@TheJoshW
Copy link
Contributor Author

@Sineos yep calibration is next when I have time.
Currently, I have provided a detection_length parameter which you would set to 7 (mm) for the example sensor you gave.

@Sineos
Copy link
Collaborator

Sineos commented Jan 29, 2021

Resolves: #3715

@Arksine
Copy link
Collaborator

Arksine commented Jan 29, 2021

The changes to pause_resume.py are not correct. It should not command Octoprint to pause or resume the print as it has already happened. The paused and resumed action commands notify Octoprint of the action which is what is desired.

@TheJoshW
Copy link
Contributor Author

TheJoshW commented Jan 29, 2021

@Arksine I'll respond to your comment first, then go into more detail as to my understanding of how pause/resume works (happy to be corrected at any point). According to the OctoPrint docs (https://docs.octoprint.org/en/master/features/action_commands.html), action:pause and action:paused do almost the same thing, however action:paused prevents OctoPrint from running any GCODE, which is not what we want as you will see below.

As for the details, pause/resume is an asynchronous event that can be commanded from many places such as the Klippy "firmware" as we are using it here, but it can also be commanded from OctoPrint using pause/resume buttons and from the Printer LCD using the OctoPrint menu. By default, OctoPrint and the Printer LCD do the equivalent of sending action:pause(d) to OctoPrint which tells OctoPrint to stop queueing GCODE. The printer will continue to print any already queued GCODE, plus there is not feedback to the printer that a pause event has occurred, and the filament_motion_sensor plugin needs to know if the printer has been paused for event handling. So the first task was to enable the pause/resume feedback by ensure the PAUSE and RESUME GCODE provided by the pause_resume plugin is called in all cases. I explain how to do this in Klipper docs FilamentMotionSensor.md. This has the bonus of being able to use the pause SD card print functionality provided by pause_resume from all these places too, which in my opinion is a more complete and consistent pause/resume implementation.

The other issue is the asynchronous nature of pause/resume. Once a pause is issued, OctoPrint stops sending GCODE to Klipper, however Klipper likely has a number of GCODEs already queued, and remember pause simply stops the flow of GCODE from OctoPrint, Klipper doesn't actually respond in anyway to the action:pause(d) command. Klipper will continue to print any queued moves, which could take a while (seconds) from when the pause was issued, especially if there are long extruder moves queued for a large print with long straight edges. Klipper can also be moved after a pause is issued, using the Printer LCD or a PARK GCODE macro so filament can be changed, etc. The pause_delay goes someway to address this by allowing the user to configure some arbitrary time between when the action:pause(d) command is issued and the printer actually stopping printing, to roughly ensure the runout_gcode is executed after OctoPrint has stopped sending GCODE (you do not want OctoPrint sending GCODE after Klipper thinks it has paused as these GCODE will get combined with the runout_gcode and SAVE_GCODE_STATE will save the incomplete state).

So in summary, there are a number of things we could do to pause_resume to make it more robust, like flushing moves, or checking idle timeout for printer being in idle, so we can be more deterministic about the gap between commanding a pause to the host using action:pause(d) and the host actually pausing the GCODE, to Klipper flushing all those moves to the printer and the printer completing the moves.

@Arksine
Copy link
Collaborator

Arksine commented Jan 30, 2021

Initially the pause_resume module did call "action:pause" and "action:resume", however it was discovered that it could cause Octoprint's "After print job is paused" gcode to run twice if the user initiates a Pause from the UI. Likewise for resume. Unless Octoprint has changed this behavior reverting back to "action:pause" would likely cause issues for existing users.

The printer will continue to print any already queued GCODE, plus there is not feedback to the printer that a pause event has occurred, and the filament_motion_sensor plugin needs to know if the printer has been paused for event handling.

There should be at most one queued gcode when a runout is detected. The filament_switch_sensor sends "action:paused" immediately upon runout detection to notify Octoprint that it should stop sending gcode. After the pause_delay the "PAUSE" gcode (along with the runout template and M400) is placed on the tail of the gcode queue. The M400 will block execution until the runout_gcode has completed. At this point we should be able to safely assume that the printer is paused.

The pause_delay option was added to address a bug in Octoprint where it did not properly handle acknowledgments which could result in it queuing up additional gcode commands. However my understanding is that Octoprint has fixed this issue, every gcode Octoprint sends must be acknowledged prior to it sending another gcode.

The other issue is the asynchronous nature of pause/resume. Once a pause is issued, OctoPrint stops sending GCODE to Klipper, however Klipper likely has a number of GCODEs already queued, and remember pause simply stops the flow of GCODE from OctoPrint, Klipper doesn't actually respond in anyway to the action:pause(d) command. Klipper will continue to print any queued moves, which could take a while (seconds) from when the pause was issued,

What you are dealing with here is not queued gcode, its queued moves in the lookahead buffer. This makes "tracking" sensors a challenge, as you are comparing real-time feedback of the encoder against a future position. It does seem that you are estimating the extruder's current position which is desirable for a sensor like this.

So in summary, there are a number of things we could do to pause_resume to make it more robust, like flushing moves, or checking idle timeout for printer being in idle.

It might not be a bad idea for the filament sensor to replace the pause_delay with a call to toolhead.wait_moves(). We wouldn't want pause_resume to do this as it would simply be the equivalent of adding M400 to the PAUSE command, Octoprint could still send gcode commands behind it. This wouldnt be necessary for prints sourced from the virtual sdcard, the internal call to M24 blocks until the pause is completed.

@TheJoshW
Copy link
Contributor Author

@Arksine thanks for the clarification, happy to revert the changes to pause_resume.py. I mainly made them to maintain consistency between pauses commanded via pause_resume.py and those commanded via the printer LCD OctoPrint Pause menu item (which calls action:pause/resume directly), so maybe menu.cfg needs to be changed to action:paused/resumed too. Take a look at FilamentMotionSensor.md and see if the extra changes changes I recommend at the bottom make sense.

One issue I came across, was that filament_motion_sensor.py was calling send_pause_command() then waiting pause_delay then running PAUSE GCODE followed by runout_gcode and M400 (as you mentioned) this all worked fine. As an example when this happens on a runout, I go to the printer, replace the filament and select OctoPrint -> Resume on the printer LCD, by default this only triggers action:resume which causes OctoPrint to start sending GCODE to Klipper again. The issue with this is that RESTORE_GCODE_STATE is not called to restore printer state, nor is is_paused and pause_command_sent cleared as would be done if RESTORE GCODE was called. So I recommended changes that makes this all consistent and ensure PAUSE, RESUME and CANCEL_PRINT GCODE is called in all situations.

@Arksine
Copy link
Collaborator

Arksine commented Jan 30, 2021

I agree that the behavior should be consistent in Klipper. Ideally the Octoprint menu would call PAUSE and RESUME if pause_resume is loaded so a pause doesn't rely on Octoprint's configuration. The call to PAUSE would need to be more than simply the gcode though, because like with the filament sensors we need to instruct Octoprint to stop sending gcode before we place PAUSE on the gcode queue. It is something I will look into.

@TheJoshW
Copy link
Contributor Author

@Arksine no worries. pause_resume.py defines the PAUSE gcode command which calls action:pause(d) so that should work as is. Just need a consistent way to call it.

@Sineos Sineos mentioned this pull request Jan 31, 2021
@Coffee0297
Copy link
Contributor

can you please add so the amount between the pulses are in the config? so custom types are possible? Thank you.

@kalinon
Copy link

kalinon commented Jan 31, 2021

can you please add so the amount between the pulses are in the config? so custom types are possible? Thank you.

Are you referring to the length of filament? because i do see this setting: detection_length: 7.0

@Coffee0297
Copy link
Contributor

Ohh yes i totaly missed that. Thank you!

@kalinon
Copy link

kalinon commented Jan 31, 2021

Ive been testing this and so far so good. Although i notice it sends a action:pause even if it is not actively printing.

@TheJoshW
Copy link
Contributor Author

Thanks all for testing this. Whenever the extruder moves the filament_motion_sensor plugin will be measuring the length extruded and will trigger if the sensor does not detect filament movement (and run the PAUSE gcode and runout_gcode and send action:pause to the host if pause_on_runout is True). This can happen if extruding while bypassing the sensor or if detection_length is too short. If this is not the situation you are experiencing please let me know and any other issues you see. Thanks.

@kalinon
Copy link

kalinon commented Jan 31, 2021

Thanks all for testing this. Whenever the extruder moves the filament_motion_sensor plugin will be measuring the length extruded and will trigger if the sensor does not detect filament movement (and run the PAUSE gcode and runout_gcode and send action:pause to the host if pause_on_runout is True). This can happen if extruding while bypassing the sensor or if detection_length is too short. If this is not the situation you are experiencing please let me know and any other issues you see. Thanks.

@TheJoshW i think that's an accurate description of what happens. However i think we may want/need a config switch to allow it to only act when a print is running. Here were the steps I performed and results i saw:

  1. Turn printer on (pre-heat, level, probe, etc)
  2. Manually push filament through to HE
  3. Extrude 25mm - PAUSE/runout_gcode is sent to host

The reason i believe that #3 is triggering the logic is that there is slack between the extruder and sensor. Here is my crude ASCII drawing of how the filament is ran on my Voron 2.4

(Spool) ------ (sensor) -----
                             |  ** <- slack in filament can occur here
                             |
                             |--- (E Motor) ---- (extruder)

Until that slack is tightened all E movements will trigger the runout. I also see it trigger while the print is inPAUSE state.

Here's the scenario i see during a filament change:

  1. Start print
  2. Filament Runs out
  3. PAUSE/runout_gcode is sent to host
  4. Replace filament manually
  5. Extrude 25mm - PAUSE/runout_gcode is sent to host
  6. Extrude 25mm - PAUSE/runout_gcode is sent to host
  7. RESUME sent manually to continue

Now its possible to use the SET_FILAMENT_MOTION_SENSOR command to disable it in these various stages... i.e enable on PRINT_START, disable on PAUSE, enable on RESUME etc. But perhaps its easier to either make the default behavior the following:

  1. Only send PAUSE/runout_gcode when print is running
  2. Do not send PAUSE/runout_gcode when print is paused

@TheJoshW
Copy link
Contributor Author

TheJoshW commented Feb 1, 2021

@kalinon thanks for the details. As per my previous comments, pause/resume doesn't actually change the printer state, so you can move the print head and extrude while in pause. Idle timeout is the closest thing to printer state, however any movement of the print head or extruder puts the printer in "printing" state even when it is paused. So as a fail-safe I made the filament_motion_sensor monitor all extruder movement. It is possible to disable the sensor when in pause mode and I am happy to do that, however, this doesn't account for the time before the print starts and the printer isn't printing, nor is it in pause. Happy to take suggestions to handle this state. The other thing is filament slack. I have this issue as well, as my sensor is on the top of the printer, I increased the detection_length to account for this. Removing all filament slack before moving the extruder helps too.

@kalinon
Copy link

kalinon commented Feb 1, 2021

@TheJoshW Yeah, my issue was that in my runout_gcode i triggered M600 which had a relative move to pull away from the print and retract the filament for change. This would cause it constantly move up and undo any extrusion i had done when trying to replace the filament.

You seem to have a good grasp on the state changes of the print cycle so I will defer to you on that behavior. Im still learning klipper and its differences from marlin. I do think perhaps a config option such as ignore_during_pause to allow users to toggle the behavior could cover this use case.

Ive modified most my gcode commands to handle the current behavior, but am having it almost always trigger when it starts to do the standard skirt. I'm guessing the skirt is just not outputting enough material or something. Once i get the print going, the sensor/code works great, even at 7mm. Perhaps i need to up it as you suggest and it will get me past the skirt issue.

@kalinon
Copy link

kalinon commented Feb 2, 2021

@TheJoshW I think there is a bug. If the sensor is disabled it will still trigger an action:pause if a runout is detected.

You should be able to test this by having an empty extruder, then disabling and extruding via:

SET_FILAMENT_MOTION_SENSOR SENSOR=f_sensor ENABLE=0
G1 E25 F300

Mainsail log:

2/2/2021, 4:51:55 PM | filament_motion_sensor(f_sensor): enable = False, detection_length = 12.00
2/2/2021, 4:52:00 PM | M83G1 E25 F300
2/2/2021, 4:52:03 PM | action:pause

@TheJoshW
Copy link
Contributor Author

TheJoshW commented Feb 3, 2021

@kalinon Thanks for the update. I see the problem in _process_runout(). I should be able to get to it this weekend as well as the other suggestions.

@KevinOConnor
Copy link
Collaborator

Interesting, thanks. As a high-level feecback, this looks like useful functionality.

I have not performed a full review, but I did notice a few items:

  1. The changes to pause/resume should be in a separate PR. Though, it's my understanding that those changes are not correct.
  2. Unfortunately, the printer.send_event() method is not designed for high-frequency updates and I'm concerned tracking the extruder position that way will increase host system load. As mentioned briefly at Endstops on a different MCU to stepper motors #3832 (comment) , I'm planning to introduce functionality to the low-level stepper code to provide the actual stepper position from a recent print_time. I think that should be useful in this context.
  3. Perhaps I've misread the code, but it looks like it has a lot of similarity to the filament_runout_sensor.py module. We really don't want to duplicate that functionality - instead we want new filament sensors to import and use the existing filament_runout_sensor.RunoutHelper() code. (For example, see how tsl1401cl_filament_width_sensor.py and hall_filament_width_sensor.py reuse that code.)

Cheers,
-Kevin

@dewi-ny-je
Copy link

I barge in just to provide an idea for future development.

In #2610 a design using a magnetometer is provided which would allow extremely high measurement accuracy (potentially microns of filament motion).

Maybe this filament run-out detection plugin could be sometimes in the future expanded to provide continuous feedback to be used to verify not only the presence of motion, but also the consistency between commanded and effective filament motion, a sort of closed loop feedback for filament motion.

@TheJoshW
Copy link
Contributor Author

Interesting, thanks. As a high-level feecback, this looks like useful functionality.

I have not performed a full review, but I did notice a few items:

@KevinOConnor thanks for taking a look at this and providing your expert opinion.

  1. The changes to pause/resume should be in a separate PR. Though, it's my understanding that those changes are not correct.

I will back this change out.

  1. Unfortunately, the printer.send_event() method is not designed for high-frequency updates and I'm concerned tracking the extruder position that way will increase host system load. As mentioned briefly at #3832 (comment) , I'm planning to introduce functionality to the low-level stepper code to provide the actual stepper position from a recent print_time. I think that should be useful in this context.

Yep agree with the printer.send_event() method use. I have tried to make it as quick as possible and perform any time consuming actions in a greenlet. The work in #3832 looks very promising and I would be happy to use it. Let me know how you would like to proceed, i.e. is the use of printer.send_event() ok for now, with the plan to refactor at a later date with the changes from #3832?

  1. Perhaps I've misread the code, but it looks like it has a lot of similarity to the filament_runout_sensor.py module. We really don't want to duplicate that functionality - instead we want new filament sensors to import and use the existing filament_runout_sensor.RunoutHelper() code. (For example, see how tsl1401cl_filament_width_sensor.py and hall_filament_width_sensor.py reuse that code.)

Thanks I will look at this. filament_runout_sensor.py uses arbitrary timeouts which I removed in favour of actual state, so happy to feed these changes back to filament_runout_sensor.py as well. I didn't want to affect too much of the existing code on my first change.

@Bob90
Copy link
Contributor

Bob90 commented Feb 15, 2021

Sorry, I'm new. Does this mean I can add a sensor now?

@TheJoshW
Copy link
Contributor Author

Thanks Kevin, I'll think about that and do more testing, maybe keep a prev_extruder_pos to detect retractions and act appropriately. Will also incorporate Arksine's suggestion plus some other enhancements if I get to them. Will raise another PR when I am ready.
Cheers.

@WindoC
Copy link

WindoC commented Mar 19, 2021

Are there any debug values that can be output for this module? I found some fault-positive jam detection when printing the first layer. Also, there is no info/log output when an error detected.
Suggest to add function to able debug output the encoder action and extruder's length.

@tjengbudi
Copy link

any doc or quick start guide to try this? i have btt smart filament sensor to try. but lost in how set this. any clue? thanks

@TheJoshW
Copy link
Contributor Author

See the filament_motion_sensor section of https://www.klipper3d.org/Config_Reference.html. It's the same as the filament_switch_sensor but with the addition of detection_length (default of 7 should be ok) and extruder (usually extruder). And you need to specify the switch_pin the sensor is connected to.

@tjengbudi
Copy link

@TheJoshW thanks... already set and working.... at least my print can resume. thanks a lot for this feature

@markwinger
Copy link

I have one of the BIGTREETECH Smart Filament Sensor Filament Break Detection Module sitting on a shelf. I bouoght it then switched to klipper so never used it. It sounds like this implementation would support it. Is there documentation, or examples on setting getting it running with klipper?

@Cosik
Copy link

Cosik commented Apr 7, 2021

Hi, question from my side. Some time ago I design rotary sensor for my Duet board and RRF (https://www.thingiverse.com/thing:3879971) if I good understand I could use it with those implementation? Also did you check performance of such sensor? Currently with 44 teeth I get resolution around 0,5mm.

@markwinger
Copy link

I added this section to my printer.cfg
filament_motion_sensor filament_sensor]
detection_length: 7.0

The minimum length of filament pulled through the sensor to trigger

a state change on the switch_pin

Default is 7 mm.

extruder: extruder

The name of the extruder section this sensor is associated with.

This parameter must be provided.

switch_pin: PC12
pause_on_runout: true
runout_gcode:
M117 Filament out
#insert_gcode:
#event_delay:
#pause_delay:

See the "filament_switch_sensor" section for a description of the

above parameters.

I also commented out my filament_switch_sensor section. I connected the "smart sensor and tried it.

It draws the first line (purge) the errors with filament out. I tried changing the switch pin to !PC12 and got the same result.

I'm running klipper version v0.9.1-400 with fluidd v1.11.2.
Should this work or am I missing something? Are there docs on how to test the config and hardware?

@TheJoshW
Copy link
Contributor Author

TheJoshW commented Apr 8, 2021

@markwinger yea that should work. See my previous comment:

See the filament_motion_sensor section of https://www.klipper3d.org/Config_Reference.html. It's the same as the filament_switch_sensor but with the addition of detection_length (default of 7 should be ok) and extruder (usually extruder). And you need to specify the switch_pin the sensor is connected to.

Commenting out filament_switch_sensor is also correct and switch_pin should be the same as the filament_switch_sensor. I have not added debugging or calibration functionality yet.

@TheJoshW
Copy link
Contributor Author

TheJoshW commented Apr 9, 2021

@Cosik hi, if your sensor toggles the switch_pin then it should work. The filament_motion_sensor is pretty basic it just waits for a change in state then resets the runout length. So you should get at least 0.5mm resolution I would assume based on the fact it triggers from 0 to 1 and from 1 to 0.

tntclaus pushed a commit to tntclaus/klipper that referenced this pull request Apr 18, 2021
Add functionality to support a Filament Motion Sensor for detecting extruder jams as well as runouts.  Works by an encoder toggling the switch_pin 0/1 as the filament is pulled through the sensor.

Signed-off-by: Joshua Wherrett <thejoshw.code@gmail.com>
driest pushed a commit to driest/klipper that referenced this pull request Apr 26, 2021
Add functionality to support a Filament Motion Sensor for detecting extruder jams as well as runouts.  Works by an encoder toggling the switch_pin 0/1 as the filament is pulled through the sensor.

Signed-off-by: Joshua Wherrett <thejoshw.code@gmail.com>
@tjengbudi
Copy link

@TheJoshW i already used this feature. but something have bad behaviour. if my length used 6-8mm it is randomely pause but it will resume immidietly. but the weird is, resume process looks like not call. the height of the z axis is not return. it will return after several second. if i used 10mm it will paused randomly but it the filament is not jam or not runout. there is 2 problem here. hope you can check or gave some clue

@TheJoshW
Copy link
Contributor Author

TheJoshW commented Jun 7, 2021

@tjengbudi this is a basic sensor so it could be a wiring issue or a bug if your print has a long retraction just after the runout length is reached. Making the extruder go backwards then trigger runout multiple times. If you can answer these questions it may help:

Are you using BTT smart filament sensor?
Are you using a Bowden extruder with long retraction length?
Is filament sensor very close to the extruder?
Does it happen in all prints or just some?
Does it trigger if you put a very large detection_length?

Thanks.

@tjengbudi
Copy link

tjengbudi commented Jun 7, 2021

@TheJoshW
Are you using BTT smart filament sensor? yes
Are you using a Bowden extruder with long retraction length? no, direct retraction is 3.5mm
Is filament sensor very close to the extruder? no
Does it happen in all prints or just some? if i use min length detection 6-7 it always happens, and it is automatically resumed
Does it trigger if you put a very large detection_length? i just set 10mm and it triggered. but it is not automatically resume.

if it is at 6-8mm and it is auto resume after pause. the z position is not return. it just return printing but it like print in the air. cannot make sure x and y position returned or not

the cable is used twisted cable.

@TheJoshW
Copy link
Contributor Author

TheJoshW commented Jun 8, 2021

@tjengbudi I have a direct extruder with the BTT smart filament sensor mounted on the top of my printer. I have my detection_length set to 35 to compensate. This works fine for runout but may be to much distance if there is a jam. Ideally the sensor should be as close as possible to the extruder so every extrusion and retraction is accurately detected by the sensor. As for your issue with auto-resume, I did not write that code it is part of the filament switch sensor which the motion sensor is based on. I hope that helps.

@charredchar
Copy link

charredchar commented Jun 30, 2021

I'll be building my own filament motion sensor this weekend so I am eager to test this. Moving away from using just a simple switch that doesn't detect a snapped filament.

One thing I am worried about, I'm putting the sensor outside of my enclosure, closer to the spool, and wondering how having about 300mm of filament between the sensor and extruder will mess with things. It is a direct drive and I'm not too worried about "wasting" that length, more about saving a print. With that length basically acting like a buffer I don't think having a longer length in the settings would be an issue.

Okay, SET_FILAMENT_SENSOR already enables/disables the sensor.

You could add another command to set the filament detection length, though it would seem odd to do that at runtime. (That is, setting that solely in the config may be sufficient and simpler.)

-Kevin

The instance I can think of actually wanting to change this setting mid-print would be more if you're having issues. It would be nice to be able to adjust it on the fly to dial it in if you have false triggers on a really long print without just flat out disabling it.

@TheJoshW
Copy link
Contributor Author

TheJoshW commented Jul 2, 2021

@charredchar Hi. Happy to do that, however I am not sure how I can "append" DETECTION_LENGTH to the existing SET_FILAMENT_SENSOR command, will need to look into that. As for your configuration, I have exactly the same setup. I set detection_length to 35 and it works fine. The only issue is when a jam occurs you will print for a bit longer without filament until 35 mm is fed through and the jam actually triggers. Hope this helps.

@Curtis-Fletcher
Copy link

I've just built a filament motion sensor using a standard rotary optical encoder. The encoder provides a quadrature output (Two pins, when A leads B CW, B leads A CCW) allowing the reader to determine which direction the sensor is rotating, something like this may help with problems where retraction reads like extrusion.

My ideal scenario would be where the sensor reader would know roughly how much extrusion (positive or negative) is due during period and would trigger when the measured value deviated too much from the expected value. Being able to debug log the extrusion and sensed extrusion might also allow you to identify extrusion errors (Slip, jam, grind, etc).

From what I see in filament_motion_sensor.py the sensor code does read the current extrusion position (I assume that's a current sum that includes retraction so can shrink as well as grow?) but the sensor trigger is just used as a heartbeat rather than a calibrated counter (I am a developer but python isn't my preferred language so I might be misunderstanding) if I'm reading this right I could have a go at, say "filament_speed_sensor.py" that actually compares extrusion to the sensed value. everything in /extras seems to be auto loaded so it doesn't look like it would need any changes elsewhere.

My question is has this notion been rejected or perhaps is already being worked on, being new to Klipper I don't want to mess with existing effort or retread old ground.

@TheJoshW
Copy link
Contributor Author

TheJoshW commented Jul 9, 2021

Hi @Curtis-Fletcher. Another user, @Sineos, also requested a similar feature, I haven't got around to it, however it sounds like your sensor is different enough to warrant a new plugin that includes this extended functionality. Have a look at previous comments in this PR and check out the issues mentioned by @Sineos.

@tjengbudi
Copy link

@TheJoshW i have a problem with the filament motion sensor. it is working until it detect the filament jam, i checked in the filament sensor status it gets error. after resume the filament sensor status is still error. if the filament jam again it will not detect again. it will resolve until i restart the klipper

have you experienced about this ? i think it is not wrong in my setting. i open the issue but looks like the issue will be ignored and closed.

@tjengbudi
Copy link

looks like you have same problem with me #4540 (comment)

@TheJoshW
Copy link
Contributor Author

@tjengbudi I am reusing the RunoutHelper from filament_switch_sensor. It works on state change so after a jam or runout you must pull filament through the sensor to change its state to "filament present" otherwise future jams will not be detected.

@tjengbudi
Copy link

@tjengbudi I am reusing the RunoutHelper from filament_switch_sensor. It works on state change so after a jam or runout you must pull filament through the sensor to change its state to "filament present" otherwise future jams will not be detected.

@TheJoshW so it is known problem?

@TheJoshW
Copy link
Contributor Author

@tjengbudi That's how all
The runout sensors work with Klipper. If you get a runout and don't put more filament in to reset the sensor, you can restart printing with no filament and Klipper will continue printing (but print nothing).

@tjengbudi
Copy link

tjengbudi commented Aug 26, 2021

@TheJoshW i see. there is no way out? how if the filament not changing it will cannot not resume? i think it will the most safety use case

@TheJoshW
Copy link
Contributor Author

@tjengbudi, I don't believe paused is a Klipper state. Pause simply tells the host to stop automatically sending gcode to Klipper (and run a macro if defined). If the user wants to manually send gcode to move or run a macro etc they can and Klipper won't stop them. This also applies to "resuming" which restores the printer state to when pause was requested and tells the host to resume streaming gcode. This has nothing to do with the filament runout sensor. If I understand correctly what you are asking, you want Klipper to check for a filament jam or runout and block the resume command until the issue is rectified. This could be complemented with a gcode mux_command of RESET_JAM which would allow the user to use gcode to clear the jam detection (in the case of a false positive). This will change the function of Klipper outside of the scope of the filament_motion_sensor and I will need to defer to @KevinOConnor and @Arksine to see if this is desired for Klipper.

@tjengbudi
Copy link

@TheJoshW oh i see. but looks like it is a bug that it can print without filament even the sensor get notified. if it is not prevent the printer to resume printing, at least it can detect another jam without must change the filament.

as you said, i also have problem with second printing (without restart the klipper service), sometime it have random paused and sometime it is automatically resume after that if my pla broken it will not notified at all. or event the extruder never extrude. (known problem you said before)

@github-actions github-actions bot locked and limited conversation to collaborators Oct 14, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet