Giter VIP home page Giter VIP logo

Comments (142)

fschill avatar fschill commented on August 16, 2024 4

FWIW, I also have a clone of grbl-Mega on my github account: https://github.com/fschill/
I extended it to 5 axis control, and made the tool offsets work for all axes, not just Z (on lathes I need offsets for X and Z). Also working on a simple, real-time GUI for semi-manual operation, running on a raspberry with touch screen - haven't published it yet, but planning to do so soon.

from grbl-mega.

fschill avatar fschill commented on August 16, 2024 4

Success! I wanted to get something going first before starting to overcomplicate things. The feedrate control was already working quite well even across varying spindle speeds. So to synchronize the start, I simply added an extra bit of code to the Dwell command (G4): if in G95 mode (feed in units per rev), execute the dwell, and then also wait for the spindle to cross zero before proceeding.
With this it's now possible to write threading GCode, eg.:

G0 X1 Z0 ; go to start position
G95 ; Feed per revolution mode
G0 X-0.5 ; go to cutting depth, clear of workpiece
G4 P1 ; Dwell and wait for spindle sync (in G95 mode)
G1 F1 Z-20 ; start threading pass
G0X1 ; retract at end of move
Z0 ; end of pass

Doing repeat passes lines up pretty well with the previous cuts. It's best though to keep the spindle speed the same - it still works with different speeds, but due to the acceleration ramp in the beginning, they don't line up quite as well. I took some videos, will upload them as soon as I have time.

The current state is in my fork in branch "spindle_sync". I think it's a good basis, already does something useful. Further modes can be built on top. Beware, it's still early beta, doesn't do any safety checking (e.g. if spindle speed or resulting feedrate is too high), and may damage your equipment. Feel free to test it, but at your own risk :) Be careful.
(edited - sorry, was logged in with another account...)

from grbl-mega.

fschill avatar fschill commented on August 16, 2024 3

Before this thread derails too much, I'd like to keep it focused on the original topic: Lathe pulse input for threading, i.e. software sync of an open-loop spindle, for grbl-Mega (as this is a thread on the grbl-Mega repository). (Also, I'm not going to buy your software, and I'm not a windows user...)

Any suggestions by the maintainers would be much appreciated, particularly to avoid integration issues later. @chamnit if you have time, can you give me some pointers about the bigger picture?

Regarding encoder ticks/rev, it remains to be seen what the minimum is to get good results, and it will obviously vary depending on the lathe and RPM stability. The easiest would probably be a super-high res encoder (>500-1000 ticks), so that it's enough to keep track of the spindle position with an interrupt, and just query the position and speed at any update step. To make it work with lower-res encoders, and at slow RPM, interpolation is required to fill the gaps between ticks. This is more work on the software side, but would make it more flexible. It may require two different versions, as the interpolation method might be too slow for a 1000-tick encoder signal. I think it's a matter of getting started somewhere, and testing what works, and what precision is achievable. 1 tick/rev is most likely not enough. 4 ticks/rev as on my machine is probably borderline - I think on my machine the speed variations within a quarter revolution are fairly small, but smaller machines might have more trouble. But given that 20-30 step/rev are fairly easy to do with a variety of methods (magnets+hall sensor, DIY optical encoder with lasercut or hand-cut wheel, etc.), it would be worth trying to get an interpolation method to work.

In any case, I see three separate functions:

  1. a module to measure and report spindle position and speed at any time (either interpolated or direct),
  2. extending the motion planning to execute precisely timed motion segments,
  3. a higher-level canned cycle for threading, that breaks down the gcode into lead-in, feed and lead-out segments.

I think 1) is completely independent of everything else. 2) would probably have to go either into the stepper update interrupt (if fast enough), or one layer above into the "st_prep_buffer".
3) is at the same level as arc interpolation in the planner, and fairly straight forward once 2) works, I think. Any opinions/feedback on these thoughts?

from grbl-mega.

fschill avatar fschill commented on August 16, 2024 2

Hi HuubBuis,
I've read your comments above. It is certainly a way to do it, and has additional advantages if one wanted to go further (mill-turning, indexing, etc.). But for now I'm looking for a software solution: essentially, implementing the tapping cycle as it is defined in GCode. My spindle encoder has 4 pulses per revolution, and as it's a fairly heavy spindle, and RPM-controlled motor, the speed is pretty constant. I think it will be ok to interpolate the speed and spindle position in software. And if not, it's relatively easy to mount a higher resolution encoder. I don't want to mess with the existing motor (230V 1.5 kW), so doing closed-loop with that is not so easy. Also, it's a V-Belt so it won't keep good sync for very long I'd think. I could mount a separate motor and a clutch system, but that's a major hassle. Also, I'd like to run automated repeat cycles, so having to manually switch over for threading would be annoying.

Regarding a software solution, the nice thing is that it's only some work to do once, and then anybody can use it immediately. Mounting an encoder is easy (maybe it's already there anyway), and threading is a super useful feature. It's also a major reason to convert a lathe to CNC, because it's then easy to do any thread with out having to change gears. And it's even possible to cut conical gears, e.g. pipe threads.
I had a closer look at the code, and my current best approach angle is to tap into the "plan_compute_profile_nominal_speed" method in planner.c. It already gets called by st_prep_buffer regularly from what I can tell, and testing the feedrate override, it gets applied fairly instantly within line segments. The comments say that the segment buffer holds 40-50msec of steps, so one would have to take some latency into account. For adjusting the feed, it might be ok, assuming that the speed is fairly constant, and that threading is done at fairly low RPMs normally. Syncing could maybe also be done there. It would require taking time into account, and explicitly predicting ahead and aligning the execution of line segments with the spindle position (closed loop speeding up/slowing down the feed to get into sync during lead-in). As the acceleration limits have to be observed, it would have to be done at some planning stage before the actual stepper loop I think, as sudden jumps in the stepper outputs would be problematic.
My current thought is that the motion primitive to aim for is "reach a certain position with a certain speed at a given point in time in the near future". The tapping cycle could then be built on top of it.
I'd appreciate further ideas or suggestions where the best place would be for this, or any other ideas that would help.

from grbl-mega.

fschill avatar fschill commented on August 16, 2024 2

Ok, I made some progress (still some way to go though). For those who are interested, my current state is in https://github.com/fschill/grbl-Mega (spindle_sync branch).

  • I added an extra module for reading the spindle encoder, measuring speed and current spindle position. Still to do: interpolated position. At the moment I'm only using the current speed.
  • added timekeeper.c/h for measuring time, using HW timer 5, with 4 us resolution. Used for spindle speed measurements
  • added support for G95 (feedrate per revolution mode). This set an extra flag in plan_line_data_t and plan_block_t (had to change the condition variable to uint16_t, as it was fully used already). The flag is evaluated in plan_compute_profile_nominal_speed to compute the actual feed rate based on spindle speed. The initial value for spindle speed is taken from the gcode (M3, etc.). During execution, protocol_execute_realtime calls spindle_sync_update from spindle_sync.c, which updates the spindle_speed in the planner blocks with the actual measured spindle speed, and re-plans.

I've only tested it on my desk so far, with an encoder handwheel, watching the outputs on the screen. It seems to work, insofar the reported feedrate and the coordinates correspond in speed to the handwheel. I'll still need to test on the lathe to see how well it tracks. I do not expect it to be perfect, and I'm planning to do closed-loop feedback with the feedrate to keep it in sync with the motion progress.

What is also still missing is a synchronisation to the absolute spindle angle, to be able to do multiple passes and hit the start of the thread. I think this should go into a G33 cycle that flushes the queue and waits for the right moment to start. Reading the LinuxCNC documentation, it seems that G33 always hits the start at the zero angle (index position of spindle). I don't know if it's possible to define an angle offset directly - it could be done by moving the start position if there is enough space for lead-in.

Potential issues:

  • due to the minimum feedrate requirement, it still moves (slowly, at minimum speed) even if the spindle is stopped. This can be dangerous. During a G33 cycle, we can check at the start if the spindle has the right speed (close to the last M3 S--- command), and throw an error if the speed is wrong. If speed drops too much during execution, or gets too fast to keep up, aborting is tricky, if the spindle is not controlled by GRBL, as simply stopping can be disastrous too. Checking at the start should be sufficient though.
    Another approach would be to issue a hold command if the speed drops below the minimum speed, and resume if it speeds up again. Being able to completely stop and resume could be useful for manual thread chasing, or for rigid tapping in the future, but it's not so easy to do it precisely.

from grbl-mega.

shooter64738 avatar shooter64738 commented on August 16, 2024 2

Hey all! I meant to get back to this a couple days ago and comment, but just didn't get a chance.

Couple of things I have ran into that might help others (to not make the same mistakes)

  1. High resolution encoders seemed like the way to go. Lower priced encoders are pretty small making the optical slots close together. Vibration on high res encoders cause a tremendous amount of erroneous 'bouncing' This causes the angle to eventually get completely lost. The controller thinks the spindle has moved but its just picking up signals caused from the encoders internal wheel bouncing. On a lathe with a heavy chuck and spindle, this may be less of an issue, but its really been a killer on a mill spindle, even if its mounted to the drive motor.
  2. High resolution encoders suck the life out of the avr running grbl. A 600 ppr encoder running quadrature mode produces 2400cpr. Somewhere around 3000rpm grbl spends more time trying to handle the interrupts from the encoder than it does in motion. So in general, using either one channel from the quadrature, or just a lower res encoder would actually work better to some degree.

I was never able to completely solve issue 2, and I was pretty bummed by the 4th or 5th time working through it on the bench only to have it fail in practice. So I went with a separate board (a nano) to control my spindle. Since it has very little to do, it can handle a pretty high count rate from the encoder. A simple formula translates encoder ticks per rev into a step pulse value. So for example every 7.2 encoder ticks, I need to send a pulse to the grbl system pin, which causes grbl to run through the motion code one time. This did create the need a gcode parser on the nano to get the programmed feed rate and mode, along with spindle speed and direction.

I do think an index is going to be needed so that if the encoder position does get lost at some point, it would never be in error more than one revolution. This could go beyond the scope of a hobby cnc system though.

I'll get the changes I made to grbl up, and you can see how it worked better. The majority of the work I did was on a separate controller, and I haven't gotten to work on it much since April. I have written so much code trying to get this to work, I've pretty much ported the entire grbl project to c++ in fragments. @fschill the only concern I would have with your approach is overloading the avr with other ISR tasks. There probably is a way to keep it all on the grbl board but I was never satisfied with the methods I tried. If you have it working pretty well on a bench, put your encoder on a drill and run it at 2000 rpm and see how it does. I know some systems use only the programmed spindle speed to set the feed rate (assuming the spindle is right) and others read the spindle rpm at motion start (and assume it stays there). Obviously the best approach is reading it constantly and adjusting as needed.. Its a simple and complex problem all at the same time!

My upload of grbl is here: grbl 6 axis synch. Its far from done for sure. Most of my changes are in planner,stepper,system, and I added rtc.h and rtc.c Hopefully it will be useful to other people, this is by no means the only way to do it..

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024 1

Google on "open source CNC controller"
https://buildbotics.com/
http://smoothieware.org/
https://www.thunderclap.it/projects/60431-open-source-cnc-controller
https://openbuilds.com/threads/openbuilds-apex-controller.9186/

and there are more!

from grbl-mega.

109JB avatar 109JB commented on August 16, 2024 1

