clough42 / electronic-leadscrew

Lathe electronic leadscrew controller
MIT License
321 stars 117 forks source link

Thread table calculation limitations #254

Open johnsonm opened 1 year ago

johnsonm commented 1 year ago

My G0709 lathe change gears and gear box support more thread pitches than the ELS tables currently include. Some of this is just going beyond the range of the tables. It's easy to add 4TPI or 112TPI, 0.1mm or 7mm. But some can't be supported due to the precision of the calculations; e.g. .125mm, 5.75mm, 5.75TPI. Here's the full range of supported threads:

image

image

Would there be any appetite for adding a digit of precision to have the option for these additional thread specs? It would also mean shifting the display over for every thread spec. E.g. it would look something like:

const FEED_THREAD metric_thread_table[] =
{
 { .display = {ZERO  | POINT, ONE,   ZERO, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(100) },
 { .display = {ZERO  | POINT, ONE,   TWO,   FIVE}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(125) },
 { .display = {ZERO  | POINT, TWO,   ZERO, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(200) },
 { .display = {ZERO  | POINT, TWO,   FIVE, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(250) 
...
},

I recognize that adding lots of thread specs would mean more button pushing. I could see adding them conditionally, say by changing a new default #define EXTENDED_THREAD_TABLE false to #define EXTENDED_THREAD_TABLE true in Configuration.h and leaving only the more common thread specs outside that define in Tables.cpp.

tomvikse commented 1 year ago

Just set up common one in the start,and the more spesial in the end.. or use "thread to shoulder" firmware custom thread pitches

https://github.com/kwackers/electronic-leadscrew

johnsonm commented 1 year ago

Sorry, I guess I wasn't clear enough about the problem. I am using the kwackers branch as my starting point.

The TPI_FRACTION and HMM_FRACTION macros cannot represent 5.75TPI or .125mm or .225mm pitch because of their units and the fact that they are integer not floats.

I'm proposing changing the units for those macros from "threads per 10 inches" and "hundredths of a millimeter pitch" to "threads per 100 inches" and "thousandths of a millimeter" respectively, in order to support additional threads that cannot be supported with the current units.

johnsonm commented 1 year ago

I note that doing this makes right-justifying with a decimal point moving around happen more, so what I'm playing with keeps the decimal point fixed as much as possible. There's just one jump, between the ones and the tens, which is needed in order to support 5.75TPI (who uses that anyway‽ but a web search shows that there are definitely a bunch of lathe models that support it...)

Anyway, increasing the numerators by a factor of ten in the macros, and the denominators by a factor of ten in the declarations, should cut the same threads. I could have typos or bugs in here, but just to show what it I'm thinking:

#if defined(LEADSCREW_TPI)
#define TPI_NUMERATOR(tpi) ((Uint64)LEADSCREW_TPI*STEPPER_RESOLUTION*STEPPER_MICROSTEPS*100)
#define TPI_DENOMINATOR(tpi) ((Uint64)tpi*ENCODER_RESOLUTION)
#endif
#if defined(LEADSCREW_HMM)
#define TPI_NUMERATOR(tpi) ((Uint64)254*1000*STEPPER_RESOLUTION*STEPPER_MICROSTEPS)
#define TPI_DENOMINATOR(tpi) ((Uint64)tpi*ENCODER_RESOLUTION*LEADSCREW_HMM)
#endif
#define TPI_FRACTION(tpi) .numerator = TPI_NUMERATOR(tpi), .denominator = TPI_DENOMINATOR(tpi)

const FEED_THREAD inch_thread_table[] =
{
#ifdef EXTENDED_INCH_THREADS
 { .display = {BLANK, FOUR,       BLANK, BLANK},   .leds = LED_THREAD | LED_TPI, TPI_FRACTION(400) },
 { .display = {BLANK, FOUR|POINT, FIVE,  BLANK},   .leds = LED_THREAD | LED_TPI, TPI_FRACTION(450) },
 { .display = {BLANK, FIVE,       BLANK, BLANK},   .leds = LED_THREAD | LED_TPI, TPI_FRACTION(500) },
 { .display = {BLANK, FIVE|POINT, FIVE,  BLANK},   .leds = LED_THREAD | LED_TPI, TPI_FRACTION(550) },
 { .display = {BLANK, FIVE|POINT, SEVEN, FIVE},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(575) },
 { .display = {BLANK, SIX,        BLANK, BLANK},   .leds = LED_THREAD | LED_TPI, TPI_FRACTION(600) },
 { .display = {BLANK, SIX|POINT,  FIVE,  BLANK},   .leds = LED_THREAD | LED_TPI, TPI_FRACTION(650) },
 { .display = {BLANK, SEVEN,      BLANK, BLANK},   .leds = LED_THREAD | LED_TPI, TPI_FRACTION(700) },
#endif
 { .display = {BLANK, EIGHT,      BLANK, BLANK},   .leds = LED_THREAD | LED_TPI, TPI_FRACTION(800) },
 { .display = {BLANK, NINE,       BLANK, BLANK},   .leds = LED_THREAD | LED_TPI, TPI_FRACTION(900) },
#ifdef EXTENDED_INCH_THREADS
 { .display = {BLANK, NINE|POINT, FIVE,  BLANK},   .leds = LED_THREAD | LED_TPI, TPI_FRACTION(950) },
#endif
 { .display = {BLANK, ONE,   ZERO,      BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(1000) },
 { .display = {BLANK, ONE,   ONE,       BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(1100) },
 { .display = {BLANK, ONE,   ONE|POINT, FIVE},     .leds = LED_THREAD | LED_TPI, TPI_FRACTION(1150) },
 { .display = {BLANK, ONE,   TWO,       BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(1200) },
 { .display = {BLANK, ONE,   THREE,     BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(1300) },
 { .display = {BLANK, ONE,   FOUR,      BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(1400) },
 { .display = {BLANK, ONE,   SIX,       BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(1600) },
 { .display = {BLANK, ONE,   EIGHT,     BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(1800) },
 { .display = {BLANK, ONE,   NINE,      BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(1900) },
 { .display = {BLANK, TWO,   ZERO,      BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(2000) },
#ifdef EXTENDED_INCH_THREADS
 { .display = {BLANK, TWO,   TWO,       BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(2200) },
 { .display = {BLANK, TWO,   THREE,     BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(2300) },
#endif
 { .display = {BLANK, TWO,   FOUR,      BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(2400) },
 { .display = {BLANK, TWO,   SIX,       BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(2600) },
 { .display = {BLANK, TWO,   SEVEN,     BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(2700) },
 { .display = {BLANK, TWO,   EIGHT,     BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(2800) },
 { .display = {BLANK, THREE, TWO,       BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(3200) },
 { .display = {BLANK, THREE, SIX,       BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(3600) },
#ifdef EXTENDED_INCH_THREADS
 { .display = {BLANK, THREE, EIGHT,     BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(3800) },
#endif
 { .display = {BLANK, FOUR,  ZERO,      BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(4000) },
 { .display = {BLANK, FOUR,  FOUR,      BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(4400) },
#ifdef EXTENDED_INCH_THREADS
 { .display = {BLANK, FOUR,  SIX,       BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(4600) },
#endif
 { .display = {BLANK, FOUR,  EIGHT,     BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(4800) },
 { .display = {BLANK, FIVE,  SIX,       BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(5600) },
 { .display = {BLANK, SIX,   FOUR,      BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(6400) },
 { .display = {BLANK, SEVEN, TWO,       BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(7200) },
 { .display = {BLANK, EIGHT, ZERO,      BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(8000) },
#ifdef EXTENDED_INCH_THREADS
 { .display = {BLANK, EIGHT, EIGHT,     BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(8800) },
 { .display = {BLANK, NINE,  TWO,       BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(9200) },
 { .display = {BLANK, NINE,  SIX,       BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(9600) },
 { .display = {ONE,   ZERO,  FOUR,      BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(10400) },
 { .display = {ONE,   ONE,   TWO,       BLANK},    .leds = LED_THREAD | LED_TPI, TPI_FRACTION(11200) },
#endif
};

...

#if defined(LEADSCREW_TPI)
#define HMM_NUMERATOR(hmm) ((Uint64)hmm*LEADSCREW_TPI*STEPPER_RESOLUTION*STEPPER_MICROSTEPS)
#define HMM_DENOMINATOR(hmm) ((Uint64)ENCODER_RESOLUTION*254*100)
#endif
#if defined(LEADSCREW_HMM)
#define HMM_NUMERATOR(hmm) ((Uint64)hmm*STEPPER_RESOLUTION*STEPPER_MICROSTEPS)
#define HMM_DENOMINATOR(hmm) ((Uint64)ENCODER_RESOLUTION*LEADSCREW_HMM*10)
#endif
#define HMM_FRACTION(hmm) .numerator = HMM_NUMERATOR(hmm), .denominator = HMM_DENOMINATOR(hmm)

const FEED_THREAD metric_thread_table[] =
{
#ifdef EXTENDED_METRIC_THREADS
 { .display = {POINT,         ONE,   BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(100) },
 { .display = {POINT,         ONE,   TWO,   FIVE},  .leds = LED_THREAD | LED_MM, HMM_FRACTION(125) },
 { .display = {POINT,         ONE,   FIVE,  BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(150) },
#endif
 { .display = {POINT,         TWO,   BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(200) },
#ifdef EXTENDED_METRIC_THREADS
 { .display = {POINT,         TWO,   TWO,   FIVE},  .leds = LED_THREAD | LED_MM, HMM_FRACTION(225) },
#endif
 { .display = {POINT,         TWO,   FIVE,  BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(250) },
 { .display = {POINT,         THREE, BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(300) },
 { .display = {POINT,         THREE, FIVE,  BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(350) },
 { .display = {POINT,         FOUR,  BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(400) },
 { .display = {POINT,         FOUR,  FIVE,  BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(450) },
 { .display = {POINT,         FIVE,  BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(500) },
#ifdef EXTENDED_METRIC_THREADS
 { .display = {POINT,         FIVE,  FIVE,  BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(550) },
#endif
 { .display = {POINT,         SIX,   BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(600) },
#ifdef EXTENDED_METRIC_THREADS
 { .display = {POINT,         SIX,   FIVE,  BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(650) },
#endif
 { .display = {POINT,         SEVEN, BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(700) },
 { .display = {POINT,         SEVEN, FIVE, BLANK},  .leds = LED_THREAD | LED_MM, HMM_FRACTION(750) },
 { .display = {POINT,         EIGHT, BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(800) },
#ifdef EXTENDED_METRIC_THREADS
 { .display = {POINT,         EIGHT, SEVEN, FIVE},  .leds = LED_THREAD | LED_MM, HMM_FRACTION(875) },
 { .display = {POINT,         NINE,  BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(900) },
#endif
 { .display = {ONE,           BLANK, BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(1000) },
#ifdef EXTENDED_METRIC_THREADS
 { .display = {ONE | POINT,   ONE,   BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(1100) },
 { .display = {ONE | POINT,   TWO,   BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(1200) },
#endif
 { .display = {ONE | POINT,   TWO,   FIVE, BLANK},  .leds = LED_THREAD | LED_MM, HMM_FRACTION(1250) },
#ifdef EXTENDED_METRIC_THREADS
 { .display = {ONE | POINT,   THREE, BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(1300) },
 { .display = {ONE | POINT,   FOUR,  BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(1400) },
#endif
 { .display = {ONE | POINT,   FIVE,  BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(1500) },
#ifdef EXTENDED_METRIC_THREADS
 { .display = {ONE | POINT,   SIX,   BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(1600) },
#endif
 { .display = {ONE | POINT,   SEVEN, FIVE, BLANK},  .leds = LED_THREAD | LED_MM, HMM_FRACTION(1750) },
#ifdef EXTENDED_METRIC_THREADS
 { .display = {ONE | POINT,   EIGHT, BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(1800) },
#endif
 { .display = {TWO,           BLANK, BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(2000) },
#ifdef EXTENDED_METRIC_THREADS
 { .display = {TWO | POINT,   TWO,   FIVE,  BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(2250) },
#endif
 { .display = {TWO | POINT,   FIVE,  BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(2500) },
#ifdef EXTENDED_METRIC_THREADS
 { .display = {TWO | POINT,   SEVEN, FIVE,  BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(2750) },
#endif
 { .display = {THREE,         BLANK, BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(3000) },
#ifdef EXTENDED_METRIC_THREADS
 { .display = {THREE | POINT, TWO,   FIVE,  BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(3250) },
#endif
 { .display = {THREE | POINT, FIVE,  BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(3500) },
 { .display = {FOUR,          BLANK, BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(4000) },
 { .display = {FOUR | POINT,  FIVE,  BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(4500) },
 { .display = {FIVE,          BLANK, BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(5000) },
 { .display = {FIVE | POINT,  FIVE,  BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(5500) },
#ifdef EXTENDED_METRIC_THREADS
 { .display = {FIVE | POINT,  SEVEN, FIVE,  BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(5750) },
#endif
 { .display = {SIX,           BLANK, BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(6000) },
#ifdef EXTENDED_METRIC_THREADS
 { .display = {SIX | POINT,   FIVE,  BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(6500) },
 { .display = {SEVEN,         BLANK, BLANK, BLANK}, .leds = LED_THREAD | LED_MM, HMM_FRACTION(7000) },
#endif
};

I'll plan to PR the patch against mainline but I'll be merging it in my own repo on top of the kwackers fork for my own use, because I absolutely want that functionality.

I'd also think that adding these outlandish thread specs would make a lot of button-pushing, so I also added configuration to explicitly setting a default index for power-on, and made it be the same value by default whether the extended thread tables are selected or not.