Joystick managed by Marlin

This topic contains 20 replies, has 7 voices, and was last updated by  Jamie 1 week, 6 days ago.

Viewing 21 posts - 1 through 21 (of 21 total)
  • Author
    Posts
  • #106110

    Jamie
    Participant

    As a bit of a diversion from my second build, I’ve put together a joystick that allows jogging with analog control of the feed rate.

    I decided to take a different approach from the approaches I’ve seen, which operate through the Raspberry Pi or a separate microcontroller like @arminth‘s solution (https://www.v1engineering.com/forum/topic/manual-joystick-control-fro-mpcnc-2/).

    This one has a very dumb joystick, with modifications made to Marlin to read the analog values and inject g-code into itself.  Here is a schematic of the joystick.  The enable pin is active-low with a pullup on the digial pin, so if it’s disconnected it will treat it as disabled and not lose its mind trying to read floating analog voltages.  Right now I have this connected on AUX-2, using A5, A10, D44, and A12.

    joy_schematic

    I’ll publish the code, but I’m not sure whether to try for a fork and pull request, or to just publish a patch file.  There is not that much code and it’s a pretty non-invasive modification.  One way or another I’ll post it once I get it organized for publication.

    I started with one of the super cheap x/y thumb joysticks, but the inconsistency of the ADC readings was making me nervous, so I bought this one for $17: https://www.amazon.com/gp/product/B07CVGPMDP/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1

    The overall strategy is mostly straightforward.  Read the analog values, by mimicking the method used for temperature ADC reading. Then in the idle loop, check to see if the enable pin is active (low) and if the joystick is outside the dead zone.  If the movement queue has more than 4 commands, then abort, so we fill the queue with only about 1/4th of a second worth of movement.

    If all the checks pass, then calculate a feed rate (as a fraction of the maximum feed rate) based on how far the joystick is pushed.  Then for that feed rate, calculate the distance that would take about 1/20th of a second to traverse.  Then temporarily enter relative mode and inject a g-code command to move that distance at that feed rate.

    As a result, the joystick should generate a constant flow of about 20 commands per second with roughly a 1/4 second lag between the joystick position and the speed response.  Since a small movement of the joystick can provide slow movement, a bit of lag should be alright since you can jog quickly and fine-tune at low speed, so you don’t have to stop on a dime.

    Attachments:
    3 users thanked author for this post.
    #106121

    Jeffeb3
    Participant

    If all the checks pass, then calculate a feed rate (as a fraction of the maximum feed rate) based on how far the joystick is pushed. Then for that feed rate, calculate the distance that would take about 1/20th of a second to traverse. Then temporarily enter relative mode and inject a g-code command to move that distance at that feed rate.

    This is great! This is exactly what is needed in jogging. Very clever.

    Since a small movement of the joystick can provide slow movement, a bit of lag should be alright since you can jog quickly and fine-tune at low speed, so you don’t have to stop on a dime.

    Have you tried a non linear response? I have a feeling my moves will all be full speed or creeping, but with a continuous in between. Making a little expo curve would give a bit more range on the low end while keeping a high top end.

    1 user thanked author for this post.
    #106125

    Ryan
    Keymaster

    Wow…I hope this is can get pulled in. We could entertain so many people with a ZenXY….

    1 user thanked author for this post.
    #106129

    Jamie
    Participant

    Have you tried a non linear response? I have a feeling my moves will all be full speed or creeping, but with a continuous in between. Making a little expo curve would give a bit more range on the low end while keeping a high top end.

    A keen observation!  Yes, actually it’s already nonlinear.  I was first thinking exponential like you said, but quadratic was quicker to code (no decisions to make on choosing dynamic range) and so far it seems good enough by feel.  Although I haven’t put it into real use, it seems to have pretty good granularity at the low end.

    1 user thanked author for this post.
    #106136

    Jamie
    Participant

    Okay, here’s a commit which I “ported” to upstream Marlin bugfix-2.0.x.

    https://github.com/vector76/Marlin/commit/2d258d649795fa062b95afac60ea639e61bc7585

    It appears this branch of Marlin is a fast-moving target, functions and variables changed names so I don’t know that a single patch will apply to upstream Marlin and also work for (today’s) MPCNC flavors.  But I can generate PRs against the V1 firmware if there’s interest.

    I’m going to build “pure” Marlin with this change, plus configuration changes for steps/mm etc., and once I confirm that it still works I’ll submit it to upstream Marlin for their consideration.

    #106346

    Jamie
    Participant

    Okay, pull request officially submitted to upstream Marlin: https://github.com/MarlinFirmware/Marlin/pull/14648

    I have no idea if they will adopt it but we will see.

    #106347

    Ryan
    Keymaster

    Awesome, subscribed to that one!

    #106349

    Jeffeb3
    Participant

    Looks good. I hope you don’t mind my armchair peer reviewing. I hope those things make it easier to swallow into the main. I do think they will want it outside of temperature. I also think they will like it. They do have some cnc only features and it’s completely disabled by default. There also some larger 3D printers that might benefit from this.

    I personally am very tempted to hook my son’s toy 3D printer up with a spare Marlin controller and a joystick… He would go bonkers for it.

    #106381

    Ryan
    Keymaster

    DUDE!!!!! YES! Congratulations! Awesome addition to Marlin.

     

    Now I am going to have to figure out how to use it. Joystick has been ordered…Need to update my zen.

    #106382

    Ryan
    Keymaster

    Oops jumped the gun…looks close though!

    • This reply was modified 1 month ago by  Ryan.
    #106932

    AJ Kostyak
    Participant

    WOW. 6 years later, has there been any third party success with this topic, particularly on Marlin 2.0 optimized for MPCNC dual endstop LCD?  I am fearful of combining the two Marlin edits… not afraid to get my hands dirty with some C++ but is it worth the hassle.  Also, you stated this script ran in the idle loop, does that mean it will not interfere with running Gcode or add unnecessary computation to the travel calculations?  I am debating an attempt to disable temperature for this reason considering I am not planning to 3D print with this build.  I know there are a few analog pins on the Rambo.

    Definitely an admirable project and contribution!

    #106940

    Jamie
    Participant

    Marlin 2.0 is changing rather a lot lately, and the patch for adding joystick to the latest Marlin won’t work on the MPCNC flavors.  Some of the variables have changed names and it won’t merge cleanly.

    I originally implemented the feature off the MPCNC codebase, so if you want it I can publish a fork that contains the joystick update.  Tell me which branch you’re using and I can make it pretty hassle-free.

    Or you can wait for the patch to make it into official Marlin and for the MPCNC fork to pull from upstream, but there are no guarantees on when either of these will happen.

    It shouldn’t interfere with processing because 1. everything time-sensitive is driven by interrupts, and 2. it tries to minimize CPU usage by aborting early if there is nothing to do, and 3. it shouldn’t be enabled while you’re processing a job (part of the reason for the enable pin, besides preventing screwing up a job), and 4. a job will usually (maybe) keep the planner full, which also disables the joystick.  So it should be extremely gentle on the CPU when running a job.

     

    1 user thanked author for this post.
    #106952

    Jeffeb3
    Participant

    WOW. 6 years later, has there been any third party success with this topic, particularly on Marlin 2.0 optimized for MPCNC dual endstop LCD?

    What is 6 years?

    #106978

    thesfreader
    Participant

    And it looks like Jamie’s PR is getting enough attention to get effectively pulled when “ready”. NICE !

    #107040

    AJ Kostyak
    Participant

    Whoops, I misread the forum date, looks like this is a lot more recent XD.  Yes I am on the MPCNC full size RAMBO with dual endstop and large LCD flavor.  I have a super-PID in the mail but I will likely keep it on a separate circuit with a dial just because I feel more comfortable with manual control over that, despite Marlin’s support for it.  I think with all the emerging 3D printer tech it might be some time before a more convenient jogging method is prioritized over support for new extruder and sensor types, but hopefully not!  I would very much appreciate the RAMBO_dualend_LCD patch if you still have it,

     

     

    #107054

    Jesse
    Participant
    #107084

    Jesse
    Participant

    I was literally searching for a way to do this for 3 weeks. And then all the sudden after I had given up, I was on V1 Forums and you posted this. You are awesome.

    #107313

    Jamie
    Participant

    Ok, it seems there’s quite a lot of interest in this.  Eventually I am hoping it will make its way into upstream Marlin 2.0.x but in the mean time I’ve patched five versions of Ryan’s MPCNC code: RAMBo, dual and non-dual flavors, RAMPS, dual and non-dual flavors, and Mini-RAMBo.

    I tested the change on the RAMPS series-wired version and merged the change into the other 4.  I am pretty sure this will work but technically it’s untested.

    I couldn’t create a proper fork because I already have a fork for the upstream Marlin 2.0.x and GitHub doesn’t permit multiple forks (or forks-of-forks) on a single account.  So instead I imported which appears to be nearly the same thing.

    Here are the versions

    This contains the implementation but it’s not enabled by default.  You must enable it and set your pins at the bottom of Configuration_adv.h.

    You will also need to use M119 (with joystick switch off) to determine appropriate values for your joystick dead zone and max range.  The configuration allows going without an enable switch but I think it’s a really bad idea to do so.  Your machine might take off on you as soon as it’s powered on.  The enable switch is configured to be enabled when the enable pin is shorted to ground, and disabled when the switch is open.  This allows disconnecting the joystick without having the machine decide to move on its own.

    I’d love to see video if other people get this working!

    2 users thanked author for this post.
    #107315

    Jamie
    Participant

    Looking over the list, I realized the ZenXY might be especially fun, so I patched those too:

     

    4 users thanked author for this post.
    #108602

    Glen
    Participant

    I would appreciate any advice on adding a joystick to the SKR 1.3.  I wonder if there are enough spare analog inputs to do this???

     

    #108624

    Jamie
    Participant

    I’m unfamiliar with which pins can support analog reading.  The thermistor ports would be possible in theory but they have pullup resistors that will make the readings wonky, depending on the resistance of the joystick.  You will have to get your hands dirty in the firmware to disable or remap the thermistors and fix whatever else might break because of that.

    You can connect the joystick without any hardware modifications and see if you get decent resolution on the ADC readings.  If the joystick has high resistance then it is likely that you will have poor resolution.  If you get lucky then the ADC readings might be usable and you would just set your dead zone and extreme limits based on the values you get from M119.

    The other alternative would be to remove the pullup resistors from the board.  Then your joystick will be able to use the full range of the analog pins.

    Also, I tried to follow the existing pattern in Marlin for analog reading, which “should” work for the 32-bit boards, but as far as I know this has not been tested.  I have not looked closely at the hardware abstraction layer, so there is a chance this might not be correct for non-Arduino boards.

Viewing 21 posts - 1 through 21 (of 21 total)

You must be logged in to reply to this topic.