@HuubBuis Good luck with your software, but it is not a viable solution at least for me to use a stepper to power the spindle. I have a lathe that threads with a single pulse input per rev already using LinuxCNC, but would love to use Grbl on my lathe. A stepper powered spindle also requires using a separate control scheme for cutting and for threading and a change between stepper power and whatever the other spindle drive is. An pulse input for threading eliminates the need for 2 different control schemes and all the switching and has been proven to work on countless installations of other machine control software (LinuxCNC, Mach 3, Turbo CNC, etc.)

I also have my doubts as to whether a stepper powered spindle can have enough torque. Sure you have been able to cut threads, but how big, and even the lightest threading cuts on a large diameter will require a good amount of torque. For a stepper based solution that would require multiple gear ratios between stepper and spindle.

as far as:

If GRBL has to synchronize, it would not only cost more programming power put also additional code. And there is no room for extra code on the Arduino.

You do realize this is posted in the Grbl-mega issues forum and the mega has plenty of room for additional code and plenty of pins. Also, another user is already working on an encoder based solution that I think has great promise. Instead of using the arduino clock to time the step signals, it uses the interrupt from the encoder to do it. A wonderfully simple concept. I'm hoping he's still working it.
#58

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024 1

@109JB @fschill

No i was not aware this is the xmega thread.
With a stepper on the spindle, any cnc software can do threading.
I do Cr42Mo4 M40 with 2Nm stepper.
Thanks for the encoder/interrupt solution, great idea.
I get the impression my contribution is not appreciated. I will unsubscribe.

from grbl-mega.

shooter64738 avatar shooter64738 commented on August 16, 2024 1

(I edited this because I think I have a better idea than when I first wrote it:))
Ok at 4 ticks per rev, that would be kind of low resolution, but honestly I think that could be plenty. What if we took your idea and my idea and we mash them together.

  1. Use a separate control for the spindle. It reads the pulses from your encoder, and determines rpm of the spindle. Since you have 4 sensors you have 4 reads per rev.
  2. After one rev on the spindle control, send the rpm to grbl via a serial connection. Use an upper end character like char 254 to precede the rpm. grbl would know when it picks this up its an rpm from a spindle control. In G95 mode, grbl will not start motion until it gets this rpm value from the spindle control. The spindle control can have a set rate of updating the rpm, of say 10hz. Regardless of the encoder being used, it will send the rpm at 10hz to grbl. It wont send the first one until its made a complete revolution to get its first rpm, and then when it either rolls to spindle angle 0, or the index pulse is hit. This should keep thread starts pretty consistent. And if we need more than 10 updates a second, I'm pretty sure we could go to 100 pretty easily without loading grbl much.
  3. Low res encoders wont/shouldn't be an issue because grbl is interpolating/predicting the feed rate based on the rpm at a frequency of 10 times per second. Even a 100cpr encoder would be plenty because the feed rate would get adjusted 10 times per second. That seems plenty to keep up with a threading operation.

You could scale down the encoder outputs so that even a 2400cpr encoder wont send a pulse from the controller to grbl more than 10 times per second. The way I've been going about it, I was driving grbl with encoder pulses instead of timer ticks. Which may work eventually, but a low res encoder would give threads on a lathe that look like tiny stair steps. If we interpolate as your are planning, low res encoders wont be an issue.

from grbl-mega.

fschill avatar fschill commented on August 16, 2024 1

Hi,
just a quick update - I had a chance to test it on the lathe just now, with a sharpie drawing "threads" on bar stock. It looks pretty good already, even though it's just trying to match the speed without closed-loop position tracking. It even keeps up while changing the spindle RPM from 100RPM to 500RPM and back, drawing a fairly regular looking "thread" (although I saw a little bit of unevenness when changing the RPM too quickly, and also was hitting the max feed of 800mm/min on my Z with a 2mm pitch). But the principle is sound, it works. During real thread cutting the RPM changes won't be that big anyway. I'll try to post a video soon, but I'm quite busy this week.
I think once I add a synchronisation point for the lead-in (within a G33 cycle), it might already be usable if precision is not that important, and if the spindle speed is fairly slow and constant.

@shooter64738 : I'm not sure if I fully understand your suggestion. I think with low-res encoders such as mine, there is no problem measuring the spindle speed in GRBL directly (as it's working pretty well already). For high-res encoders I can see a use for an intermediate controller that downsamples the encoder (although one might also just get another encoder with less ticks). I'm not sure if sending additional things through the UART is going to help - it will introduce additional latencies if trying to adjust to varying spindle speeds during the cycle. As it will need an electrical pin anyway for the start synchronisation, it seems overly complicated to me.

from grbl-mega.

fschill avatar fschill commented on August 16, 2024 1

uploaded a video showing the various stages of progress: https://youtu.be/Ia_g6kpPqtE

from grbl-mega.

fschill avatar fschill commented on August 16, 2024 1

@Kukuzca Yes, on my lathe I also use the original spindle motor. I do not have a high-res encoder, I just used the existing sensor of the RPM display, which generates 4 pulses/revolution. My software synchronises a timer to those pulses, and then interpolates the speed and angle. More pulses are of course better, but it works quite well even with just 4 pulses/rev. What I haven't tested yet is what maximum pulse rate the Arduino can cope with - at 4 p/rev and 1200 RPM it's no problem, but that's all I know.
Regarding the drive of the steppers: I think I know what you mean now. I have not implemented G33 yet (some more explanation in this comment above: #26 (comment))
I foremost use GRBL to run my lathe as a CNC machine, the treading is a little add-on that I'm still working on (but don't have much time for right now). I didn't want to bypass GRBL's motion planning system, as that would make it difficult to maintain coordinate frames, ensure acceleration ramps, etc., so all motion still goes through the regular motion planning. I tapped into the feedrate control, similar to the feedrate override, to achieve spindle-synchronised feed.

What I have implemented is explained here: #26 (comment)
Essentially, it's just a G95 (feedrate per revolution mode), which means that the speed of movement is relative to the spindle speed. F 1.0 in G95 means 1mm movement for each revolution. It can also be used for regular turning - you're directly programming the chip thickness, basically.
For threading this is not enough, unless you only do one pass. To have a simple solution for the start, I just modified the G4 command - if in G95 mode, it will wait the given delay, and then also wait for the spindle to cross zero degrees. This makes it possible to do repeat passes that line up in the same groove. Note that it is not perfect, as it only controls the feedrate, and does not "lock" absolute position to spindle rotation (still needs to be done). But I've cut some threads with it, and it works as long as you don't change the spindle speed or anything.
More recently I also added a non-standard "R" parameter to G4, to wait for arbitrary angles (e.g. G4 P1 R90 should wait until the spindle reaches 90 degrees). I haven't tested this mode very much yet - seems to work, but not sure how precise it is.
On my machine (and most lathes afaik), the z axis is the one along the bed (parallel to axis of rotation), and the x axis is the cross slide. The G95 mode applies to total feedrate along any axis, so you could also turn a "spiral" along the X axis with it, or conical threads (but be aware that the pitch along Z is not the same as the pitch along the direction of movement...).
I hope this helps. If you try it out, I recommend testing with a sharpie first...

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024 1

I have implemented a G33 spindle synchronization for threading in the GRBL-Mega version. The code is based on the @fschill G95 spindle sync version https://github.com/fschill/grbl-Mega/tree/spindle_sync except:

  • it uses an index pulse so the spindle can be stopped (after the threading pass) and turned in any direction.
  • synchronization pulses to improve accuracy are optional.
  • it uses current GRBL input pins (Y-Limit and Probe) so existing GRBL shields can be used.
  • it synchronizes on spindle rotations (not speed) so errors are not accumulated and long threads can be made
  • it calculates and reports the actual synchronization error (mm or inches) to monitor the threading quality.
  • between passes, spindle speed can be changed

By shifting the start position, multi start threads can be made (Shift 1/2 pitch for a 2 start thread).
By calculating the pitch over the tool path (Z:X) tapered threads can be made.

There is a Wiki with an explanation for the users and an explanation of the threading code for those who want to adapt their grbl (mega) fork.

I am working on a version for the Arduino Uno. I think, if I strip all not lathe related code, it will just fit. This Arduino Uno release is targeted for October 2019

see Grbl-L-Mega

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024

I do threading on my lathe using GRBL and a stepper (Nema 23) on the spindle controlled by the GRBL Y-axis. It works using unmodified GRBL V1.1.

from grbl-mega.

X3msnake avatar X3msnake commented on August 16, 2024

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024

Here you find all drawings, pictures, electronic designs and documentation for all my lathe modifications:
My Lathe

For software I use (my own) CNCL

Any question please ask

from grbl-mega.

X3msnake avatar X3msnake commented on August 16, 2024

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024

