jschoch / ESPels

ESP32 electronic leadscrew for a lathe
Apache License 2.0
19 stars 4 forks source link

SAE lathe options #11

Closed digiexchris closed 1 year ago

digiexchris commented 1 year ago

Hello! I'm about to dive into this myself. Just wondering if you've implemented inch threads or use with inch leadscrews? I'm a software engineer myself so I can probably take care of it, just wondering if you've considered it and how you would approach that problem. Especially any problems you envision with error in converting metric threads on an imperial leadscrew and visa-versa. I'm thinking that there are thread conversions that will never perfectly resync once started, but I suspect if we accept a certain low percentage error (tuneable/calculateable through the frontend perhaps), it will be more than good enough. Of course, adapting the frontend to convert TPI to distance in lead is easy enough...

digiexchris commented 1 year ago

actually I just started having a look, I think I could implement it fairly easily, if you're willing. Going to start playing with it regardless. I noticed there are a bunch of variables that seem to be unused, and a few others that are related to some refactors you had planned, I might implement those too!

jschoch commented 1 year ago

I'm happy to help! sorry for the late reply, i was out of town last week. Also sorry for the state of the code, didn't get many collaborators so I've not put the work into documenting it and cleaning it up. It is fairly stable and I do use it frequently.

Regarding imperial, Two ways to do it, one is to just convert in the UI, the 2nd is to have a flag and do it in the firmware. If you are familiar with react hooks it should be fairly easy to do in the UI.

I need to check my local repo and see if there are any un pushed commits hanging around here or in the repo with the UI. I will do that now.

jschoch commented 1 year ago

I pushed some updates to the frontend in a branch called hobbing, but I've not looked at it in a while and kinda forgot what I was doing. I have a hobber and wanted to re-use the UI for that but again I forgot how much progress I made.

Looks like this repo is in sync with the last merge.

More thinking about imperial with imperial lead screws, I'm using regular division, ideally this is higher precision but practically I haven't had any issues. It would be better to use the approach didge uses via rational numbers from Boost. I may have had that working at some point, i know i tried and had issues getting it compiled.

