Electronic Lead Screw Mod

My understanding of the Clough42 ELS is that it does not know what the spindle angle is. It keeps track of the spindle angle position relative to its point of initiation by totaling the number of encoder pulses from the point of initiation. This has always seemed like a cumbersome way to manage sync.

If the controller pulses to the driver are disabled, either using the driver disable/enable or via the software controlled pulse stream, sync is lost. If the spindle continues to rotate, the encoder is still sending pulses and they will have to be accounted for on order to reestablish sync. Managing all that math seems like a tedious way to go.

I like using the half nuts and thread dial when threading. For me, the ELS is simply an electronic replacement for the gear train, as Clough had intended. I have a solution for threading to a shoulder or turning to a stop via my variable speed motor and TouchDRO. Hence no pressing need to make a change at this point. I like my 602 and with modifications I have made it very nearly meets all my requirements. A recent modification of the Clough42 software by kwackers on github to enable user entry of custom thread pitches via the UI is close to completing my wish list.
(It only addresses metric pitches and while I can do the math to calculate inch threads, there are some holes due to the limited number of decimal places for the pitch entry but for the most part, it is close enough for practical purposes.

I am not inclined to want to go CNC with my lathe. I prefer the manual control and most of the time I don't bother with the power feed or even turning on the DRO. The dials and a micrometer has worked well for simple tasks for more than fifty years. For the very few times that I need CNC control, my Tormach mill can be configured as a vertical CNC lathe. However, if I wanted to have the ELS control the x axis, I would probably elect for full CNC. The reason being that G code is relatively simple to write and far more universal in function.
The Clough42 ELS knows the spindle count, which is referenced (I presume) to the spindle position on power on. So the spindle angle can be referenced to the start point by using simple modulo arithmetic. This is true, as long as the encoder pulses are being counted. If the encoder pulses are not looked at, or the interrupt is turned off, then that reference is lost. This is equivalent to opening the half nuts. As long as we enable the counting, one can get back to the start point. In C, this is a simple command. I don't know what variable names are used, so I will make up some, for the sake of discussion
C:
angle_count = count_val % ppr;
angle = angle_count * 360.0/ppr;
This is the angle in degrees relative to the start angle. The start angle is arbitrary. As long as the count_val doesn't over or under flow, the relative angle is recoverable.

I have to agree with your approach to Clough42's ELS. I just want to replace physical gear changing with electronic changing. If I can add extra stuff, like thread to a stop, it would be very nice. It's not necessary, but it would be very helpful for coarse pitches and metric threads. As it stands, with metric threads, I have to stop the spindle every time I get to the gutter, retract, reverse the lathe and start again. It would be nice to not to have to do that. Integrating the VFD brake would be both neat and (at least initially) terrifying. Trying to determine if I want to do that or not. Due to my small shop constraints, I do not have access behind the lathe. The lathe is close to the wall. So taking the VFD approach is temporarily not my prime approach. I'm not ready for lathe CNC, as I consider myself very much a beginning machinist. Not enough experience to avoid colossal screw ups in CNC land.

I took the easy way out in my code and disabled the encoder as a way to shut things down. (No updates = no movement of the stepper.) I shouldn't have done that - because that causes loss of spindle sync. Instead, I need to disable the stepper. I will make those changes, so that I can look into thread to the gutter. I also don't keep a copy of the stepper count, but I can easily add one to my code. Thread to a stop requires access to the VFD controls. I may get there, but think that will be later.
 
It is true that the start angle is arbitrary as long sync isn't lost. Stopping the pulse train to the stepper, either by means of the controller , or the driver enable breaks sync. It is theoretically possible to regain that sync by knowing how many pulses were generated by the encoder and doing some sort of makeup for the driver when it is again enabled but it seems like this is a lot of work.
 
It is true that the start angle is arbitrary as long sync isn't lost. Stopping the pulse train to the stepper, either by means of the controller , or the driver enable breaks sync. It is theoretically possible to regain that sync by knowing how many pulses were generated by the encoder and doing some sort of makeup for the driver when it is again enabled but it seems like this is a lot of work.
It breaks physical sync. However, we still know the spindle angle (as long as the encoder pulses are being counted) and we know the stepper angle inferred from the step count (using the same modulo logic as for the spindle angle). Assuming we have not lost count of either, can we not then recover to where we started? We would have to take a snapshot of the spindle count at the time of disengagement of the stepper, correct?

There might be some gcd issues, especially if we are doing non-native threads relative to the lead screw, but this seems like a problem with a mathematical solution, as long as we impose some restraints, like keeping the half nuts engaged. I think if one was clever enough, we don't even need that restraint. We would probably have to keep one restraint, maybe like only engaging "1" on the thread dial, so the problem is tractable.

The code might be tricky, but face it, we have a computer in there. It doesn't care if we add a few op codes or not, as long as we don't blow the timing budget.
 
I'm working on this threading sync problem on my own, fairly modified, Clough42 ELS. I'm solving it in a pretty simple way: my ELS already allows feeding into a previously-set stop. I set a stop at the right hand side of the work, and at the shoulder I'm feeding in to. Now I can just press my "Feed Left" button, and it will feed up to the shoulder. Retract, press Feed Right, and it feeds back, repeat.

Because this system knows the starting position (the right stop), my modification for threading is just going to be to wait for the correct spindle position before beginning the feed. As long as you use the same spindle position every time, from the same starting point, it should work perfectly.

Unfortunately I've been set back a bit by somehow losing quite a bit of my previous code, so I'm rebuilding it now.

The changes to do all of this aren't trivial - I'm not a master coder, but nevertheless it has taken me quite a few hours to get to this point. James' extremely good ELS was only designed to be a simple replacement for change gears, so you need to make a lot of changes to keep track of things.
 
I agree with Wobbly, btw, that this is a pretty trivial maths problem. For non-coders like me there are lots of "gotchyas" like overflowing variables etc, but it's all manageable with enough planning. As long as you never touch the half nuts, the computer can do extremely fast accurate maths to figure out these problems.
 
It breaks physical sync. However, we still know the spindle angle (as long as the encoder pulses are being counted) and we know the stepper angle inferred from the step count (using the same modulo logic as for the spindle angle). Assuming we have not lost count of either, can we not then recover to where we started? We would have to take a snapshot of the spindle count at the time of disengagement of the stepper, correct?
I dislike the use of the term "disengagement", but yes. Actually, it can be simpler than that. Simply set the encoder register to 0 and the lead screw register to 0x8000,0000. Keep track of he pulses from the encoder, overflowing when the number of pulses from the encoder indicates one full revolution (or underflowing if the register goes negative), and keep track of any pusles sent out to the stepper / servo motor.

There might be some gcd issues, especially if we are doing non-native threads relative to the lead screw, but this seems like a problem with a mathematical solution, as long as we impose some restraints, like keeping the half nuts engaged.
Correct. As long as the half nut remains engaged, it doesn't matter at all whether the lead screw and the part have matching thread metrics. Unlike the issue with mechanical gears, there is always a series of points where the spindle and the lead screw will match within +/- 1 pulse of both.

I think if one was clever enough, we don't even need that restraint. We would probably have to keep one restraint, maybe like only engaging "1" on the thread dial, so the problem is tractable.
No, that will not work. The 1 position no longer has a predictable phase angle relative to the spindle, but honestly, it doesn't really matter. At the spindle speeds allowed by using the ELS, driving the carriage with the ELS will usually be much faster than using the half nut, in any case.
The code might be tricky, but face it, we have a computer in there. It doesn't care if we add a few op codes or not, as long as we don't blow the timing budget.
Which is why driving the carriage with the spindle at 3000 RPM becomes practical. I doubt I would ever thread at that speed, but driving the carriage in reverse is not a big deal.
 
Many of you may be familiar with James Clough's Electronic Lead Screw project. For any of you who are not, and do not own a CNC lathe, I strongly encourage you to take a look at this project on YouTube. It is quite straightforward, and a fairly inexpensive upgrade to any manual lathe, especially if, like mine, your lathe uses change gears rather than a lever shift transmission, or even worse, again like mine, does not have a reverse threading capability.

One thing currently missing from James' ELS is the ability to turn or thread to a shoulder. Adding this feature would really make this system a truly spectacular machine, giving my lowly Chinese import lathe much of the functionality of lathes costing tens of thousands of dollars. (Not the rigidity, power, accuracy, etc. of those machines, of course, but then what can one expect for around $1500?)

The entire project is open source, so there is no issue whatsoever in making modifications. The only issue for me is I know virtually nothing about C++, and almost the entire software suite is written in C++. I looked at the code, and it is very well written with reasonable amounts of comments in the code. I think anyone more familiar with C++ than I would no doubt be able to easily modify the code to allow turning and threading to a shoulder. James is evidently extremely busy, so I don't want to burden him with my shortcomings, but he has expressed an interest in having such a feature added to the code.

Id there anyone here who is fairly experience in coding in C++ and would be willing to collaborate with me on this project. I already have what I think are good ideas on work flow implementation. I just need someone who can translate that into code.


I've implemented this in my ELS, if you have any specific questions fire away.



The specific code to deal with spindle direction changes and virtual stops is here:


It is ugly and could use a few refactorings, but it works and I can explain it. It may be better implemented as a state machine but it has to run in an ISR that is run every encoder tick. This means it has to be very fast and your encoder resolution/gearing determines the max speed you can run. I've tried other methods but driving the position function each encoder tick seems to be the easiest way to do this.

I use this "virtual stop" functionality all the time, it is great for threading or just cutting up to a shoulder. I have a DRO but have not yet mounted it to the lathe because I can use the ELS to step off the measurements and it works nicely. I plan to mount the linear scale and bake in the touchDRO software into my ELS since it is so simple. Here is the code i'm using on my milling machine for esp32 touchDRO: https://github.com/Aggebitter/TouchDRO-Simulator-on-ESP32

The only other thing i'll say, and i've said it many times before, is that trying to do a hardware user interface for this sort of thing is just begging for pain. My approach is to use websockets and a web browser SPA (single page app) so you can easily change the user interface. You can get to it from any device, there are no "apps" to spy on you, and it is much quicker to change. You just send json back and forth and make the ELS the source of "truth" for all the data and configuration. This is well worth the learning curve in my opinion.
 
I've implemented this in my ELS, if you have any specific questions fire away.
Well, my ask WRT this thread is for someone who can help with some coding. Clearly you are extremely well versed in C++, so if you choose could be a tremendous resource. I have already built the hardware, and I am effectively quite broke, so I am not looking to switch gears at this point. Rather, I want to build on James' work and simply add the shoulder stop functionality to his existing project. Would you be willing to help me in that regard?
It is ugly and could use a few refactorings, but it works and I can explain it. It may be better implemented as a state machine
Why do you say that?
but it has to run in an ISR that is run every encoder tick. This means it has to be very fast and your encoder resolution/gearing determines the max speed you can run. I've tried other methods but driving the position function each encoder tick seems to be the easiest way to do this.
When the lead screw is engaged, I more or less agree, although there also needs to be some timing when the lead screw is not engaged and / or the spindle is not turning. There needs to be at least 1 or 2 ISRs related to critical button presses which can take control whether the encoder is producing 1/4 million pulses (3000 RPM @ 4096 pulses per revolution) per second or zero. Fortunately, "high speed" on a lathe is not really very high speed in an electronic circuit. Any ISR needs to be handled in an expedited fashion, but with a 50MHz or greater clock speed, handling any time critical code in less than 4 microseconds should not be overly difficult. That is 200 clock cycles, at least.
I use this "virtual stop" functionality all the time, it is great for threading or just cutting up to a shoulder.
That is the idea, yeah.
The only other thing i'll say, and i've said it many times before, is that trying to do a hardware user interface for this sort of thing is just begging for pain.
Why do you say that? It's just not a very sophisticated thing to do, so a simple hardware interface seems ideal.
My approach is to use websockets and a web browser SPA (single page app) so you can easily change the user interface.
Why would one want to change? If we were wanting to implement CNC capability, or something of that nature, then one might indeed want to make all sorts of changes. That is not the idea, here. I am wanting to keep this as simple and inexpensive as possible.
You can get to it from any device, there are no "apps" to spy on you, and it is much quicker to change.
I don't want to get to it from any device, and spying on a completely self-contained system is impossible.
You just send json back and forth and make the ELS the source of "truth" for all the data and configuration. This is well worth the learning curve in my opinion.
I am familiar with websockets. Indeed, I use them extensively in my design for my thermostat project (you can see it here), but the paradigm for this project is completely different. James' (and my) idea is for a mechanically robust system dedicated to one simple set of actions with virtually no user feedback. Please note I am not deprecating the efforts of folks here like wobblyhand. His project is great, and for those who choose to follow that path, I tip my hat. For my purposes, however, I just want to add shoulder stop capability to James' project using the same $2 controller he uses.
 
Well, my ask WRT this thread is for someone who can help with some coding. Clearly you are extremely well versed in C++, so if you choose could be a tremendous resource. I have already built the hardware, and I am effectively quite broke, so I am not looking to switch gears at this point. Rather, I want to build on James' work and simply add the shoulder stop functionality to his existing project. Would you be willing to help me in that regard?

I'm not a very good c/c++ programmer so you may not want me as a teacher.
Why do you say that?
it is ugly because it is the minimal working code, not the best code or the easiest to read code. It has tons of hanging half finished ideas sprinkled throughout.
Why would one want to change? If we were wanting to implement CNC capability, or something of that nature, then one might indeed want to make all sorts of changes. That is not the idea, here. I am wanting to keep this as simple and inexpensive as possible.
If you can design an interface that you'd never want to change then you are a better designer than me. this is not easy for me. I wanted to display the angle releative to the start. I wanted to add a turn counter for winding coils. I wanted to add a mode that made the cut and did an auto rapid back to the starting position. I will re-use it to drive my hobbing controller. Simple is good. websocket control is $0 hardware, you already have a phone or tablet. The bigger win is the ease of refactoring the controller code. Doing all of that in hardware is yuck. if you could abstract it all away then fine, but a MCU doesn't have the resources for that.
I don't want to get to it from any device, and spying on a completely self-contained system is impossible.

I am familiar with websockets. Indeed, I use them extensively in my design for my thermostat project (you can see it here), but the paradigm for this project is completely different. James' (and my) idea is for a mechanically robust system dedicated to one simple set of actions with virtually no user feedback. Please note I am not deprecating the efforts of folks here like wobblyhand. His project is great, and for those who choose to follow that path, I tip my hat. For my purposes, however, I just want to add shoulder stop capability to James' project using the same $2 controller he uses.
There are 93 forks, Kent VanderVelden for example added a nextion touch screen. It looks like he added some capability for limit switches. You may get some ideas from a fork/PR or ask someone who's forked it for help. I don't have any experience with Clough's code and it seems he uses TI's proprietary IDE which I also have no experience with.

There are not updates to clough's code in 2 years, i'd consider it dead. You might as well hard fork it if you want to reuse it.

Here is a very simple view of how clough's ISR works

1// read the encoder

2// calculate the desired stepper position3

3// compensate for encoder overflow/underflow

4// if the feed or direction changed, reset sync to avoid a big step

5// remember values for next time

6// service the stepper drive state machine

The most niave implementation is you need to insert a calculation deciding if the move calculated in step 2 exceeds the stop and if so tell the controller it is either done or in error. This is likely best done with 2 stops, the first is where you start and the 2nd is where you want to stop. Since the direction could go wonky you want to be sure you stay between these. You can implement these stops as simple integer counters relative to a "start position counter". Be aware that you might get overflows if you use 32bit values since when threading you may leave the spindle running for a while. It looks like clough switched to Uint64 because of this10/2020.

The problem with this niave approach is that it doesn't account for acceleration/deceleration and you likely don't have any spindle control. The practical thing is that if you use a closed loop stepper it tends to compensate for this naivete quite nicely (at the expense of accuracy). I'm honestly not really sure of the best way to do this to account for acceleration without spindle control. You'd need a motion controller that could estimate the current distance from the stop and calculate the acceleration curve (based on your settings (based on your hardware)) and as it gets into the range where it would need to decelerate it somehow balances that with the need to keep up with the spindle (which you have no control over). This is tough because you must decelerate and maybe mess your thread up or overshoot. Again, in practice this error doesn't seem all that big and in my opnion isn't worth messing with, just use a closed loop stepper which can compensate. If you use an open loop stepper you may loose steps when it tries to stop on a dime and then you could slowly lose position and not be able to repeat theading passes.

Before you begin you need to figure out how to tell the controller to stop. Are you using a hardware stop or a software stop. If software how do you tell the controller where the stop is? Are you going to have a 10 digit keypad to enter a value? can you change the units? How do you account for thread direction vs spindle direction? this is hairy, when left hand threading with the tool in front you need to move the carriage left if the spindle is moving counter clockwise. if the tool is in the back and you run the spindle in reverse (clockwise) you need to move the carriage right. swap all that if you are cutting a right hand thread. How do you enter "stop mode" vs "slave mode"? How do you exit it? How do you tell all this to the controller since it wasn't designed for this? Do you try to implement double button presses, or long presses? What about the display?
 
Keep in mind, the Clough UI is a simple 7 segment LED array with momentary switches and LED light array. So you end up with really basic UI like up/down/mode buttons and basic display feedback. You could switch it out to something fancy like a LCD, but I haven't seen the need for it and it would require a fair bit of code. It sounds like the OP idea is to use the SET button to mark places for the start/end stops. Simple enough in theory. And if you leave everything engaged all the time and count output pulses, it should be reasonably clean.

I don't have time to work on it, or I'd offer. I also don't have a spare setup and my control box for the lathe is not easy to get to.

As for "dead project" meh, it's not like it really needs much added to it. It does what he designed it to do. I suspect if you contact him with a pull request he'd consider adding it. The project was about replacing change gears, and it does that very well indeed. He seems to jump between projects a lot, partly at least for his channel content. I can understand that as I tend to do it too. Spare time for me is limited so I tend to focus on one thing at a time and jump around a bit.
 
Back
Top