There are a few GCode senders (https://github.com/gnea/grbl/wiki/Using-Grbl) together with a cam program that supports GRBL, you are ready to start, but no threading. All other software i have found are based on their own (some times GRBL based) hardware solutions. That makes CNC on the lathe a bit expensive for most of us.
For mach3 there are lathe extensions, but they also are expensive. Then there is the printer port that is not supported under windows 10.
Linux CNC is also a way to go, but i didn't find good support for the lathe and they also need a printer port.
There is an opensource controller (http://smoothieware.org/) i looked at. I could make the board my self but it would be more expensive than the arduino boards and it needs a gcode generator/sender.

I now have a small tablet, wireless connected to the lathe, can do treading and lot of cool stuff and can still uses any other GRBL compatible software, hard to beat! Nevertheless, I check weekly the internet for affordable CNC lathe solutions but until today without success.

from grbl-mega.

fschill avatar fschill commented on August 16, 2024

Hi,
I'm using GRBL on my lathe now, and am also interested in threading/spindle synchronisation. My lathe already has an encoder on the spindle for the RPM display, and I'm hoping to be able to do threading without having to install another servo motor and clutch system. It's a mid-sized lathe, and such a conversion would be a major project.

  • Does anyone know if there have been any attempts (open-source, available) to extend GRBL with spindle sync?

  • If I would tackle this myself, can you give me some hints where in the overall structure would be the best place to insert it? I'm still trying to understand the detailed workings of the motion planning. My current assumption is that it would have to go into the planner. The spindle-directed speed could maybe be handled similarly to feedrate override, or by adjusting the current feed rate on the fly. The synchronisation is trickier, as it needs to plan in the lead-in and lead-out, as well as the acceleration ramp, to come out at exactly the right place once it hits the proper feed.

  • is there already a fork that has a spindle encoder input for other purposes, e.g. closed-loop RPM control? If so, it would probably be a good idea to start there, so that the wiring and overall code structure is consistent.

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024

I use GRBL and do threading by adding a stepper on the spindle axis. It is controlled by the GRBL y-axis. Now threading is just adding some rotation when the Z-moves and that is handled by GRBL. Until now I used a Nema 23 , 2 Nm stepper. Recently I upgraded (for the wrong reasons) to a Nema 24, 4 Nm stepper. This way i have no synchronization problems and it a lot more accurate than using a single pulse synchronization.
I think 2Nm is enough because i mostly make small parts. For the larger threads, is just takes a bit more time, but it's runs automatically so who cares.
Besides threading i know can also do knurling using a cutting tool, grinding (drills, mills, slit saw disks, etc) broaching and more.
The stepper is engaged by a lever. For normal turning I still use the original spindle motor.
For drawings, pictures and documentation look at: My Lathe
Your encoder for the spindle probably only has one pulse. You could consider adding a separate encoder and closed loop controller (depends on the motor). Then it would just look like a stepper to GRBL. I considered doing this, but the cost would be high and the gain just more torque during threading. Most of the time I can't even run the 2 Nm stepper at higher speeds due to the deflection of the small parts I make.

from grbl-mega.

tklus avatar tklus commented on August 16, 2024

That is great news! I have been patiently waiting for this...

I have an extra pi that I could use for testing this out once it’s published

Thanks for all the hard work...

I am hoping to start converting my lathe soon

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024

I use tool offsets on all axes but don't have a tool changer. So for me, engaging the stepper by the leaver isn't a problem. If it was, i would put an actuator on it.
If GRBL has to synchronize, it would not only cost more programming power put also additional code. And there is no room for extra code on the Arduino. The atmega port, i think, is also maintainded by Chamnit. There you have more memory and pins. I think that is a better to start with. Chamnit, the developer is busy changing the code so porting GRBL to other hardware will be easier. After that he will probably port GRBL to arm.
There are more open source stepper controllers that have support for threading and spindle synchronization. The problem is their boards are "expensive", but maybe, like me, you can build your own boards. Having a look at their code could also bring up some ideas.
My lathe as a variable speed spindle. Due to its low torque, synchronizing with only a single pulse would definitely give bad threads at the first rotations. I would definitely need more synchronization pulses. I think 100 will do!
You are building a gui on a raspberry. I considered a raspberry also, but decided for a 7" tablet. I now have a small screen, touch control, WiFi and Bluetooth connection for 70$. I can't build this, that cheap, based on a raspberry. And the software on the tablet (windows 10 App) also runs on a PC without modification.

from grbl-mega.

X3msnake avatar X3msnake commented on August 16, 2024

from grbl-mega.

fschill avatar fschill commented on August 16, 2024

silly question (maybe): I will need a way to measure elapsed time accurately (at least relative to the stepper ISR). I can't find any way to get current microseconds or anything like that. Does that exist already, or do I have to add it? I'd add a counter to the stepper ISR. Just realised though that the refresh rate of this may change (at least if AMASS is disabled). Any easy way to find out the current ISR rate, or alternatively, is AMASS ever turned off, and can I just assume a constant update rate?

from grbl-mega.

fschill avatar fschill commented on August 16, 2024

@109JB thanks for the link to the other thread - was not aware of it (which is why I asked if anyone is already working on it). Will read and see how to proceed.

from grbl-mega.

bsherman100 avatar bsherman100 commented on August 16, 2024

I'm very excited that work is being done on this, I am looking to adapt a AS5147 to my lathe.

https://www.mouser.com/ProductDetail/ams/AS5147-EK-AB?qs=sGAEpiMZZMvxVoyCXc2K7r%2f0QHff57jdQtyR0Erk%252brE%3d

from grbl-mega.

X3msnake avatar X3msnake commented on August 16, 2024

@HuubBuis that's just your impression your input is welcome.

from grbl-mega.

109JB avatar 109JB commented on August 16, 2024

@HuubBuis It is not that your contribution isn't appreciated, It is just that not everyone agrees with your approach. If it works for you that is great, and if it even works for someone else, that is great too. Not everyone is going to agree with you all of the time. Don't take it as that your contribution is not appreciated. Not everyone has to agree all the time. Do you ever disagree with your friends, or family?

from grbl-mega.

fschill avatar fschill commented on August 16, 2024

@109JB looking at the other thread by @shooter64738, I think it's an interesting approach, but will be limited to high-res encoders to work. For rigid tapping quite interesting, as the spindle needs to accelerate anyway, and then reverse, but for threading there remains the problem of accelerating the Z axis for repeat cycles, to hit the thread start again. Not an easy problem. It's one of those features that seems simple at first, until you start looking into the details :)
There were also some good ideas regarding encoders. I was going to simply keep count of the encoder ticks to maintain absolute spindle position, but an index pulse would be useful too. While running, counting would be enough, but when stopping and restarting, turning the spindle by hand, etc. it might lose track with a single pin low res encoder. For rigid tapping, we'd need quadrature encoding too, to detect reversal, but for the lathe it's not needed I think. Also an interesting idea from that thread was to have a special tooth on the wheel for index, that way only one sensor/one pin is needed. I'm considering to modify my magnetic encoder by putting two magnets next to each other for a longer index pulse. But for now I think I'll start with single-pin input, everything else can be added later.

@HuubBuis everyone's contribution is appreciated. You already described your approach, and it's great, but not for everyone. I had some specific questions, regarding the topic of this thread, and just repeating what you already wrote earlier didn't add additional information. I also found it strange that when someone is attempting to implement a new feature for this open source project, that it seemed like you are trying to argue against having this feature at all, while pushing your own solution that you sell as non-open source (nothing against doing that, software is work that should be paid). But there's a time and a place for marketing, and these issues/threads here are the time and place for questions regarding this project (as indicated at the top of the page), not other projects.
Btw. I was also wondering where the place would be for collecting information about related projects that don't really fit into "Issues", like other GUIs, hardware, etc. related to GRBL. Are there lists in the wiki? Couldn't find it.

from grbl-mega.

X3msnake avatar X3msnake commented on August 16, 2024

from grbl-mega.

fschill avatar fschill commented on August 16, 2024

thanks for your comments! On my lathe I actually only have 4 ticks/rev (magnetic sensor, 4 little magnets in a ring on the shaft sensed by a hall effect sensor). This was already built-in for the RPM display that came with the machine. I checked with the oscilloscope, and it gives a clean, stable output. It's not a symmetric signal though, it is normally high with short low pulses when a magnet goes by. So I think this will be ok regarding signal quality and interrupt load. For getting the exact spindle position, it will require time-based interpolation though, and it is less quick to pick up spindle speed variations. I was planning to do closed-loop progress tracking, and fine-tune the feedrate to keep the tool in sync. At the moment I only adjust the speed, which could accumulate drift over longer distances. We'll see how well it works - I think for short threads with a constant spindle speed it might already be enough, but would be nicer to guarantee good tracking. Directly coupling the steppers to the spindle encoder would be more precise, but then we have to worry about obeying acceleration limits, and would need a high-res encoder.

Regarding index pin, my thought is to keep it as flexible as possible. If there is no index pin, it will just keep counting. I see the biggest risk here when using only a single-channel encoder without index or quadrature, and stopping the spindle, e.g. to check the thread. Maybe it's a matter of documenting clearly what the limitations are for single-channel encoder w/o index, with index, with or w/o quadrature, and regarding number of ticks/rev.

The ISR load on the AVR is a good point. For testing, I actually also have a 600 line encoder on my desk, but no motors attached so I can't really see how smooth the motion output is, and if there is any stuttering. And of course no vibrations. I only use the falling edge in the interrupt, so that can help to reduce the interrupts/second, and I'm only using one of the channels for now. Instead of having both channels on interrupt, you could also get the direction with one interrupt and simply reading the other channel. If that is not enough, we could also consider to impose an RPM limit for threading (I thought that mostly this is done at a few 100 RPM at most), and refuse a G33 command if the RPM is too high. Any other time the interrupt could be turned off, or we could only use the index pin interrupt at high speeds for RPM control.
I was actually thinking of taking a second arduino to count the stepper pulses and encoder ticks, and forward this to my PC for plotting, as a debugging tool. Just reading off coordinates doesn't really show any potential issues.

from grbl-mega.

109JB avatar 109JB commented on August 16, 2024

I am only a rank amateur when it comes to programming, and you guys are obviously much better than I, but I would like to contribute as this spindle sync issue is the biggest thing preventing me from converting over to Grbl completely. That said, I have a few comments:

  1. in regard to spindle rpm, whether using a separate MCU to read RPM or not, I think you need to program in a comparison between successive RPM readings before and sync move is made. The reason I say this is because you need to make sure the RPM has stabilized before starting a sync move for many reasons. As one example, my lathe spindle uses a treadmill motor and controller and has a soft start feature where the motor ramps up to speed. From a dead stop to full speed can take several seconds. Obviously spindle sync for threading isn't going to be at full speed, but the slow accel is still there.

  2. As for counts per rev. I'm not at all sure about the intricacies of it, but can say that LinuxCNC can do threading with only 1 count per rev (index). https://www.youtube.com/watch?v=jHKmcjoCyLg and the same is true for the older DOS based turboCNC http://www.dakeng.com/threading.html , and also Mach3. I am not opposed to anything that works, just wanted to point this out. The one reason I can see for trying to get this working on a single pulse per rev is because there are those out there that already have a 1ppr setup working on other control software and if they want to try it with Grbl, then Grbl would have to support this if possible, or they would have to change their encoder setup.

  3. as far as encoders, many LinuxCNC, Mach3, TurboCNC users have made their own encoders
    http://7xcnc.com/hardware/encoder/
    https://www.homemodelenginemachinist.com/threads/mach-3-spindle-encoder.15226/

from grbl-mega.

fschill avatar fschill commented on August 16, 2024

@109JB
thanks for your input. Regarding your points:

  1. I agree. I'm coming from computer science and self-taught machinist, so I'm learning how "pro" machines do it from others, and from youtube videos... For now I only implemented G95 mode, which simply adjusts the feedrate based on spindle speed to do constant-width cuts. By itself it is not enough for threading, unless you do it in one pass. For a proper threading cycle (G76), as far as I understand, the sequence would be:
  • bring spindle up to speed (if it isn't running already)
  • go to a "waiting position", far enough away from the thread start to give the machine time to accelerate to the right cutting speed
  • check spindle speed, and verify that the cut parameters are within the acceleration limits and speed limits of the machine. Abort and throw error if not.
  • execute lead-in move, accelerating the axes to the right speed. This should be planned carefully, so that the tool will reach the start of the thread, going at the correct speed, just as the spindle hits the "zero" mark. This is probably the hardest part. As a fallback, it might be enough to just start with the zero pulse, and always use a constant-length lead-in so that it's at least repeatable throughout the multiple passes, even if the thread would not start at the zero angle in this case.
  • execute the actual cut segment, while actively adjusting the feedrate to always match the spindle. It might be necessary to also track the progress through the cut vs. the revolutions of the spindle, as it might drift apart over long cuts due to slight speed mismatches and rounding errors
  • execute a lead-out move to get the tool out of the thread at the end
  • return to start position, repeat for n cycles with increasing depth, and finishing passes.
    Repeat passes could be explicitly coded in GCode, it would be enough if GRBL supports a single pass as long as it can reliably hit the start point.
  1. I wasn't sure what the minimum pulses per rev are to make this work, but good to know that it's in principle possible with just one. I can confirm it's working with 4 pulses. As long as the spindle speed is nice and steady, it shouldn't be a problem - the main issue is at the start of a cut, when the spindle is suddenly loaded down and might slow down significantly within one revolution. Taking light cuts can help here. I'm certainly in favour of making this feature work with as many setups as possible, and keeping the conversion work as simple as possible.
    An advantage of a single pulse per rev is that it's also the index pulse. With more ticks comes more ambiguity, but I'm hoping that it's possible to keep count at least during a single run. Doing re-cuts after a spindle stop or end of program could be more tricky without an index pulse.

  2. thanks for the links.

from grbl-mega.

fschill avatar fschill commented on August 16, 2024

Maybe a stupid question: For G33, (basic threading command), is the pitch parameter (K) always relative to the Z-axis, or to all axes/total distance traveled? It doesn't say clearly in the LinuxCNC docs, but it seems to me that it's always relative to Z. For example, when turning a tapered thread, the pitch would be the same as for a non-tapered thread, even though the tool moves further. This would be slightly different to G95 mode, where the 3D feedrate is proportional to the spinde, so the z-pitch would decrease on a tapered cut.

Does anyone know how this works? What happens if someone would issue multiple moves in G33 mode? It appears to be a modal command, so it should be possible. Can I assume that for every line with a G33 ... K... on it, the machine waits for the zero sync and "engages the nut", i.e. locks the Z-axis to the spindle? And if it's additional moves in G33 mode, but without a new G33 on the line, it just maintains that virtual lock, as if it was mechanically still coupled? What happens if the second move is in the opposite z direction than the first move (reversal)? Is this an error?

from grbl-mega.

tklus avatar tklus commented on August 16, 2024

Great work! This will push me to get my lathe converted :D

from grbl-mega.

109JB avatar 109JB commented on August 16, 2024

Absolutely awesome!!!! I do have one complaint though. Where the heck were you the past several years. I have been waiting for someone to tackle this to make Grbl useful on a lathe for some time but I unfortunately didn't and still don't have the skills to do it myself. Thank you, thank you thank you. I'm sure there will need to be more testing, but this is very exciting. I sold my 7x10 CNC'd lathe, and acquired a 9x20. I guess I need to get it cnc'd now ;)

Again, fantastic work, but I do have a few questions.

  1. what type of "encoder" would be suitable for your mod. My 7x10 had one like the one I previously posted.
  2. Are you using a hardware interrupt on the Arduino? Just one?
  3. I think you mentioned that your "encoder" didn't have any index, so are you constantly tracking the spindle so that the thread sync always works? For example, lets say you exit G95 mode and then go back in. Would the sync still track trace the previous thread, or would it possibly be off 90,180 or 270 degrees with your 4 pulse encoder?
  4. Are the coding mods something that could fit on an UNO or NANO? Possibly by eliminating one of the no longer needed axes?

from grbl-mega.

109JB avatar 109JB commented on August 16, 2024

Also, do you feel that once flushed out a bit more that this is something that could be added to the mainstream branch?

from grbl-mega.

fschill avatar fschill commented on August 16, 2024

@109JB yeah, I know the feeling ;) I only just converted my lathe to CNC. My milling machines were CNC converted from the start, but for the lathe it wasn't that pressing, as most parts can also be machined by hand. For me it was actually the real-time jogging feature in GRBL that I was waiting for, as I still want to use it in "semi-manual", using the steppers as motordrive and DRO. I'm also working on a hand-wheel based on a high-res encoder (600 lines) for "fly-by-wire" manual machining - I like the analog feel of hand wheels.
Funny thing is, I never actually cut a thread on my lathe, as I was always too lazy to change the gears. Now that it's CNC, I figured that this should be a thing of the past now...

Regarding the current version: Yes, it absolutely needs more testing, and there could still be some surprises and bugs. Caveats I know about:

  • The current implementation is very basic - it keeps track of spindle speed and adjusts feedrate, and there is a way to wait for the spindle to move through zero (interrupt keeps count of revolutions, and it waits for revolutions divided by #ticks/rev to tick over). It does not account for acceleration times, so when repeating a pass at a different spindle speed, it will be slightly shifted.
  • it does not keep track of total distance travelled vs. revolutions of the spindle, so there is a possibility of drift. For short threads it should be ok, but don't try to cut lead screws...
  • there are no safety checks if the machine can actually execute a command. I think it might even run feedrates beyond the GRBL settings at the moment, I stalled my steppers occasionally.
  • G95 mode adjusts total feedrate relative to spindle. Good: works in all directions, could eg. cut spirals in X. Bad: when cutting tapered threads, the pitch is not the same.
  • potential bug I just realised: the encoder tick counter is 16 bit, and can overflow. This should be ok if the encoder has 2^n number of ticks (like mine), but would create problems otherwise. ToDo: fix the overflow

Regarding your questions:

  1. I'm using what my lathe came with: a collet on the spindle shaft, with 4 little magnets set in, and a single hall sensor that is connected to the RPM display. The sensor pulls low when there is a magnet, so I configured the interrupt for falling edges.
  2. I'm using hardware interrupt INT4, on "digital pin 2". Just one for now. I think regarding the concerns about CPU load, one interrupt should be enough even for quadrature encoders. For index pin support we could use a second interrupt, as it's only once per rev.
  3. yes, the encoder ISR is constantly keeping track of the spindle encoder counts, and divides by number of ticks/rev to get revolutions. For now there it calculates speed based on elapsed time between ticks, but doesn't do any angle interpolation. It wasn't necessary for now as I only start at zero, and the feedrate control of GRBL takes care of smooth motion between.
    I haven't tested what happens if you leave G95, but I think it should still track a previous thread. The only danger I see is if I stop the spindle, and maybe reverse it or get jitter if it happens to stop on a magnet. An index pin would definitely be a useful addition, but I think it's good if it also works without (with maybe some limitations).
  4. I don't know regarding UNO/Nano - it seems to be pretty maxed out. I tried to keep my changes as separate as possible, but I did have to go into GRBLs core in some places. One issue is probably that I'm using HW Timer5 for time keeping - don't know if the UNO has another spare timer, but it certainly doesn't have a timer5. What would be the benefits of supporting the UNO? I guess there are shields around for it, but for my lathe I can't use the tiny stepper drivers anyway, so I needed to make my own breakout.
  5. After some more testing, I think that could be done safely. As long as one doesn't use the G95 mode (or later, G33/G76), everything else should work normally. Maybe the spindle encoder interrupt could be switched off by default to avoid any issues with CPU load, and lathe users would have to explicitly set a define to turn it on.

Things still to do:

  • add a configuration setting for the spindle encoder. Number of ticks and polarity of edge are currently hard-coded, this is obviously not good. (for testing, you can set this in spindle_encoder.c).
  • add safety checks, and abort if commands cannot be run with the given values
  • add support for G33, with compensation for acceleration times, and absolute pitch tracking in Z. Also, afaik this is what Fusion360 generates, so it would be good to have support for this out of the box.
  • I think G76 is not really needed, but could be added later.

from grbl-mega.

terjeio avatar terjeio commented on August 16, 2024

Interesting "thread" - I have started work on spindle sync as well and plan to continue my work on that soon. I too have started with G33, I calculate the angular position from encoder input and use that in a PID-loop to adjust the segment timing. This is a test result from 15 passes or so:

img_8480

Also, I want to control my lathe (an old Emco 5) from a MPG pendant so I am currently working on that - I want to use it in "standalone" mode - without firing up a PC. I am going to implement some basic operations, such as threading, by entering data in on-screen dialogs and then let the pendant control the lathe:

img_8515

from grbl-mega.

shooter64738 avatar shooter64738 commented on August 16, 2024

@fschill I think if you just had an index pulse, you could turn the timer on in g95, and turn it off when in g93 or g94. The ext interrupt could also be turned off unless in g95. grbl could run as 'normal' even at high feed rates pretty easily even with a high res encoder. I still dont think a high res encoder is needed. :) What you have there looks pretty good for threading. I haven't gotten to take much of a look at your code yet, but all the 'issues' listed previously could be over come fairly easy. I also don't think a quadrature encoder is needed. In G95 mode any rotation of the spindle regardless of direction should cause the controller to move towards its end point. The program would know the direction of the spindle based on the m3/m4 code. If you were to turn it by hand some amount, when you started the spindle again and went to cut another thread pass, if it didn't start motion until it hit the index, it would still start cutting at the same place.

With a low pulse rate (say something below 64 because its a nices 2's comp value) the pin change interrupt might work just as well and you could assign the encoder pulse and index pins all over the board instead of the ext interrupt. I think pin 2 on the uno is taken up for a stepper pulse pin, but I could be mistaken. There is also the issue of needing another timer, which I think is used in the uno version as a step pulse delay option. I moved to the mega board for other reasons, but there are a lot of uno board users out there as @109JB stated.

Also I believe Mach3 is known to have issues on threading passes if the spindle speed is changed due to its acceleration of the axis motion too. One way around it is to have enough lead room that by the time the thread starts to cut, the axis is beyond accelerating and is in it full speed stage. You might be able to shorten that time up by changing the acceleration rate in g95 mode to a higher value. That would limit the take off velocity of the axis because it has less time to accelerate.

All in all, it works. It may have some limitations, and if that stops someone from using it, well they can thread with a die and a T handle :) I like it. Makes me wanna build a lathe.

from grbl-mega.

109JB avatar 109JB commented on August 16, 2024

I like the idea of having an index pulse even if it means needing another pin interrupt. As @shooter64738 said, when not threading there really isn't a need to keep the interrupt going. I'm sure it running slows the rest of grbl down, so shutting off the interrupt while still being able to turn it back on would be nice to have.

As for the UNO vs Mega, I don't care that much really. More curious than anything. I do have more nanos and Unos lying around than Megas, but I have a couple of those too, so not a big deal to me. Just thought that since there are fewer axes that it could possibly work.

from grbl-mega.

Jimbobfrank0 avatar Jimbobfrank0 commented on August 16, 2024

Even on a lot of professional cnc machines changing the spindle speed after a cut will result in a different thread being cut. This is very good work it seems I have started to build my lathe at about the right time.

terjeio that is a very nice looking pendant and dro.

from grbl-mega.

terjeio avatar terjeio commented on August 16, 2024

@Jimbobfrank0 : Thanks, nice looks does not compensate for a working brain - giving it one is hard work as I aim for a completely event driven GUI.

A few observations:

Feed hold should be postponed until a threading movement is complete, stopping in the middle of a pass is bad/dangerous? Even wait until retract is complete? This needs to be handled in grbl as it is a signal input as well as a real-time command. I am a newbie when it comes to lathe work so I might be wrong, anyway I am bit scared of the lathe...

I miss a real-time command for cancelling a job gracefully when holding - I like the way I can do that in Mach 3. I think a reset is a bit over the top.

Any views on this?

from grbl-mega.

fschill avatar fschill commented on August 16, 2024

@terjeio Good point about feed hold. I already set the flag for "no feed override" for commands in G95 mode, as that is equally dangerous, but have not done anything about feed hold. Not sure at the moment how realtime commands could be queued - one could completely ignore it, but I do like having feed-hold always working as a safety feature. Obviously during threading it would ruin the piece, and maybe the cutting tool as well. For now, and for myself, I'm happy to just not trigger feedhold at such times. Waiting until after retract would not be possible in G33 I think, as it doesn't define a retract position. In G76 it's possible to do a "retract and hold", maybe even in the middle of the thread. Resuming from hold would be trickier - safest would probably be to repeat that pass from the start. It would get pretty complicated though.

Regarding cancelling during hold - that would definitely be good. Not sure, i thought it's possible but need to check. I also had some issues recently where it got stuck in hold during a jog that should already have been terminated, and resuming resulted in unintended motions. I do need to check my GUI though as well, could be a problem on the PC side. The current jogging mode with realtime-abort does have some issues, it's not easily possible to cancel and override current jogging motions, as would be nice for cursor-key based realtime jogging like in linuxCNC. I got it working pretty well, but there are very rare glitches, and it's not possible to transition from an active jog on one axis into a diagonal jog on multiple axes. Minor quibbles though.

from grbl-mega.

109JB avatar 109JB commented on August 16, 2024

Feed Hold - One could argue either way. Sure it is bad if the axes stop moving during a sync move. It will ruin the cut at a minimum, probably scrapping the part However, what if the axes don't stop until a sync move is complete? Maybe the sync move has the Z axis running right into the lathe chuck. Maybe the operator is hitting feed hold during a portion of the move where no material is being cut. One can think of a whole slew of possibilities either way.

In any case, what occurs on other machines must be weighed carefully when talking about Grbl. The way that Grbl operates with GUIs and the streaming protocols means things can happen in unconventional or unexpected ways. For example, on most machines, a "feed hold" will not stop a sync move, but a "program stop" will. Grbl has no program stop command or pin, but it does have a "reset/abort" command and pin. However, invoking it while the machine is in motion results in an alarm, and a loss of position. So, many GUIs first invoke a feed hold, wait for the machine to stop, and then reset as a work-around. Works great, but if feed-hold is disabled during a sync move, then the machine never stops, and the reset never happens. I can't see a way around this. If the machine doesn't stop when the operator expects, this could be more dangerous than a ruined part or broken tool.

Bottom line, I would vote to leave feed-hold active during synced moves.

@terjeio Why would you consider a soft-reset "over the top"? A soft-reset is no big deal on Grbl. It isn't like re-booting a computer, machine position isn't lost as long as it doesn't happen during motion, takes just a second, and flushes the buffer and any other stagnant stuff. Really just think of it a a "return to defaults" command rather than a reset, because that is essentially what is happening. Easy peasy.

from grbl-mega.

terjeio avatar terjeio commented on August 16, 2024

@109JB : I consider a soft reset "over the top" when holding for the reasons you give. Why should I have to cancel the resulting alarm and worry about the position beeing lost? When I do a feed hold followed by a stop in Mach 3 neither does the computer or Mach 3 restart ( a bad analogy, I know). And there is no alarm to cancel. Smooth.

Wanting to use feed hold to stop the z-axis from hitting the chuck is perhaps indicative of something amiss in the protocol? I would hit the eStop button when something is about to badly wrong, using feed hold should not be they way my brain should get trained to react in such scenarios (because I want to avoid a reset?).

@fschill : I have modified handling of jog cancel so that it flushes the serial and input buffers, this to ensure jogging motion reliably stops. I have no jogging buttons in my gcode sender GUI, I use the keyboard - and have successfully coded for 3-key rollover support. No glitches so far, even when abusing the navigation buttons, touch wood. Similar to Mach 3 jogging action can be modified by <Ctrl> and <Shift>, this for step and fast mode.

Feed hold during jogging is for what? I think it should be ignored or result in jogging beeing cancelled. Or is jogging regulary used for movements doing cutting actions? IMO as one famous person puts it: "Bad".

I think cancelling during hold can be done safely in a similar way to how my jog cancel behaves, flush the serial buffer, the input buffer and the motion buffer(s). I will at least try to implement such a feature for myself. I will also try to implement a delayed feed hold when executing spindle synchronized motions, I am not going to be the only user of the lathe so dangerous actions has to be blocked. It believe it should be fairly easy to implement - ignore the status flag until it is safe to act upon it.


I have forked grbl-mega and backported the changes I have done to jog cancel, I have also added code to support a secondary input stream - this to allow use of MPGs like the one I am working on. Available from my github account. Be aware that I have not subjected this to the same stress tests as my ARM port.

from grbl-mega.

109JB avatar 109JB commented on August 16, 2024

@terjeio -

Why should I have to cancel the resulting alarm and worry about the position beeing lost?

I am not sure what you are talking about. My implementation of Grbl does NOT alarm, and does NOT lose position if a soft reset is invoked when the machine is not moving. If the machine is in motion when reset is invoked then yes it triggers an alarm due to possible loss of position, but not if care is taken to stop motion first.

You say you have implemented a routine to flush the input and planner buffers. If this accomplishes what you want then all is good.

Wanting to use feed hold to stop the z-axis from hitting the chuck is perhaps indicative of something amiss in the protocol?

No, you miss my point. There is not "program stop" in Grbl, so Grbl's feed hold is used by GUIs for implementing one, but if you disable the feed hold for sync moves you will essentially disable the "program stop" implementations as well. This could be far worse than the benefits of disabling feed hold during sync moves as program stop should work regardless of what the machine is doing. This is what operators expect.

I would hit the eStop button when something is about to badly wrong, using feed hold should not be they way my brain should get trained to react in such scenarios (because I want to avoid a reset?).

It depends. The emergency stop is for just that, an emergency. If it isn't an emergency then there is no need to use the emergency stop. Just because a tool is heading toward the chuck doesn't mean that it constitutes an immediate emergency. It may be several seconds before it gets there and a program stop would be more than appropriate. However, if disabling feed hold has disabled program stop, instead of a simple matter of having to invoke a program stop you are now forced to use an e-stop for what was not an emergency. That is what I am opposed to. This has to do with how Grbl interaction takes place.

My emergency stop is implemented so that power is cut to the entire machine requiring re-powering, homing, possibly re-zeroing, etc. All of this because the only way to stop during a sync move would be to e-stop.

I am not going to be the only user of the lathe so dangerous actions has to be blocked.

I agree that dangerous actions need to be blocked, and if you feel what you propose is better for your situation, with your GUI and your custom Grbl, then all is well, but you are assuming that is the case for everyone and that cancelling motion during a threading cut is a dangerous enough situation to warrant disabling feed hold. I contend that not being able to cancel motion during a threading cut could be even more dangerous.

In my opinion the danger of stopping motion during threading is almost exclusively to the part and the cutting tool. Whereas, disabling a method of stopping motion could create more danger to the machine in general and to the operator as a result. There is no reason that existing GUIs can't use this newly created sync move right now because it is simply a matter of streaming the code. However, depending on how the GUI is written, this proposed disabling of the feed hold could break what is supposed to happen because of how the GUI is written. In the current release version of Grbl, feed hold works all the time no matter what, regardless of what the machine is doing, and GUIs have come to expect this behavior. Changing this expectation could have more disastrous effects than a broken threading tool or scrapped part.

Also, consider a machine with a safety door. The operation of the safety door has to stop the machine. In many cases, this is a regulation requirement. The way the safety door is implemented in Grbl is to tie the safety door switch to the feed hold pin of Grbl. Therefore, disabling feed hold during any move will disable the function of the safety door. Now I don't have safety doors on my machines, but this is an example of how a seemingly innocuous change can have unexpected results.

All I am saying is that while there may be benefits of disabling the feed hold during a sync move, it is not simply a matter of doing it without considering all of the ramifications. Perhaps what needs to be done is create another parallel realtime function that essentially does what feed hold does, but cannot be disabled. Maybe call it a "persistent feed hold" or something. Then one could be disabled during sync moves to satisfy those that need it, while maintaining one that stops no matter what. Or maybe a define in config.h so the user can select how he wants feed hold to function. I just don't think it would be a good idea to implement disabling it during sync moves as a default behavior without a way to override that selection.

from grbl-mega.

Jimbobfrank0 avatar Jimbobfrank0 commented on August 16, 2024

On a normal cnc lathe feed hold while threading retracts in X out of the threads then returns to thread start point in Z. When start is hit again it will recut the last thread.

from grbl-mega.

109JB avatar 109JB commented on August 16, 2024

On a normal cnc lathe feed hold while threading retracts in X out of the threads then returns to thread start point in Z. When start is hit again it will recut the last thread.

I would be all for this type of feed hold implementation during thread cutting. It would still be necessary to investigation what ramifications making a change like this would have overall, and might not be trivial.

from grbl-mega.

fschill avatar fschill commented on August 16, 2024

On a normal cnc lathe feed hold while threading retracts in X out of the threads then returns to thread start point in Z. When start is hit again it will recut the last thread.

I think this is the best option. All the GRBL realtime commands should always be active, and for consistency always do the same thing. We could consider adding a non-realtime "program hold" that will finish the current command and then stop, if we really want such a thing.

Some things to consider though: G95 isn't really a threading command, it's simply a mode to specify feedrate in units per revolution. This is quite common for lathes it seems, also for normal cuts, as one can simply enter the desired chip thickness. Considering this, feed hold should just do feed hold, as it would be quite reasonable to do all normal cutting in G95 mode.

G33 is a bit more closely related to threading - it locks the axis to the spindle at all time, and guarantees synchronisation at the start. Note that for now I haven't implemented this yet, and cheated a bit by simply adding a "spindle sync wait" to the Dwell command as a workaround. However, G33 would still not be enough to implement a "smart feed hold" with a retract and repeat, as the command has no clue if it's an internal or external thread, how much it can retract, etc.
For that we need to implement the G76 canned cycle, which has all those parameters, and takes care of multiple repeat cycles, retracting, etc. Internally, G76 is translated into a series of G33 and G0 commands.

I think for now we can consider the current state as "beta - usable, but beware, and don't press hold". I think Fusion uses G33 (need to check), or maybe depending on the post processor also G76, so in the long run we should aim to make GRBL compatible with this, to have a seamless workflow (I assume by now Fusion is the go-to for almost every hobbyist - not aware of any free open-source alternative at the moment, and other CAM packages are quite expensive).

from grbl-mega.

shooter64738 avatar shooter64738 commented on August 16, 2024

This might be better handled as a canned cycle, but further it might also need to be split up. If one were to retract and move the Z to a home position for threading on a lathe, that would be ideal. But on a mill, I would prefer it not move the X axis if I hit feed hold on a boring/tapping cycle. :) In a mills case, it would just need to stop, a lathe would be slightly different it seems. Perhaps its time to add a setting for turning vs. milling and allow them to behave as they should for their respective machine.