The main position counter is 64 bits and it should not have issues with overflowing (though I don't check in the code). At some point I timed the code and it seemed to be fine for the jobs I threw at it, but I'm also using a closed loop stepper and that stepper allows for some slop in the acceleration. I've run it with an open loop stepper but it runs much better with a closed loop stepper due to the lack of acceleration code.

In my hobber firmware I've used a different approach and instead of my home baked step gen library using RTM peripheral it uses FastAccelStepper which also supports RTM and it does the acceleration. It may be worth while to port that over here. It essentially is always trying to step to the target position regardless of error due to the acceleration parameters. My hobber has a closed loop servo on it so I'm not 100% it will work as well as this code and or with a stepper.

digiexchris commented 1 year ago

awesome thanks!

Regarding inch vs mm in firmware, I've got a weird lathe. It's got a 7 tpi leadscrew with a 4:1 reduction at the spindle, effectively 28 tpi. This means it has very low error for metric threads, but still some. Weirdly, this also means I don't have any close by ratios I could drive it at with a stepper without getting inch error too. I'm going to have to think this over, but I think it's likely it's not going to be a big deal either way. I also have an open loop. I was looking at the ESP-Flexystepper (which I've converted to be non-arduino so I could run it in an Espressif esp-idf toolchain directly) for my own firmware I had started, and it has some interesting possibilities. Such as commands that tell it to move a certain distance relative to it's own internally tracked state, and it runs until it's gotten there, with a nice acceleration loop. It also has a separate deceleration configuration, which is nice for a machine like this that often can decelerate faster than accelerate. Just an option. A possible implementation is here, if you're curious. https://github.com/digiexchris/LeadscrewWarrantyVoider/tree/master/main (more to get my thoughts down than anything serious). I pinned the stepper manager on one cpu to make sure it doesn't lag on sending steps to the closed loop driver.

Anyway, I did get your firmware and frontend to compile, but I had to work some of the dependency chain a little bit, seems that some people have renamed and consolidated github projects since. Got the setup running on my hardware too! I can do a pull request with those changes.

Do you mind if I do a little bit of a reorganization? I love the functionality you already have in place, but I've moved a few things around in my local copy so I could understand it better and separate some concerns a bit. I think in c++ a little easier also, if you're not opposed to that.

Another thing I was thinking about is storing the web stuff on an i2c sd card reader along with wifi config and maybe machine config, so it's a little more out of the box for others. Far in the future thought though.

Regarding overflows, are you doing any resetting of the counter if it gets close to the overflow point? I think it's probably not difficult to solve just to future proof it for people that have other needs, like if they need to gear a motor down a lot.

I'll spend some time with a gear calculator and see if I can get a change gear combination that spits out round numbers for inch stuff and see how that changes my preferences. I was also thinking of trying to find a close ratio that works for Metric on my lathe too, and then just make some kind of switchover mechanism to switch the stepper onto the metric converting pulley or something, with maybe a microswitch to tell the firmware which mode it's in.

Do you have a link to that rational number math from the other firmware? Having trouble finding it, that sounds interesting too.

jschoch commented 1 year ago

awesome thanks!

Regarding inch vs mm in firmware, I've got a weird lathe. It's got a 7 tpi leadscrew with a 4:1 reduction at the spindle, effectively 28 tpi. This means it has very low error for metric threads, but still some. Weirdly, this also means I don't have any close by ratios I could drive it at with a stepper without getting inch error too. I'm going to have to think this over, but I think it's likely it's not going to be a big deal either way.

I think the leadscrew pitch should be calculated to include the reduction.

My spindle encoder has a 1:1 gearing with the spindle, i'm assuming you also are going to be mounting the encoder to the spindle in the same way, but it should be possible to adjust for a non 1:1 encoder ratio.

here is the check to be sure the ratios work for single quadrant Bresenham https://github.com/jschoch/ESPels/blob/master/src/src/Controls.cpp#L190-L199

Important to note that the error is in a fixed range and shouldn't grow. all that magic happens here: https://github.com/jschoch/ESPels/blob/master/src/src/gear.h

I also have an open loop. I was looking at the ESP-Flexystepper (which I've converted to be non-arduino so I could run it in an Espressif esp-idf toolchain directly) for my own firmware I had started, and it has some interesting possibilities. Such as commands that tell it to move a certain distance relative to it's own internally tracked state, and it runs until it's gotten there, with a nice acceleration loop. It also has a separate deceleration configuration, which is nice for a machine like this that often can decelerate faster than accelerate. Just an option. A possible implementation is here, if you're curious. https://github.com/digiexchris/LeadscrewWarrantyVoider/tree/master/main (more to get my thoughts down than anything serious). I pinned the stepper manager on one cpu to make sure it doesn't lag on sending steps to the closed loop driver.

I had some isssues with pinning, it was actually faster without pinning, the RTM part doesn't use CPU though. I'm open to other step gen libraries but they should use RTM or have a hook for us to use it. The RTM peripheral can do like 200khz stepping with no added CPU loading.

Anyway, I did get your firmware and frontend to compile, but I had to work some of the dependency chain a little bit, seems that some people have renamed and consolidated github projects since. Got the setup running on my hardware too! I can do a pull request with those changes.

Let me know what had issues and i'm happy to update dependencies

Do you mind if I do a little bit of a reorganization? I love the functionality you already have in place, but I've moved a few things around in my local copy so I could understand it better and separate some concerns a bit. I think in c++ a little easier also, if you're not opposed to that.

I'm open to looking at any changes you may propose. The main thing I see as needing work is the threading offset calculation and workflow. I don't typically use a compound so I have a bit of a hack in there to use some trig to figure out how much offset to use on each pass so the cutter moves in like a compound would. There are also several approaches to doing this (move in from left, or right, or center and out to each side) that could be configurable. If you had an X stepper this could be more automated. Now it can just offset the thread start to mostly automate it but it requires the operator to keep track of which pass it is on.

Another thing I was thinking about is storing the web stuff on an i2c sd card reader along with wifi config and maybe machine config, so it's a little more out of the box for others. Far in the future thought though.

I'm open to making this configurable but putting it on S3 is pretty much no effort for an end user. The machine firmware config gets stored in nv-ram but it could also get stuffed into a cookie with a way to export/import json.

Regarding overflows, are you doing any resetting of the counter if it gets close to the overflow point? I think it's probably not difficult to solve just to future proof it for people that have other needs, like if they need to gear a motor down a lot.

I think it needs to run for something like 24 hours straight to overflow, but I'm open to adding something to check it.

I'll spend some time with a gear calculator and see if I can get a change gear combination that spits out round numbers for inch stuff and see how that changes my preferences. I was also thinking of trying to find a close ratio that works for Metric on my lathe too, and then just make some kind of switchover mechanism to switch the stepper onto the metric converting pulley or something, with maybe a microswitch to tell the firmware which mode it's in.

i'd like to implement 4 quadrant Bresenham, right now the max thread pitch is limited because the slope can't be more than 1, but it is something i havn't bothered to do yet

not sure how fast this would run on the esp32 or if it can work with the boost Rational classes... https://github.com/ashiagarwal73/Bresenham-s-line-algorithm-for-all-quadrants

Do you have a link to that rational number math from the other firmware? Having trouble finding it, that sounds interesting too.

https://github.com/prototypicall/Didge/blob/master/firmware/ext/boost/rational_minimal.hpp

and

https://github.com/prototypicall/Didge/blob/8fa59816286a575c28f201cbd2113bb64574e99b/firmware/threads.hpp#L16

My c/c++ skills are pretty weak and my understanding of toolchains, linking etc is even worse. I also tend to do spurts every 6 months so I forget everything each time and re-learn the same basic c++ crap over and over. I've progressed some since I started this. compiling in the boost libs may be easier than I thought but didge has a strange dependency called Kvasir which is like a HAL.

Also the react code is in need of modularization, it was my first react hooks project and almost no effort was put into making it pretty.

Finally I'm open to moving this to the esp-idf if we can manage to get all the dependencies working, the hardest are ArduinoJSON which does all the grunt work for serialization, and asyncwebserver which handles the websockets. I've seen others use ArduinoJSON outside of arduino so it should be possible. I'm using VS code which has an IDF plugin. I'm also fine with sticking with platformIO + Arduino env.

digiexchris commented 1 year ago

thanks you've definitely made me rethink some of my assumptions! I bet the issues reported by the author of ESP-flexystepper is solved using the RTM. 200khz is good up to 60000 rpm in native steps or 7500 rpm at 8x microstepping! More than enough for anyone I know that's doing manual threading.

One thing I didn't see but maybe I'm thinking about it wrong, do you have a normal feeding mode? where it would run the leadscrew forever and let me feed like I do now with manual change gears for normal turning, by engaging and disengaging the half nuts? Seems like everything requires a distance to move in jog mode but I'm probably just looking in the wrong spot.

I think the idea with the leadscrew reduction in my lathe headstock is 28tpi has less error for metric than both 7 and 8 tpi do for some small threads. Error not growing, good point. I'll take a look at that algorithm you linked.

There is an Arduino shim so getting it working on esp-idf is no big deal. But I don't think switching from Arduino is something that needs to happen really. There's a lot of great peripheral support in the arduino world as third party libraries, and you've gotta hand roll a bunch of stuff for the esp-idf ecosystem (though that's gotten a lot better in the last two years). But on the other hand you get a lot more control over the hardware direct through esp-idf. I don't have a good reason for suggesting it, I've just spent more time there with the esp than with the arduino stuff. I'm happy with upsetting the cart as little as possible.

For now, I'll get that dependency list packaged up and sent over. Wasn't complicated. Again, maybe I'm just blind and didn't see the obvious :)

jschoch commented 1 year ago

thanks you've definitely made me rethink some of my assumptions! I bet the issues reported by the author of ESP-flexystepper is solved using the RTM. 200khz is good up to 60000 rpm in native steps or 7500 rpm at 8x microstepping! More than enough for anyone I know that's doing manual threading.

I don't think you want to thread at 6k rpm ;)

One thing I didn't see but maybe I'm thinking about it wrong, do you have a normal feeding mode? where it would run the leadscrew forever and let me feed like I do now with manual change gears for normal turning, by engaging and disengaging the half nuts? Seems like everything requires a distance to move in jog mode but I'm probably just looking in the wrong spot.

You should get a bench setup going so you can see it working and get familiar with the UI. We could add a bit to the vitural encoder to make that easier. The debugging screen updates every 200ms or so, maybe needs some tweaking of the naming, but it shows what's going on. that said the way I actually us it is like this:

  1. I almost never release the half nut when operating with the ELS, to the point where I got rid of the mode where it just runs all the time. It can be added back easily but I honestly never use it.
  2. The "jog" functions are what I use to make the cuts, I adjust the pitch and depth of cut and then "jog" to make the cut. Again maybe naming is confusing here.
  3. If I have a lot of material to remove I have a "bounce" mode that will cut to a distance and rapid back to the start position. https://www.youtube.com/watch?v=fqDJYVlFkZ8
  4. the benefits for 2 and 3 are that I can maintain position and that helps when machining up to a feature. The downside is leadscrew wear.

I recently added a scale to the Z with touchdro, where as before accurate positioning of the Z was pretty difficult. This made full time halfnut more attractive for actual work where you could skip setting up a dial indicator for positioning. Let me know and we'll look at adding the full time mode back in, and also let me know if you have a bench setup. We can start a new branch to work out some of this stuff.

digiexchris commented 1 year ago

yup sounds good. I also have touchdro going, it's a life changer. I'd highly recommend considering a scale for touchdro on both the cross slide and the tailstock. Huge improvement in how fast I can get fussy precision work done. I wonder if I can convince Yuriy to add a webhook to the touchdro UI so we could use it to set the end position for a jog...

I have it running on my workbench right now, I'm moving the encoder by hand. The stepper tracks extremely well even with the naive acceleration implementation and closed loop turned off. I personally don't feel that reworking the acceleration logic is worth it for a normal lathe, since there's built in acceleration in the spindle motor. Clough42 has done extensive testing on his, with zero acceleration at all and it works fine.

Yeah I don't mean threading at 6000rpm, I mean the stepper turning at 6000 rpm for some use cases, like in in order to feed making finishing cuts on small work turning 2000 rpm in the spindle with a 3:1 reduction between the stepper and the leadscrew (to reduce costs on the stepper and decrease degrees per step at the same time, some people might like that, or would be required for something like a servo motor), would require the stepper to turn at 6000 rpm.

I've also been thinking about this ELS system for my mill too, have it run in a totally different mode that either doesn't require an encoder, for normal feeding, or has an encoder in a perpendicular axis enabling helical and bevel gear cutting, or crazy angles without changing setups. Far far far future thought though, I'd personally need a MUCH bigger stepper.

I'll have a pull request up today I think with the dependency changes and moving some simple config.h stuff around and adding comments to ease access for less programmery users. Oh also a note for the UI, several deps require Node 14, we should pin that in the package.json.

I didn't do it, but I also recommend we commit the dependencies to the repo for the firmware side of things, which is more common in the C/C++ world. It means that if someone stumbles onto this in 10 years and wants to try it, they can without fixing missing deps. More important for a stable product. Also, there was that whole leftpad debaucle years ago. It's not that common to commit deps in javascript because of the whole "everything takes 900000 dependencies" but it's super common in game dev and industrial c++.

You know, even if we don't actually change anything, I'm having a blast! Thanks for putting this code base out on the internet!

digiexchris commented 1 year ago

oh also, are you able to update the s3 ui? it seems out of date with master. it was missing the configuration section when I looked at it and compared it to the copy I built from master.

jschoch commented 1 year ago

yup sounds good. I also have touchdro going, it's a life changer. I'd highly recommend considering a scale for touchdro on both the cross slide and the tailstock. Huge improvement in how fast I can get fussy precision work done. I wonder if I can convince Yuriy to add a webhook to the touchdro UI so we could use it to set the end position for a jog...

let's breakout some of these ideas into additional issues, I'm using a esp32 and my own board for touch DRO so we might be able to do some integration.

I have it running on my workbench right now, I'm moving the encoder by hand. The stepper tracks extremely well even with the naive acceleration implementation and closed loop turned off. I personally don't feel that reworking the acceleration logic is worth it for a normal lathe, since there's built in acceleration in the spindle motor. Clough42 has done extensive testing on his, with zero acceleration at all and it works fine.

We can deprioritizie this but based on my hobber code it shouldn't be all that much work. Again, another issue to track it.

Yeah I don't mean threading at 6000rpm, I mean the stepper turning at 6000 rpm for some use cases, like in in order to feed making finishing cuts on small work turning 2000 rpm in the spindle with a 3:1 reduction between the stepper and the leadscrew (to reduce costs on the stepper and decrease degrees per step at the same time, some people might like that, or would be required for something like a servo motor), would require the stepper to turn at 6000 rpm.

Stepper torque falls off pretty quickly after 800 RPM or so, so that is also bad. My servo's only go 3k rpm.

I've also been thinking about this ELS system for my mill too, have it run in a totally different mode that either doesn't require an encoder, for normal feeding, or has an encoder in a perpendicular axis enabling helical and bevel gear cutting, or crazy angles without changing setups. Far far far future thought though, I'd personally need a MUCH bigger stepper.

I'll have a pull request up today I think with the dependency changes and moving some simple config.h stuff around and adding comments to ease access for less programmery users. Oh also a note for the UI, several deps require Node 14, we should pin that in the package.json.

I just merged some changes from the nvram2 branch, try them out and see if they don't clobber your work first.

I didn't do it, but I also recommend we commit the dependencies to the repo for the firmware side of things, which is more common in the C/C++ world. It means that if someone stumbles onto this in 10 years and wants to try it, they can without fixing missing deps. More important for a stable product. Also, there was that whole leftpad debaucle years ago. It's not that common to commit deps in javascript because of the whole "everything takes 900000 dependencies" but it's super common in game dev and industrial c++.

I"m open to this, not exactly sure how to do that, is it just a matter of updating the .gitignore?

You know, even if we don't actually change anything, I'm having a blast! Thanks for putting this code base out on the internet!

Sure thing, this is the good part of the intarwebs

digiexchris commented 1 year ago

let's breakout some of these ideas into additional issues, I'm using a esp32 and my own board for touch DRO so we might be able to do some integration.

Yup good idea. We should close this and separate stuff into different discussions.

We can deprioritizie this but based on my hobber code it shouldn't be all that much work. Again, another issue to track it.

yeah and if you already have it working, why not.

Stepper torque falls off pretty quickly after 800 RPM or so, so that is also bad. My servo's only go 3k rpm.

Agreed but that's not the case for all hardware combinations. My stepper with the closed loop digital driver maintains more than enough torque up to 1500 (even though it's 1/4 of it's torque). Also, the Teknic servos can peak at 6000. But really my point was, 200kHz is more than enough for a hobby environment! So the limitations of the RMT is still an excellent choice.

I didn't do it, but I also recommend we commit the dependencies to the repo for the firmware side of things, which is more common in the C/C++ world. It means that if someone stumbles onto this in 10 years and wants to try it, they can without fixing missing deps. More important for a stable product. Also, there was that whole leftpad debaucle years ago. It's not that common to commit deps in javascript because of the whole "everything takes 900000 dependencies" but it's super common in game dev and industrial c++.

I"m open to this, not exactly sure how to do that, is it just a matter of updating the .gitignore?

I'll just move the deps out of the platformio cache into a libs dir and commit them directly, and update a lib path in the platformio.ini. Easier than it sounds :). No worries I'll handle it and make it obvious how.

jschoch commented 1 year ago

here's a build of the hob_branch for the frontend, give it a try http://espels.s3-us-west-2.amazonaws.com/hob_branch_01/index.html