Closed kcheeeung closed 5 years ago
Is this for 1.1.x or 2.0.x?
This might work. They define/create E_MIN and E_MAX endstops.
E endstops 1.1.x.zip E endstops 2.0.x.zip
You'll need to define E_MIN_PIN and/or E_MAX_PIN as needed.
You'll also need to add the following to the Configuration.h file as needed.
The E endstop(s) are setup with the pullup resistor always enabled.
Had a couple of compile errors. Here's the corrected files.
Wow! Thanks for the quick response Bob! I'm working with 1.1x right now. Great work of you and the Marlin team on the development on the Marlin 1.1.x and 2.0.x. The Marlin 2.0.x looks very promising!
I've been looking through the source code myself previous to try to understand what were the key changes needed, but I've come somewhat close as to identifying that I woud need endstop.cpp. It's pretty difficult to understand the Marlin unless one has developed and worked with it a lot. I hope to learn more soon.
The next steps would be define the E_MIN_PIN and E_MAX_PIN in the .h file of the board I'm working with. Great to hear back from you, and I'll you know how it goes.
I have not been able to test the changes.
Let me know if you run into trouble & I'll see what I can do.
I hope you had a nice Thanksgiving holiday. I couldn't figure this one out yet. I made the changes as mentioned of the E_MIN_INVERTING
. I reassigned pins in RAMPS.h for testing purposes and also so I don't have conflicting pins. Everything seems to compile correctly, but testing with the endstop doesn't appear to stop the E motor when it's moving
Sample Gcode:
G92 E100
G1 E0
click endstop, but still moves to 0 position.
**pins_RAMPS.h**
// Limit Switches
//
#define E_MIN_Pin 3
#define X_MIN_PIN 2//3
#ifndef X_MAX_PIN
#define X_MAX_PIN 2
#endif
Not sure what else might be missing. The "E axis" exists for the extruder filament, but there aren't any bounds to it. It appears you can send any G0/1 E## and the extruder motor will spin regardless.
In a setup with filament runout sensor, I believe 4 endstops are used as well. The X, Y, Z, and finally another one for the filament sensor. The filament runout sensor looks like it calls quickstop_stepper() when it's activated (it stops the single E motor? all motors?) Do you think this is what we need? Would this optimal is accuracy and repeatability?
The intended idea is to use the E# in the gcode to spin a certain number of steps to reach a particular position, which requires the knowledge of a "home or reference point." I'd have a post processing script do something like this to the gcode: G0/1 E## (in the correct + or - direction to "home") firmware stops E motor when it hits endstop or endstop is touched/activated G92 E0 (Define "homed" position as the 0 point) G0/1 E## (move to calculated position based on E steps/mm)
Sorry for this long post. What is your take on this?
Hmm. I have done a bit more digging and realized that the endstops result in stepper.endstop_triggered()
, which ultimately leads to kill_current_block()
.
**stepper.cpp**
void Stepper::endstop_triggered(AxisEnum axis) {
#if IS_CORE
endstops_trigsteps[axis] = 0.5f * (
axis == CORE_AXIS_2 ? CORESIGN(count_position[CORE_AXIS_1] - count_position[CORE_AXIS_2])
: count_position[CORE_AXIS_1] + count_position[CORE_AXIS_2]
);
#else // !COREXY && !COREXZ && !COREYZ
endstops_trigsteps[axis] = count_position[axis];
#endif // !COREXY && !COREXZ && !COREYZ
kill_current_block();
}
For all purposes, I would just need the kill_current_block() function to stop movement of the moving E motor. Would that we correct?
**stepper.h**
static inline void kill_current_block() {
step_events_completed = current_block->step_event_count;
}
Then we'd need is the "E endstop" to be a signal to call kill_current_block() to stop the E motor movement. The E axis is "homing" and upon the trigger of the endstop, the motor stops movement. I'd using be "manually homing" by sending one of the G0/1 E# commands.
Here's the link to rev C of the 1.1.x E endstop code.
There's several more changed files plus an example Configuration.h file.
I was able to test this code.
I just saw your latest post.
Yes, kill_current_block();
(or its equivalent) is what actually stops the stepper motor. I had that part correct but I didn't have the enables (#if statements) setup correctly.
I'd using be "manually homing" by sending one of the G0/1 E# commands.
After that issue a G92 E0
to set the E position to zero.
Great! I've gotten it to work. Is it possible to use all 3 of the leftover XYZ MAX pins/ports to control the same E axis?
E axis is shared between the extruder motors, so I'll change it by using the T0, T1, T2. E_MIN_PIN
is configured to a different pin than F_MIN_PIN
. Different names/pins, but the results of stopping the E axis should be the same.
I'm not sure what else I might be missing because the testing using the F_MIN_PIN
(endstop) didn't work, but E_MIN_PIN
(endstop) did. When you have some time, please help me take a look.
In config, I added:
#define F_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop.
#define F_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop.
I was trying to make a "2nd E min pin" (named F_MIN_PIN): E endstops e_min+f_min.zip
You want to stop the E axis when any of a list of pins goes active?
One way of using multiple sensors to make one pin go active is to "wire or" them and declare active as logic zero ( E_MIN_ENDSTOP_INVERTING set to false .
If the sensors are a mechanical switch then tie common to ground and tie all the normally open contacts to the E_MIN_PIN along with a pullup.
If the sensors are electronic then they'll need to be open collector or open drain.
The downside is this method can't tell the difference between the sensor not activated and the cable being broken/off.
If you want to keep E_MIN_ENDSTOP_INVERTING as true then we'll need to use one I/O pin per sensor and modify the code.
Essentially yes. I'm trying to make the E axis work for a list of pins.
That's very smart. Using the "wire or" definitely works, and I have tried it out as your suggestions.
I'm trying to "hack" the board and make the most use of it by trying to utilizing all the free pins. I'd figured it might be a waste not to use them otherwise so I've looked at the code as well.
@Bob-the-Kuhn thanks for the help thus far and throughout this year or so. I've been working on the code and got the individual I/O pins working with new modified code I added.
Good news!
Hi there guys, I am quite interested in doing this on a Sanguino ATmega1284P, however it only has 1 endstop for x/y/z. I would like to use the x endstop as another z endstop. Will try and follow along to see if I can solve the problem myself but good chance I will need help. Cheers
You want one X endstop, one Y endstop and two Z endstops.
What does the second Z endstop do?
What are you using as the Z sensors?
Thanks for the prompt reply! I'd like no X endstop, one Y endstop and two Z endstops. The Sanguino board only has 3 endstop options, unlike the RAMP which has 6.
The two Z endstops are max and min, currently have a Y min and Z min, would like to use the X endstop as a Z max.
Using microswitches as sensors.
Oh I see, so is your board has X min, Y min, and Z min. What's the name of the board you have (in Marlin config)?
And what you want to do is turn the X min into a Z max?
In Configuration.h change the homing section to read:
//#define USE_XMIN_PLUG
#define USE_YMIN_PLUG
#define USE_ZMIN_PLUG
//#define USE_XMAX_PLUG
//#define USE_YMAX_PLUG
#define USE_ZMAX_PLUG
In pins_SANGUINOLOLU_11.h change the limit switch section to read:
//
// Limit Switches
//
//#define X_STOP_PIN 18
#define Y_STOP_PIN 19
//#define Z_STOP_PIN 20
#define Z_MIN_PIN 20
#define Z_MAX_PIN 18 // X_STOP_PIN is now used for Z_MAX
How are you planning to home your printer?
The only difference between an endstop input and any other input is the endstop has a 1K-10K pullup resistor on it. My suggestion is to grab an unused input for use as the Z_MAX endstop. You'll need to create a custom cable that has the pullup resistor built in.
Let's say that you use pin xx as the Z_MAX endstop. Here's the changes you'll need to make.
#define USE_XMIN_PLUG
#define USE_YMIN_PLUG
#define USE_ZMIN_PLUG
//#define USE_XMAX_PLUG
//#define USE_YMAX_PLUG
#define USE_ZMAX_PLUG
//
// Limit Switches
//
#define X_STOP_PIN 18
#define Y_STOP_PIN 19
//#define Z_STOP_PIN 20
#define Z_MIN_PIN 20
#define Z_MAX_PIN xx // should have a pullup to +5V
Very few people actually use both a Z_MIN and a Z_MAX endstop.
X, Y & Z are needed to home the printer. X_MAX & Y_MAX are used incase you're worried about a print going out of bounds. Z_MAX is rarely used.
Fairly soon you'll find out that your bed has enough ripple & tilt that getting good first layer adhesion on a large object is hard to do. The answer is to use one of the bed leveling systems but it's hard to get all the features you want plus bed leveling into the memory available in a 1284. Please consider using a 2560 based controller.
A 2560 + RAMPS + LCD display will cost you about $30 and should arrive in a week.
The printer at the moment uses the Z axis for homing.
I have implemented the above code, then SanityCheck.h gave an error saying that XMIN_PLUG or XMAX_PLUG must be defined, so I just commented it as below out and it compiled.
Then using Pronterface I tested it out, and the Z axis will not move up at all, then I move it down, then it won't go up again. Here is the error:
@ReaganLawrence May I ask what is it you are concerned about? I think what Bob is asking is that he wants to know how exactly you are using it. His other suggestions is using another free pin on the board, which you can do as well.
Are you using it as a "normal" 3D printer? Since you are not using the x_min endstop, how will you make sure the printer will know where the home (X0) position is?
Another suggestion is that if your concern is that your print might exceed the Z height, then look in configuration.h and edit your Z_MAX_POS to whatever height (in mm) you require. Most printers come with "maximum build dimensions" so that is something you usually take in consideration when you create a CAD.
// Travel limits (mm) after homing, corresponding to endstop positions.
#define X_MIN_POS -50
#define Y_MIN_POS -40
#define Z_MIN_POS 0
#define X_MAX_POS X_BED_SIZE
#define Y_MAX_POS Y_BED_SIZE
#define Z_MAX_POS 200]
You got rid of the sanity check for X. That makes sense for your system.
The Z movement problem you're seeing is because the Z_MAX endstop is always triggered. M119 will confirm that.
Either you have a wiring problem or the Z_MAX_ENDSTOP_INVERTING definition in Configuration.h needs to be flipped between true and false.
Setting Z_MAX_ENDSTOP_INVERTING to false fixed it! Thanks for the help guys.
The printer is a DLP resin printer with the Z axis how the build plate moves, and the Y axis the projector movement. Currently X axis does nothing hence why I wanted to use the X endstop. The problem with just having a Z min was that people were going out the top and their machines and completely breaking them, hence the need for a Z max. We are implementing more features that will go on a secondary microcontroller so if a X endstop is ever needed (which it is with current R&D).
Don't go too cheap on your controller. It'll cause headaches down the road and is a very small part of the overall printer cost.
I suggest Atmel AVR2560 based boards as a starting point. They usually have all the I/O you'll need. A 2560 & a RAMPs board will costs about $20-$25.
If you need more computing power then consider LPC176x or Due based boards. Those will cost you in the $50 - $150 range.
If you're rolling your own controller then consider the LPC1778. Low cost, 32 bit, lots of I/O and with lots of compatible software already out there.
Decided it would be best not to use the X endstop in case it is needed. Then tried connecting 2 microswitches in series and putting them both in the Z endstop, however the second microswitch acted as a min endstop (complete oversight).
Now trying to use the spare pins. Preferably don't want to use PWM, Tx or Rx, so that just leaves SCL and SDA. However I cannot find what pins these correspond to. Doing my research tells me SCL and SDA are 22 and 23 respectively, however this source has X/Y/Z endstop as 24, 25 and 26 respectively, yet the pins_SANGUINOLOLU_11.h had them as 18, 19, 20 so I don't think the source is reputable.
Depending on how you configured the endstops, that should be expected. I believe even if you wired in parallel you would get the same result. (because you are still using the z_min).
Enable #define PINS_DEBUGGING
in configuration_adv.h and run M43 on your printer host. You should see a list of all your pin configurations (PIN # = to whatever is assigned). Then, as for physically locating the pin itself, you will have to somehow look for a wiring/pin diagram of your board.
If you know what you're doing (not sure how safe this is, but this is what I do). You can manually "test" pins by using M42 and a voltmeter. Probe for pins with one end and another on the ground. M43 will also show you the state of each pin.
M42 P(pin_number) S255, which reads a HIGH signal M42 P(pin_number) S0, which reads a LOW signal
In parallel both switches needed to be triggered to stop the stepper i.e. series = or gate, parallel = and gate.
Will try that in the morning when I go in, but that seems to be exactly what I need, thanks!
Works perfectly! Thank you so much for your help guys.
Hi kcheeeung. I'm fascinated by this post of yours. I have been trying to achieve the same thing for a while now. But being completely new to 3D printing and coding in general this has been a massive undertaking for me. After reading all the comments from the yourself and the other posters I gather you were in the same position as me but with the help of everyone you have managed to get this to work. Unfortunately whilst I understand you got it to work. Would you be so kind in explaining in detail what to edit in the marlin code to get the this additional functionality? I would like to add 2 additional axis using T1 and T0 steppers. If you could write a guide to doing this I'm sure it would help out a lot of people. Thanks a lot.
Hello @Gizmo6. I can very well help show you what files to change, but it might be helpful to describe what you would like to achieve with these additional "axes" so we can understand what works best. (in what application?)
Hi Kcheeeung, Thanks very much for replying! Ok the best way to describe my custom machine is it's very similar the types of vending machines you find with the XY axis product picking arm. (Not the ones with coils) only in my machine I also use the T0 and T1 as axis's in order to push the product out to a buyer and to push a new product forward into the old ones space. I am running a Ramps 1.4 board with all the endstop MIN ports taken to be used for the standard XYZ. What I would like to do is have the T0 and T1 behave in the same way as as their XYZ counterparts. I have no heating elements in my machine so all the hot end and hot bed settings have been disabled. (Using the dummy temp settings) My machine is currently working (using hand typed G-code scripts) but the T0 and T1 is simply just counting steps backwards and forwards this means my machine, over time or error loses its T0 and T1 home position ( I need to manually position :( ) What I would like to achieve is for example to be able to use G28T0 and G28T1 to home the additional axis's before the machine starts so it can be aware and adjust its original position. All my endstop MAX are free.
I am running a configured version of Marlin 1.1 for my distinct needs.
From reading your OP it sounds like it's very similiar to what you were trying to achieve and managed it. Any help would be greatly appreciated.
Like yourself I was just looking through the endstop.ccp but as I have no coding experience this is beyond my ability.
Any help at all would be fantastic! I've searched this topic so much and so many people asked the question but you are the first I have come across that seems to have managed it. I look forward to any advance you can give me :) (in the form of a tutorial would be best if its not too much to ask)
Thanks a lot.
Hi Kcheeeung, Not sure if you have had time to take a look at my provided information yet. But any help would be appreciated. Thanks.
@Gizmo6 Sorry for the delay. I was a bit busy, but I will have something for you soon. (Some things have changed in the code so I need to see what's different)
It sounds like is that: You will need 2 endstops because there are two motors (one pushing in and one pushing out). I will be using the latest Marlin 1.1.x file as the base file.
Thats great. yes I already have it all at hand and so whenever you are ready that would be great. Thanks a lot.
Hey Gizmo6, check this out. I have also tested (the E_MIN_PIN) on my own system as well to make sure it works, and it does. https://drive.google.com/drive/folders/1Gx6dZbY0tmwlZpTs4cCw9eQ199yqr_2p?usp=sharing
Based on the latest Marlin 1.1.x, can just move these files into your own folder. I'm not sure if making a tutorial would be that helpful because there's a lot of things to add and might be confusing to those who aren't familiar with the Marlin firmware itself.
Depending on your endstop configuration set inverting to false/true.
False will be setup as COM to ground and NC to signal.
I have setup these files in a way that your Y_MAX_PIN and Z_MAX_PIN PORTS are the new X_MIN_PIN. The Y/Z_MAX_PIN was just moved to pin 2 to serve as a dummy. You can also remove or comment it, but you'll need to do the testing on that.
You can also change it to E/F_MAX_PIN instead, but this will change the way you write the g-code.
//
// Limit Switches
//
#define X_MIN_PIN 3
#ifndef X_MAX_PIN
#define X_MAX_PIN 2
#endif
#define Y_MIN_PIN 14
#define Y_MAX_PIN 2//15
#define Z_MIN_PIN 18
#define Z_MAX_PIN 2//19
#define E_MIN_PIN 15// Uses the Y_MAX_PIN PORT
#define F_MIN_PIN 19// Uses the Z_MAX_PIN PORT
These "axes" we created actually have a "shared instance" in that they all use the "E axis." Even if you change the "T0/T1 axis" the E position is actually still saved so you have to use G92 to set the position in order move the amount you intend. Earlier I have mentioned that whether you choose min or max as the pins you define will change the way you write the g-code. There isn't a direct way to use the G28 to "home" the new axes. We will just need to be clever in the way you write it.
T0; this selects the T0 stepper
G92 E999; set the axis to position E999
G1 E0; move to position E0
**(as it's moving, you will hit your endstop)**
**(motor stops)**
G92 E0; set the axis to position E0, your home.
**commands to move T0 however you want**
Let me know how it goes. And a lot of credits to Bob as well in helping me out originally.
Hi kcheeeung, THANKS A LOT FOR THIS!!! I will have a play with this set up and come back to you. Even though its not a tutorial it's very well laid out and I very much appreciate your efforts :) Thanks again.
Hi Kcheeeung. Thanks a lot for this. However it won't compile for me. Please see the error message.
**Arduino: 1.8.2 (Windows 10), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"
sketch\stepper.cpp: In static member function 'static void Stepper::isr()':
stepper.cpp:433: error: 'class Planner' has no member named 'discard_continued_block'
if (!planner.discard_continued_block()) // Discard next CONTINUED block
^
exit status 1
'class Planner' has no member named 'discard_continued_block'
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.**
As I didn't understand what you had changed i'm not sure where to go from here. I have attached my working version of marlin, Maybe if you have some time you could check the issue?
The attachment is my own configurations without your additional files.
Marlin-1.1.x - TFT SCREEN UPDATE - CURRENTLY WORKING - Copy.zip
I know I'm asking a lot but if you have some time its much appreciated.
Check the google drive link again. I have updated to use your version of the Marlin. Copy/paste the files into your folder now. The guide is still the same. I was able to compile it, but haven't tested it. It's very likely that it should work.
The compile error came from the difference between versions, specifically the latest 1.1.8, and the developers have changed some features/code since then. The first edits I have done are specific to 1.1.8 and usually "mixing and matching" files across versions don't work.
To easily see the difference between the edited files, if you have git (do a git diff) or just use an online diff checker.
Hi kcheeeung,
Thank you very much you have been extremely helpful. I managed to get it working as in the endstop will stop the motor movement but what I cannot do it to get the endstops be separate controllers. No matter how I change the settings they all behave as one. Is there a way I can use one as a MAX and one as a MIN? I understand that the E will be seen by the system as a single unit but what I would like to do is to see if I can have them engaged separately. So I can position it in a way where for example a MAX could stop T1 and the MIN could stop T0. If you have explained it already above I do apologies for my noob questions. I really do appreciate your help so far.
Hi kcheeeung,
Thanks a lot for your help. I just wanted to update you on my findings. Firstly thanks a lot for your assistance. I never did get the switches to behave properly as a max and a min. Both switches operate as one no matter what configurations I set. This is not a huge problem as I have written the G-code so that the T0 spin until it hits the endstop then backs away. This leaves the firmware to believe the endstop open which allows for T1 to trigger its endstop. (By moving the away from the endstop it resets it for the next) it works GREAT. ....
BUT it only works when the rest of the axis (ZXY) have not been homed yet. Once they have been homed the T0 and T1 Endstops no longer works and I'm back to square one. I could get around this by doing the T0/T1 homing first before homing the rest, but currently I need to reset the system before the T0/T1 endstops work again.
Do you have any ideas on how to address this?
Marlin-1.1.x - CURRENTLY WORKING E-Endstop compiled with issues.zip
@Gizmo6 You just have to change the word from MIN
to MAX
in RAMPs.h (the code that is already written in). Axis position moves from SMALL to LARGE with a max configuration.
// Two slashes comments a line of code out in C/C++
#define E_MIN_PIN 0 // You have E_MIN enabled.
//#define E_MAX_PIN 0 // See the "//" in the front. The E_MAX is disabled because it's commented out.
//#define F_MIN_PIN 0 // Disabled.
#define F_MAX_PIN 0 // You have F_MAX enabled.
Thanks for pointing out and confirmed you findings. Homing the XYZ first will render the "E axes" unable to home with the E_MIN/MAX_PINS. On a fresh reset, homing the "E axes" is possible. I haven't tested in extensively as I'm using a minimal test board.
My knowledge might be limited in terms of the Marlin firmware, but I will attempt to understand and find a fix or new implementation for this endstop/E axis that can be used in conjunction with the XYZ axes. It would be more functional with the ability to properly home XYZ, then the E axes or even make it behave like a XYZ does when it homes.
@kcheeeung Thanks a lot. For your reply. Just wanted to let you know your input has been much appreciated. :) please update me if you manage to find anything.
@kcheeeung Hi, Did you ever manage to find a solution to the E Axis issue? I would be curious to know. :)
@Gizmo6 Sorry for the long delay. I was trying to see what I could do on the 1.1.x, but I don't think I quite got it unfortunately.
Hey guys. What do you guys think in terms of making the E_AXIS behave like the XYZ in terms of homing? In the previous method, we found that the e_min/max_pin would outright not work anymore if XYZ is homed first.
What I was thinking was to follow the X_AXIS codes in its homing ability (via G28) and copy/add some of that over to the E_AXIS, responding to the e_min/max_pin. I was able to get the file to compile, but on testing, the E_AXIS motor just stutters. Is there a better solution and I must have missed a place or improperly edited some of the code?
Hey guys. What do you guys think in terms of making the E_AXIS behave like the XYZ in terms of homing? In the previous method, we found that the e_min/max_pin would outright not work anymore if XYZ is homed first.
I think I would like this. As part of my ending GCode in Slic3r, I have it retract 5mm or 10mm of filament. Assuming the nozzle is hot, I think I would like to see it prime the nozzle. But that is a big departure from what has been done in the past and would need some discussion.
Hey @kcheeeung, seems like a good idea. One quick thing, I too am stuck on this issue as I am working on a project that requires 4/5 axes with end stop capabilities. I just wanted to ask if you had a download of the required files to implement this? All the links posted previously on this thread seem to be broken.
Thanks for any help!
@Roxy-3D And yea, it would be very cool if you could enable a feature that would allow you to home both of the extruder axes, it would open up a whole new set of possibilities beyond just 3D printing too
Hello everyone. I would like to create a "4th axis" using the extruder stepper motor. In the current 3D printer setup, we have the XYZ positions using either XYZ min/max pins. I would like to use one of those extra pins such that I can achieve this.
Current setup is that each XYZ min/max pins, when activated (configured to stop only the XYZ axes respectively), is to stop the stepper motor from moving, which is what I am looking for. I would like a way such that the "4th axis" knows when to stop without crashing or damaging the system.
What's the best way of doing so? I have attached an image to demonstrate what I am trying to do.
Thanks for reading.![untitled](https://user-images.githubusercontent.com/24723501/33112309-6c8ae4aa-cf07-11e7-894f-3de83b1d4cc5.jpg)