I could use what @fschill has right now as a means to create a canned cycle for rigid tap. The G95 ability is what would give me that. On the mill I would want to slow/stop the spindle as I approach and reach the Z target. Then set the Z target to the retract height of R or old Z and start the spindle in reverse.

I'm not as familiar with the lathe operation, but I believe in that case you would thread to the appropriate Z target, then retract X and return Z to home.

One fadal machine i used will perform a feed hold with the tap halfway in a hole. One of the others I used will not. There is no feed hold on that machine during a rigid tap, but there was on drill cycles. My guess is, it gets complicated in there trying to keep all of that in synch and some control firmware can, and some firmware cannot, depending on its age and the hardware it runs on.

If one were running plane jane G95 a feed hold would be a feed hold. and if you were using that to cut threads on a lathe, yea it would ruin your threads. Same as it would if I were using G95 to thread a hole with a tap. If I hit feed hold on a mill with a tap in it, the spindle would keep rotating and strip my threads or pull my part out of the holder. I would think the canned cycle or G code given would dictate what its actual operation is, and what it could/could not do during a feed hold.

Ok I took too long responding, so basically, what @fschill, @109JB all said. 👍

from grbl-mega.

fschill avatar fschill commented on August 16, 2024

@shooter64738 actually, after reading your thoughts, I guess the clean way for feed hold on mill as well as lathe is: stop the spindle, and wind down all other axes in sync with the spindle slowing down. On a purpose-built machine (Fadal, etc.) this can be guaranteed, but with GRBL everyone does it differently, and on some machines the spindle switch might not be controlled by GRBL (my machine, for example).
So the issue remains, that we can't assume that the spindle will stop, and feed hold has to work at all times. There is also the issue of completely stopping motion when the spindle is stopped - as GRBL requires a minimum feed, it never stops completely. I tried to insert a feed hold automatically if the spindle speed is zero, but I think it didn't work (need to check again, can't remember what the current state is).

Regarding behaviour between mill and lathe: rigid tapping is a different GCode to threading, so it could be implemented next to each other.
As was said above, I think hitting feed hold accidentally during threading/rigid tapping will break the tool and ruin the work, but not much more in almost all cases (unless cutting some really big threads, maybe). So the users that don't heed the warnings ("DON'T push feed hold during those cycles"), re-education will happen automatically... ;) who hasn't broken a tap...

from grbl-mega.

109JB avatar 109JB commented on August 16, 2024

All the GRBL realtime commands should always be active, and for consistency always do the same thing.

I agree, but am not opposed to alternative behavior if it makes sense. As noted, not everyone implements Grbl on their machines the same way, and some, myself included have written their own GUIs to fit their own needs on that end. For this reason, perhaps an override to feed hold during G95 or other synced motion as @terjeio suggested should be implemented but as a define that can be set in the config.h file like so many other things in there. However, I would still vote to have the default setting for this to be feed hold working all the time.

On a normal cnc lathe feed hold while threading retracts in X out of the threads then returns to thread start point in Z. When start is hit again it will recut the last thread.

I too think this is the absolute best option for lathe threading but don't see it as absolutely necessary. It also seems like this would all have to happen within Grbl, and would have to be tied to a G76 command rather than G95, since the parameters included in G76 would be necessary to define which direction to retract in X (internal/external threads), how far to retract, etc. I suppose the Mega has plenty of space to define a G76 canned cycle but the cycle would need definition as well as the alternate feed hold behavior. Just thinking out loud here.

from grbl-mega.

terjeio avatar terjeio commented on August 16, 2024

@109JB : sorry for my comment about grbl entering alarm when a reset is issued. It is due a modification I did a year ago to my branch - I have to revisit that. Perhaps I will add another input signal for eStop that triggers a reset and then enter alarm state. As it stands now grbl has no way of knowing whether eStop is active as far as I can tell. Is currently the best practice to pull the MCU reset pin low when eStop is active, thus halting the processor?
Going back to the master code I see there is a configuration for whether grbl enters alarm state at boot-up, I think that should always happen if the reset signal (or eStop) is active.

As for disabling feed hold then this can be implemented by a M-code, as per linuxcnc spec: M53
Adding support for M49 - M51 could also be useful?

As I understands it grbl tries to implement functionality in a similar vein as linuxcnc, perhaps it should be checked how the complexities around threading are handled there?

from grbl-mega.

109JB avatar 109JB commented on August 16, 2024

@terjeio - The config.h settings that force Grbl into an alarm state only does so for a hard reset or a power cycle. It does not place Grbl into an alarm state during a soft reset resulting from invoking a ctrl-X command.

In regard to how LinuxCNC handles things, I use LinuxCNC as well as Grbl and have a virtual machine with LinuxCNC. I can report the following regarding how LinuxCNC implements a few things based on running the LinuxCNC simulator in the virtual machine.

G95 using LinuxCNC - Both feed hold and program stop work immediately during the synced moves while in G95

G33 using LinuxCNC - Feed hold is delayed until the end of the G33 move, but program stop works immediately stopping the spindle stops and all axes.

G76 using LinuxCNC - Feed hold is delayed until the end of that cutting pass but program stop works immediately, stopping the spindle and all axes. This makes sense since G76 is essentially a bunch of G33's

Based on this, LinuxCNC does delay a feed hold during G33 or G76 presumably to not ruin the thread, However, since what @fschill has only implemented a G95 thus far, it seems that leaving feed hold alone at this point fits what LinuxCNC does regarding feed hold during G95 moves.

If G33 or G76 are implemented, then it may be prudent to follow LinuxCNC convention and have feed hold wait until the end of either a G33 or G76 move. I really don't see an issue with leaving feed hold to immediately pause. I'd just personally remember to not hit it during the threading cuts. If others really want this though I am not opposed. However, since this would potentially break a bunch of GUIs and how program stop is implemented in them I would vote to leave the existing feed hold as is for existing GUIs, and create a new feed hold that waits until the end of the move for use in new GUIs that want to use this behavior.

from grbl-mega.

terjeio avatar terjeio commented on August 16, 2024

@109JB : Many thanks for the info about how linuxcnc works, useful for me as I am trying to implement G33. I am making good progress on the pendant GUI so hopefully I will soon be back at the lathe for real life testing.

As for the reset I have added a new signal (input pin) for eStop so I can boot the system and provide feedback to the user. I do belive the way I implemented this will not break exsisting GUIs, and it should be safe provided that a active eStop signal also cuts power to the motors. To be tested...

I find it a bit strange that a active reset signal is ignored at boot up, IMO this indicates that there is a fault condition that should be addressed.

from grbl-mega.

109JB avatar 109JB commented on August 16, 2024

I find it a bit strange that a active reset signal is ignored at boot up, IMO this indicates that there is a fault condition that should be addressed.

I'm not sure I completely understand what you mean above. If you are referring to the soft-reset behavior vs. the hard reset/power cycle behavior, it seems the difference in behavior was by design. It has been the recommended practice for flushing the buffers for many years. Here is one post where the developer recommends this procedure for buffer flushing

grbl#195

I find it a bit strange that a active reset signal is ignored at boot up,

If you mean to imply that Grbl will ignore a reset signal on the Grbl reset pin, then I would have to say that I have not tried this but would think this would place Grbl into a reset loop until the pin is cleared.

What I was referring to is a reset that occurs from invoking a ctrl-X command. On the subsequent boot there will be no active reset condition.

As for disabling feed hold then this can be implemented by a M-code, as per linuxcnc spec: M53
Adding support for M49 - M51 could also be useful?

The above is from your previous post. I re-read and realized that I had wanted to reply but didn't.

M49-M50 and M53 - Although there is are LinuxCNC specifications for these, there are not RS274-NGC specifications. Also consider that these command can have different meanings on different machines. For example, on an Okuma mill, M53 specifies the retract plane for canned cycles. Looking at an Okuma list, there doesn't appear to be a command to disable feed hold. Personally, when working as a CNC machinist for several years, which included quite a bit of hand programming (I'm getting old), I never remember an occasion where I placed a M49-50 or M53 in any program I wrote in this context and I don't ever remember encountering this in any program I ever ran. I can't really think of a good reason to place this in a program except for not trusting an operator to use feed hold or override appropriately. In that case the operator is probably not qualified to be at the machine. In any case these are not commonly used commands.

M53 specifically - Implementing it without other changes would still cause problems with existing GUIs because feed hold is commonly used in GUI implementation of program stop. I guess what I am trying to stress is that any change to how feed hold works can affect other things that other users or GUI creators, etc, have implemented, including, but not limited to program stop.

I realize that it may seem like I am just putting down your ideas, but that isn't my intention. I actually would like to see some times when feed-hold doesn't happen immediately, like during a cutting move in a G33 or G76 cycle. but only if it doesn't break existing functions. In that vein, I think I may have a proposed solution.

I suppose that possibly the easiest path to implementing this could be to use the existing "!" feed hold character as it currently is and always active. Then a new realtime character could be implemented which could be used to trigger the same feed-hold routine but only when appropriate based on M53, G33, G76, etc. That may be the cleanest solution as it doesn't change the existing feed-hold function at all but adds a new one that can be implemented however a user sees fit. This would guarantee that the current feed hold doesn't change and therefore any GUI using it doesn't have to change their operation, but a new GUI can choose to use the new one, or the old one, depending on what the particular need is.

from grbl-mega.

109JB avatar 109JB commented on August 16, 2024

@fschill - So I decided to get a pseudo-lathe going the quick way so I can try out your code. I plan to outfit my mill spindle with some optical switches to act as a spindle encoder and mount an R8 lathe chuck to try things out. I plan to do something similar to this http://7xcnc.com/hardware/encoder/ but can alter the number of slots that are in the disk. I plan to use 2 optical switches with one for index in case it can be used later. This brings up a couple questions:

  1. Does your code always keep track of the encoder pulses even when not in G95?

  2. I seem to remember your setup had 4 ppr and I am wondering if the ppr count will affect overall system performance. I guess this is tied to question 1

  3. If ppr count does affect system performance, have you done any experiments or testing to see what those affects are?

  4. I can make a disk for testing now and always change it if needed, but wondered if you had a recommendation on how many slots in the disk I should start with?

Thanks,

John Brannen

from grbl-mega.

fschill avatar fschill commented on August 16, 2024

Hi,

  1. yes, at the moment the interrupt is always on. I have not noticed any problems so far, and I did use the CNC lathe a few times since in non-threading operations.
  2. &
  3. I haven't done any tests regarding performance and maximum pulse frequency. The maximum on my lathe is 1200 RPM *4 ppr, and I haven't noticed any problems for now.
  4. As the counter for encoder ticks can overflow, I would recommend a power of 2 ticks per rev, until this is addressed (so that it's still a full revolution even if it does overflow). I think, given my experience, a low number of ticks should be enough. You could even try with just one, then the spindle position will always be absolute. A larger number of ticks will improve the adaptation if the spindle speed changes, so if your lathe is very steady you need less, if it slows down a lot under load then maybe more (I think 16-32 should be plenty).

from grbl-mega.

109JB avatar 109JB commented on August 16, 2024

@fschill Thanks for the reply. I've ordered the optical encoders and will likely try it out with 4 ppr as you have done. Unfortunately it will still probably be a month to get things all sorted out due to family commitments, but will still be loads faster than doing a complete lathe conversion. I'll let everyone know how it goes.

from grbl-mega.

Muscles avatar Muscles commented on August 16, 2024

@fschill I was trying to use your grbl for a lathe, where should I put the rpm sensor?

from grbl-mega.

fschill avatar fschill commented on August 16, 2024

The RPM sensor typically goes on the main shaft for the spindle/chuck. My lathe actually already had an encoder for the RPM display. In this case, it's a ring clamped on the shaft on the gear side of the spindle bearing, with 4 little magnets embedded. A hall sensor reads the magnets and generates a pulse sequence (pulses are low in my setup, so at the moment my version of GRBL reacts to falling edges).
Note that this is still experimental - it works for me, but I recommend that you test it carefully. Things may go wrong...

from grbl-mega.

Muscles avatar Muscles commented on August 16, 2024

@fschill I get that, I meant which mega pin

from grbl-mega.

fschill avatar fschill commented on August 16, 2024

@Muscles oops, sorry :) Currently it is using hardware interrupt INT4, which is on "digital pin 2" on the mega board.

from grbl-mega.

Muscles avatar Muscles commented on August 16, 2024

Now we are talking, thanks!

from grbl-mega.

shooter64738 avatar shooter64738 commented on August 16, 2024

Hello all!
I was toying around with some changes this weekend trying to resolve my rigid tapping/lathe threading issues and came up with this idea, which seems to work pretty decently!

Using @fschill 's changes, I was having pretty good luck getting spindle synch with a 100ppr encoder. Ideally I think a 64 ppr encoder would be better, but what I needed was an index pulse. I had several 600 ppr encoders I ordered for closed loop feedback and decided I would mod one.

Using a quadrature encoder I removed the small disc and 'painted' half of each slot over with black nail polish. You can cover either edge, but not both. You will then get a pulse on either the A channel or the B channel (depending on which side of the slot you covered half of) but leave one slot completely open. I get the 600ppr on channel A, but since channel B has been painted over (except for one slot) I get an index pulse on B after 1 complete rev. You could of course get an encoder with a Z pulse, but since I had a bunch of these already I didnt wanna spend the money and these were crazy cheap anyway.

Also, I didnt notice too much of a problem running the 600 ppr encoder (obviously NOT as a quadrature though) I still think a lower res encoder would be better, but thought I would toss this out there for anyone that wants the index pulse and has some of these cheaper encoders. I did make some changes to handle the over flow in @fschill 's code for my testing, but it handles higher res pretty well so far.

from grbl-mega.

rokag3 avatar rokag3 commented on August 16, 2024

I have made a little program that make a divider for encoder it take a "too big" encoder and divide it by whatever
https://www.tinkercad.com/things/ipSM028xFth-encoder-quadratic-divider/editel
The switch are not implemented anymore in the software

this program is very short but a bit long to explain
If is usefull to limit the number of interuptions of your program if you use a hacked encoder from a printer
originally I did it for a frienf to divide by 2 a linear encoder so he can see the real value on his DRO for a lathe (1 mm= 2mm of metal out)
I use spool of course no need to use a costly interrupt here (cost 70 cycles)

I also have a attiny 45 version this is divide by 2
If you want to do diide bt anything (of course slower )
You must use replace the line
if (!(encoder0Pos&1))//if divisor is 2 no need to make a costly modulo
by
if (!(encoder0Pos%Divisor)){//if the position of fast encoder can be divided by divisor

/vB1.0
//rokag3 2/21/2017
//diviseur par 2 d'encodeur en quadrature
//attiny 84 20mhz
//if you use it say it's from me
// ********************************************************************************************
//Arduino IDE & Pin Mapping 
// add  2 capacitor 22picof ground to PB0 and PB1 where is the crystal 20mhz
// add a capa 1000 microf between 5V an gnd
// ATMEL ATTINY84 / ARDUINO
//
//                                  +-\/-+
//  red              VCC 5V 1|    |14  GND                         black
// quartz1 (D 10)  PB0  2|    |13  AREF (D  0)
//  quartz2 (D  9)  PB1  3|    |12  PA1  (D  1) 
//  reset                PB3  4|    |11  PA2  (D  2)           outA1 green to DRO 
//  PWM  INT0 (D8)PB25|    |10  PA3  (D  3)           outB1 yelow to DRO
//  PWM    (D  7)  PA7  6|    |9   PA4  (D  4)            in1 A green from encoder
//  PWM    (D  6)  PA6  7|    |8   PA5  (D  5)            PWM   in2 B yelow from encoder
//                                 +----+
#include <avr/io.h>

long int encoder0Pos,encoder0Divide = 0;//position of the encoder since power up.  it can be a simple int provided that the modulo of the higest number possible for encoder0 with Divisor must be 0 
const char direction [16] =   {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0}; //up or down table
const char   slowEncoder [9] = {4,12,0,8,0,4,12,0,8,};//table of sequence of the encoder A+B+ bits 2 and 3


#define in1   0 //PA4
#define in2   1 //PA5
#define outA1 2 //PA2
#define outB2 3 //PA3
#define Divisor 2 //here it must be 2 if you want more you must use the modulo test line
byte New,Nnew, Old; 
char testerr,faults,sign=0;
byte  diviseNew;

void setup() {
 pinMode(in1, INPUT);
 pinMode(in2, INPUT);
 pinMode(outA1 , OUTPUT);
 pinMode(outB2 , OUTPUT);
 }



void loop() {

 Nnew=PINA & 3;  // Only one read to keep the coherence of the time same as Nnew=PINA &48/16 if I read 32 then divided by 16 Nnew = 2
   if(New != Nnew){  //any change on the encoder ? if yes routine to determine increment or decrement
                   Old = New; 
                   New = Nnew;// I take here the value I read before the test to keep the coherence of the time
                   sign = direction [Old * 4 + New];//I take the value in my table 
                   if (sign){ //in C if the argument is not equal to zero it is TRUE so -1 is true like 1
                           encoder0Pos+= sign; //I increment or decrement the position with sign who can be -1 or 1
                           if (!(encoder0Pos&1))//if divisor is 2 4 8 16 no need to make a costly modulo 
                              {
                                diviseNew=slowEncoder[4+sign+(((PINA &12)>>2)*sign)];//
                                if ((encoder0Divide*Divisor)!=encoder0Pos)
                                   {
                                    encoder0Divide+= sign;
                                    PORTA |= (diviseNew);//equivalent to PORTA = PORTA or divisenew
                                    PORTA &=(diviseNew); //equivalent to PORTA = PORTA and divisenew
                                   }                  
                               }
                             }
                    }
              } 

/*
Old = New; 
New = (PINB &3 );
encoder0Pos+= QEM [Old * 4 + New];
 if (!(encoder0Pos%Divisor)){//if the position of fast encoder can be divided by divisor
     sign= QEM [Old * 4 + New];
     diviseNew=slowEncoder [4+sign+(((PINB &12)>>2)*sign)];
     PORTB |= (diviseNew);
     PORTB &=(diviseNew)
*/               
   //explanation not complete let say that 
   //const int slowEncoder [9] = {8,0,12,4,0,8,0,12,4};//table of sequence of the encoder A+B+ bits 2 and 3
   // sign=testerr  diviseNew=slowEncoder [4+sign+(((PINB &12)>>2)*sign)];
   // value to write is at the position 4(+1 or-1)so 5 or 3 9here we are going to take -1 for sign so we have 3
   //+ the bits in +A+B shifted to obtain the value on 2 bits here 12=8+4 so position 3 and 4 lets shift 2 time
   // if the value was 4 >>2 and it become 1
   //so (((4)>>2)*-1)=-1 so 4+sign+(((PINB &12)>>2)*sign=>3+-1=2
   // I will write the value in slowEncoder[2]so 12 in portB bit 3 will be 1 and bit 4 will be 1 job done
   // If I want to write A B in portB bit 4 and 5
   //const int slowEncoder [9] = {16,48,0,32,0,16,48,0,32};//table of sequence of the encoder A+B+ bits 4 and 5
   // sign=testerr  diviseNew=slowEncoder [4+sign+(((PINB &48)>>4)*sign)]

from grbl-mega.

Abdurahman85 avatar Abdurahman85 commented on August 16, 2024
* timekeeper.c

timekeeper.c - no such file in grbl-mega repository, as well as support G95...

from grbl-mega.

codemakeshare avatar codemakeshare commented on August 16, 2024

@Abdurahman85 The lathe add-ons are not yet in the GRBL repositories - you can find them in my fork:
https://github.com/fschill/grbl-Mega (spindle_sync branch). Be aware that it's still experimental code - I didn't have much time to continue working on it.

from grbl-mega.

Kukuzca avatar Kukuzca commented on August 16, 2024

Sorry if this is the wrong place but I cannot find the info in any other place. I'm a noob both in arduino world than in mechanical working. I've an Emco Unimat mini lathe and I want to be able to thread with it. If I install your fork on a mega I have to wire the encoder output to mega digital pin 2/ground and using a Ramps 1.4 and a stepper driver drive a stepper motor (sorry for the pun) for z axis? It is correct? Have you got some schematics on how to wire it all? Thanks!

from grbl-mega.

codemakeshare avatar codemakeshare commented on August 16, 2024

Hi,
This is unfortunately still very early and rough code, very much "work in progress"... I don't have a schematic for the wiring either, sorry. Regarding stepper drivers, I would not recommend using the tiny drivers on the Ramps 1.4 board, I don't think they're powerful enough. For a lathe, you'd want a NEMA23 motor with a suitable driver. You are of course very welcome to try it out, I just wanted to warn you to not expect it to work perfectly, and it might need some adaptation work. In principle you only need one encoder input, and you'll have to adjust the number of ticks per revolution in the code. For threading you would also want a stepper drive on the X-axis as well, to retract at the end of the thread. It might be possible to do without, if you first cut a relief groove to land in, but it would be a bit fiddly (although, not more fiddly than manual threading...).

from grbl-mega.

Abdurahman85 avatar Abdurahman85 commented on August 16, 2024

Thanks for the answer.
About drives: I will use an alternative option, namely my homemade drives - with DC-motors and optical disks. (I would put it on github, but I don’t know how yet :D)
Next, the code you have is yes, it is slightly not optimized, but there is already support for "thread cutting" - this is a big increase in the possibility of the machine ..
I'm going to port it to the architecture of stm32 ... I hope that will work .. later I uploading..

from grbl-mega.

Abdurahman85 avatar Abdurahman85 commented on August 16, 2024

from grbl-mega.

terjeio avatar terjeio commented on August 16, 2024

@Abdurahman85 : I have recently added a HAL driver for the bluepill board that might be of interest. However, I do not believe the bluepill is suitable for driving a lathe with spindle synced motion - IMO not enough free timers.

from grbl-mega.

Abdurahman85 avatar Abdurahman85 commented on August 16, 2024

from grbl-mega.

Kukuzca avatar Kukuzca commented on August 16, 2024

@codemakeshare thank you for the answer. Maybe I was not clear: my approach will be like the Abdurahman solution: I will use the original lathe motor spindle adding on it an high res encoder. From one of yours previous answer I've understood that the output of the encoder have to be wired to mega digital pin 2. When I'll send a G33 command how can I specify to Arduino to send pulses to one of the axis in particular? In other word: using the default configuration the spindle pulses from the encoder which axis will "drive" through Ramps/stepper driver electronics? I've tried to understand port and pin configuration in cpu_map.h but it's too difficult for me...

from grbl-mega.

Kukuzca avatar Kukuzca commented on August 16, 2024

Yes, I made a mistake when I wrote G33, I was meaning G95. Thanks for the answer

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024

I have implemented the G33 spindle synced threading in the GRBL-L version. There is still some room left for changes.
@chamnit If you want to add this to the grbl version, let me know then I will adjust the code so it can be turned on using a compiler define and make a pull request.

Sketch uses 31846 bytes (98%) of program storage space. Maximum is 32256 bytes.
Global variables use 1592 bytes (77%) of dynamic memory, leaving 456 bytes for local variables. Maximum is 2048 bytes.

See Grbl-L

from grbl-mega.

Bi7Wis3 avatar Bi7Wis3 commented on August 16, 2024

Hi all, and thanks for all the efforts so far.

I'm also very interested for adding threading to my lathe.
I have a ring with 4 magnets and one hal sensor mounted on the lathe.

Tried both versions ( the one from fschill and the one from HuubBuis).
Couldn't get HuubBuis version get to work. ( no spindle speed ).
@HuubBuis : you mention to use Y-Limit pin, but on the Mega you have 2 ( Min and Max). tried both, but didn't get any spindle speed.

The version from fschill, i could get to work for a single pass. but can't get any sequential passes to line up.

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024

@CrashGuard,

The GRBL mega only has one limit pin so I assume you have a shield op top of the Mega. Did you set the compiler options in the config.h to compile for this shield?

I use the Mega and Uno version without a shield and that works very well.

from grbl-mega.

Bi7Wis3 avatar Bi7Wis3 commented on August 16, 2024

@HuubBuis

I use a mega and have it configured for the ramps board. got a few of those laying around.
When i look at cpu_map.h i see 2 limit pins in the config:
#define MIN_LIMIT_BIT_1 1 // Y Limit Min - Pin D14
#define MAX_LIMIT_BIT_1 0 // Y Limit Max - Pin D15

Which one to use ? tried both without succes ..
Also tried INT4 ( D2 ), works on the version from fschill > spindle_sync..

Did you assign D11 from the CPU_MAP_2560_INITIAL definition?

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024

I used the grbl mega default D11 configuration:
#define Y_LIMIT_BIT 5 // MEGA2560 Digital Pin 11

I had a quick look at the Ramps configuration in config.h. Default there is a setting
// Disable the hardware limits
#define DISABLE_HW_LIMITS

If hardware limits are disabled, index, sync pulses and probably limit switches are not detected.

Homing however will work because it is done by polling the limit switches!

I guess, didn't analyze the code, that if hardware limits are enabled, both pins D14 and D15 should/could hopefully work.

I have a ramps board on my rotary table but have to take it apart and mount it on a lathe to test it. Not something that can be done easily at the moment!

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024

I took a closer look at the Mega Ramps configuration and found the following code fragment in limits.c:
#ifdef DEFAULTS_RAMPS_BOARD
#ifndef DISABLE_HW_LIMITS
#error "HW limits are not implemented"
#endif
#else

When i compile the code, I also get the error "HW limits are not implemented"
It seems like hardware limits are not supported on the ramps board running grbl. I also couldn't find a probe signal pin on the shield.

from grbl-mega.

fra589 avatar fra589 commented on August 16, 2024

Hi @HuubBuis,
Hardware limits can't be implemented on the RAMPS board version, since it use hardware interrupt and the port used by the limit switch on the RAMPS board are not compatible with interrupt.
On the Mega 2560 CPU, not all the IO ports support interrupt.

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024

@fra589
Thanks for this information, it save's me a lot of time.
A solution would be to use pins on the ramps board that support hardware interrupts. That could lead to confusion for those who don't read the complete documentation.

from grbl-mega.

Bi7Wis3 avatar Bi7Wis3 commented on August 16, 2024

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024

@CrashGuard
The A15 pin is connected to the therm2 pin on the Ramps Shield.
I could change the code to see the synchronization pulse as an index pulse if the number of synchronization pulses = 1. You then will be able to do threading.
I can't test the change before half of Mai but if you would test it, i will make the code change a.s.p. ultimately before the end of next week.
Beware, this change could effect the probing cycle so take care not to destroy your probe.

from grbl-mega.

Bi7Wis3 avatar Bi7Wis3 commented on August 16, 2024

@HuubBuis

In cpu_maps.h :
// Define probe switch input pin.
#define PROBE_DDR DDRK
#define PROBE_PIN PINK
#define PROBE_PORT PORTK
#define PROBE_BIT 7 // MEGA2560 Analog Pin 15
#define PROBE_MASK (1<<PROBE_BIT)

P.S. .. I have it configured as a ramps board, but took it off and using big stepper drivers now..

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024

@CrashGuard

I have plans for making a tool changer based on a rotary table setup. The Ramps board seemed a good solution for this because it has a 4e axis and many IO pins together with GND and 5V. I would also use external drivers.
No hardware interrupts on the limit switches is a no go for me. Remapping pins will lead to confusion. I have checked for other shields but didn't find an appropriate one. So at the moment I am not sure what to do (for my own project).
Never the less, I think with a small code change, Ramps users could do threading with the limitation of just one index pulse. For spindles who's speed is regulated by gears, I expect it will work fine.

I want to change system.c to set the "CONTROL_PIN_INDEX_SPINDLE_SYNC" as a response to the receive of a index or sync pulse when the number of sync pulses = 1. Then the sync pulse could be on the Index or Sync pin. The time penalty for the extra check would be a few micro seconds or less.
My plan is to do the code change and check the code for the impact. Recompile the Mega version and test this on my lathe. Recompile the Ramps version and simulate this on my Mega + Ramps board (will set a pulse generator on the sync pin).
If it works I will fit the ramps board on may lathe and test it (scheduled half of Mai). If this test is OK, I will make a new release and update the WiKi.

P.S. I have some cheap ebay adapter cables that fit on the stepstick header to connect my external TB6600 drivers (JST connector).

The old code in systemc:


// Pin change interrupt for pin-out commands, i.e. cycle start, feed hold, and reset. Sets
// only the realtime command execute variable to have the main program execute these when
// its ready. This works exactly like the character-based realtime commands when picked off
// directly from the incoming serial data stream.
ISR(CONTROL_INT_vect)
{
  uint8_t pin = system_control_get_state();
  if (pin) {
    if (bit_istrue(pin,CONTROL_PIN_INDEX_RESET)) {
      mc_reset();
    } else if (bit_istrue(pin,CONTROL_PIN_INDEX_CYCLE_START)) {
      bit_true(sys_rt_exec_state, EXEC_CYCLE_START);
    } else if (bit_istrue(pin,CONTROL_PIN_INDEX_FEED_HOLD)) {
      bit_true(sys_rt_exec_state, EXEC_FEED_HOLD); 
    } else if (bit_istrue(pin,CONTROL_PIN_INDEX_SAFETY_DOOR)) {
      bit_true(sys_rt_exec_state, EXEC_SAFETY_DOOR);
	} else if (bit_istrue(pin,CONTROL_PIN_INDEX_SPINDLE_SYNC)) {			// Detected a G33 spindle synchronization pulse. Beware, this is not the spindle index pulse
	  if (settings.sync_pulses_per_revolution>1) { 							// If G33 is configured for synchronization pulses
	  bit_true(threading_exec_flags,EXEC_PLANNER_SYNC_PULSE);				// Signal the detection of a synchronization pulse.
	  }
	}
  }
}

The new code

	} else if (bit_istrue(pin,CONTROL_PIN_INDEX_SPINDLE_SYNC)) {			// Detected a G33 spindle synchronization pulse. Beware, this is not the spindle index pulse
	  if (settings.sync_pulses_per_revolution==1) { 						// If G33 is configured for 1 synchronization pulses
	    bit_true(threading_exec_flags,EXEC_SPINDLE_INDEX_PULSE);}			// Signal the detection of a index pulse 
	  else if (settings.sync_pulses_per_revolution>1) { 					// If G33 is configured for more than 1 synchronization pulse
	  bit_true(threading_exec_flags,EXEC_PLANNER_SYNC_PULSE);				// Signal the detection of a synchronization pulse.
	  }
	}

from grbl-mega.

Bi7Wis3 avatar Bi7Wis3 commented on August 16, 2024

@HuubBuis

Sounds, good.

I also could test it on my lathe.

You said: Recompile the Ramps version and simulate this on my Mega + Ramps board (will set a pulse generator on the sync pin).

Which pin do you mean on the ramps, the probe pin (A15)?
#define CONTROL_SPINDLE_SYNC_BIT 7 // MEGA2560 Analog Pin 15, same as probe pin

And also how to set the number of pulses per rev?

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024

Which pin do you mean on the ramps, the probe pin (A15)?
#define CONTROL_SPINDLE_SYNC_BIT 7 // MEGA2560 Analog Pin 15, same as probe pin

I would first try to use the sync pulse as an index pulse because for that, no pins need to be remapped, only a change in the ISR logic.

Which pin do you mean on the ramps, the probe pin (A15)?

The Probe pin (A15) is connected on the Ramps board to THERM2

And also how to set the number of pulses per rev?

If there is only an index pulse, the number of sync pulses (pulses per rev) should be set to 1.

If the logic change works it means the other pins still support Interrupts using the current RAMPS code. Than there maybe is a solution for the missing index interrupt.

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024

And also how to set the number of pulses per rev?

The number of sync pulses is set in the arduino config $40, should be 1 if there is just an index pulse.

I have done a small test, the safety door pin interrupt is working on the ramps board after enabling it in config.h. Because the synchronization pin is setup the same way, I expect this pin to work also.

from grbl-mega.

Bi7Wis3 avatar Bi7Wis3 commented on August 16, 2024

I have tried the above code.
Connected the Sync_pulse to A15.
But when i try running :

G0 X0 Z0 F25; go to start position
G0 X-0.1 ; go to cutting depth, clear of workpiece
G90 G33 Z-5 K1 ; Threading pass at a pitch of 1 unit per revolution
G0X0.4 ; retract at end of move
Z0 ; end of pass

I get Error 18 ...

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024

Error 18: you find the errors in the file error_codes_en_US.csv inthe doc directory
"18","Index pulse timeout","G33 No index pulse received within 6 sec"

I have done the same, came to the same error. The reason is than on the RAMPS board this pin has a 4k7 pullup connected to a 10 uF capacitor. Your pulse has to be wide enough to charge the capacitor. I tested using a 2 ms high pulse at a rate of 6 Hz (360 RPM) and GRBL showed a very high speed. The slow rising flank (charging the capacitor) or the spikes when discharging this large capacitor probably causes a lot of false triggers.
I had a second problem. As soon as I started the index pulse simulator, I wasn't able to run a G92 command.
To be short, the quick fix won't work.
I reserved the next 2 days to see if I can get the RAMPS board Index signal working on another pin. For now I am going to use the DOOR pin. After that I will decide what to do.

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024

Part of the problems came from my Index pulse simulator. It had a positive pulse (NC sensor). I changed it to a 2 ms negative pulse(NO censor). Now the grbl speed is measured ok and I can sent a G92 code without problems.
To avoid problems due to the large capacitor on the THERM inputs I used the safety door pin for the index pulse.

I have made a quick and dirty change to the code. It is tested on the ramps board using a spindle index pulse simulator running at 120 RPM (2 ms low pulse) connected to A12, Pin 9 on the AUX2 connector, the former safety door pin.
It is not the final version but it should/could get you started. Use it carefully
GRBL-L-Mega-Ramps.zip
I will consider the options for a final version and will make the final version half of Mai when I can free up a lathe for testing.

from grbl-mega.

Bi7Wis3 avatar Bi7Wis3 commented on August 16, 2024

OK thnx,
I'll check it later..
I'm using NO sensors too, but to make the pulse longer, i used 2 magnets next to each other on the timing ring. ( using 4 pulses per rev, so 8 magnets ).
i can get rpm readings up to 3500 rpm without any problems with the firmware from fschill..( Pulses on Pin D2 , alse getting rpm readings in UGS.)

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024

I'm using NO sensors too, but to make the pulse longer, i used 2 magnets next to each other on the timing ring. ( using 4 pulses per rev, so 8 magnets ).
I needed the long timing pulses to get the index pulses on the RAMPS Probe input (TERM2 with 4u7 capacitor) working. On the door input there is no capacitor so the pulses can be a lot shorter. I use 4 mm diameter magnets on the small lathe and 12 mm diameter magnets on the "large" lathe.

The small lathe gets to it's max (2500 RPM) the larger lathe is limited to 1200 RPM due to a optocoupler input that is not adjusted for higher speeds (at the moment).

Beware, sync pulses are not supported in this version, only an index pulse.

D2 and D3 are connected to an dedicated interrupt capable pin (INT0/INT1). I will consider using D2 and D3 for index and sync pulses.

from grbl-mega.

Bi7Wis3 avatar Bi7Wis3 commented on August 16, 2024

fun fact:
According to specs, my small lathe should do 2500rpm, but in reality when i cranck it up, it goes over 4000 rpm ... REALY SCARY!! LOL ..

from grbl-mega.

HuubBuis avatar HuubBuis commented on August 16, 2024

Scary thing:
Be careful, the chuck may break apart (explode) if you run faster than it's max RPM.

from grbl-mega.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.