Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
clough42 committed Oct 11, 2020
2 parents 37415a0 + 16c39ab commit 7a5f6fb
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 79 deletions.
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ lathe spindle. The electronic controller allows setting different virtual gear

![Silkscreened Control Panel](https://raw.githubusercontent.com/clough42/electronic-leadscrew/master/docs/images/CPKit.jpg)

## Latest Version

The latest version of the firmware has been updated with several new features and fixes:
* Fix phantom control panel button presses
* Add power button support
* Fix integer overflow for large metric threads
* Prevent mode and direction changes while running
* Smooth tachometer display
* Add support for lathes with separate feed and thread gearing

[DOWNLOAD HERE](https://github.com/clough42/electronic-leadscrew/releases)

## Project Status
Beta.

Expand All @@ -15,7 +27,7 @@ for your lathe does require require basic electronics and troubleshooting skills
yourself.**

## Documentation
For documentation, please [**visit the project wiki**](https://github.com/clough42/electronic-leadscrew/wiki).
For documentation, please [**VISIT THE PROJECT WIKI**](https://github.com/clough42/electronic-leadscrew/wiki).

## Concept
The project is still in active development. The current hardware looks like this:
Expand Down
7 changes: 6 additions & 1 deletion els-f280049c/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@
#define STEPPER_MICROSTEPS 8
#define STEPPER_RESOLUTION 200

// Separate step and microstep settings for feed rates. Redefine these if your
// lathe has a separate feed drive train with a different ratio.
#define STEPPER_MICROSTEPS_FEED STEPPER_MICROSTEPS
#define STEPPER_RESOLUTION_FEED STEPPER_RESOLUTION

// Step, direction and enable pins are normally active-high
// #define INVERT_STEP_PIN true
// #define INVERT_DIRECTION_PIN true
Expand Down Expand Up @@ -156,7 +161,7 @@
#define UI_REFRESH_RATE_HZ 100

// RPM recalculation rate, in Hz
#define RPM_CALC_RATE_HZ 10
#define RPM_CALC_RATE_HZ 2

// Microprocessor system clock
#define CPU_CLOCK_MHZ 100
Expand Down
7 changes: 7 additions & 0 deletions els-f280049c/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ Core :: Core( Encoder *encoder, StepperDrive *stepperDrive )
this->previousSpindlePosition = 0;
this->previousFeedDirection = 0;
this->previousFeed = NULL;

this->powerOn = true; // default to power on
}

void Core :: setReverse(bool reverse)
Expand All @@ -54,6 +56,11 @@ void Core :: setReverse(bool reverse)
}
}

void Core :: setPowerOn(bool powerOn)
{
this->powerOn = powerOn;
this->stepperDrive->setEnabled(powerOn);
}



Expand Down
10 changes: 10 additions & 0 deletions els-f280049c/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ class Core

int32 feedRatio(Uint32 count);

bool powerOn;

public:
Core( Encoder *encoder, StepperDrive *stepperDrive );

Expand All @@ -62,6 +64,9 @@ class Core
Uint16 getRPM(void);
bool isAlarm();

bool isPowerOn();
void setPowerOn(bool);

void ISR( void );
};

Expand All @@ -84,6 +89,11 @@ inline bool Core :: isAlarm()
return this->stepperDrive->isAlarm();
}

inline bool Core :: isPowerOn()
{
return this->powerOn;
}

inline int32 Core :: feedRatio(Uint32 count)
{
#ifdef USE_FLOATING_POINT
Expand Down
13 changes: 13 additions & 0 deletions els-f280049c/StepperDrive.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ class StepperDrive
void incrementCurrentPosition(int32 increment);
void setCurrentPosition(int32 position);

void setEnabled(bool);

bool isAlarm();

void ISR(void);
Expand All @@ -119,6 +121,17 @@ inline void StepperDrive :: setCurrentPosition(int32 position)
this->currentPosition = position;
}

inline void StepperDrive :: setEnabled(bool enabled)
{
if( enabled ) {
GPIO_SET_ENABLE;
}
else
{
GPIO_CLEAR_ENABLE;
}
}

inline bool StepperDrive :: isAlarm()
{
#ifdef USE_ALARM_PIN
Expand Down
56 changes: 33 additions & 23 deletions els-f280049c/Tables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,11 @@ const FEED_THREAD inch_thread_table[] =
//

#if defined(LEADSCREW_TPI)
#define THOU_IN_NUMERATOR(thou) ((Uint64)thou*LEADSCREW_TPI*STEPPER_RESOLUTION*STEPPER_MICROSTEPS)
#define THOU_IN_NUMERATOR(thou) ((Uint64)thou*LEADSCREW_TPI*STEPPER_RESOLUTION_FEED*STEPPER_MICROSTEPS_FEED)
#define THOU_IN_DENOMINATOR(thou) ((Uint64)ENCODER_RESOLUTION*1000)
#endif
#if defined(LEADSCREW_HMM)
#define THOU_IN_NUMERATOR(thou) ((Uint64)thou*254*STEPPER_RESOLUTION*STEPPER_MICROSTEPS)
#define THOU_IN_NUMERATOR(thou) ((Uint64)thou*254*STEPPER_RESOLUTION_FEED*STEPPER_MICROSTEPS_FEED)
#define THOU_IN_DENOMINATOR(thou) ((Uint64)ENCODER_RESOLUTION*100*LEADSCREW_HMM)
#endif
#define THOU_IN_FRACTION(thou) .numerator = THOU_IN_NUMERATOR(thou), .denominator = THOU_IN_DENOMINATOR(thou)
Expand Down Expand Up @@ -171,29 +171,39 @@ const FEED_THREAD metric_thread_table[] =
// Each row in the table defines a standard metric feed, with the display data,
// LED indicator states and gear ratio fraction to use.
//
#if defined(LEADSCREW_TPI)
#define HMM_NUMERATOR_FEED(hmm) ((Uint64)hmm*10*LEADSCREW_TPI*STEPPER_RESOLUTION_FEED*STEPPER_MICROSTEPS_FEED)
#define HMM_DENOMINATOR_FEED(hmm) ((Uint64)ENCODER_RESOLUTION*254*100)
#endif
#if defined(LEADSCREW_HMM)
#define HMM_NUMERATOR_FEED(hmm) ((Uint64)hmm*STEPPER_RESOLUTION_FEED*STEPPER_MICROSTEPS_FEED)
#define HMM_DENOMINATOR_FEED(hmm) ((Uint64)ENCODER_RESOLUTION*LEADSCREW_HMM)
#endif
#define HMM_FRACTION_FEED(hmm) .numerator = HMM_NUMERATOR_FEED(hmm), .denominator = HMM_DENOMINATOR_FEED(hmm)

const FEED_THREAD metric_feed_table[] =
{
{ .display = {BLANK, POINT, ZERO, TWO}, .leds = LED_FEED | LED_MM, HMM_FRACTION(2) },
{ .display = {BLANK, POINT, ZERO, FIVE}, .leds = LED_FEED | LED_MM, HMM_FRACTION(5) },
{ .display = {BLANK, POINT, ZERO, SEVEN}, .leds = LED_FEED | LED_MM, HMM_FRACTION(7) },
{ .display = {BLANK, POINT, ONE, ZERO}, .leds = LED_FEED | LED_MM, HMM_FRACTION(10) },
{ .display = {BLANK, POINT, ONE, TWO}, .leds = LED_FEED | LED_MM, HMM_FRACTION(12) },
{ .display = {BLANK, POINT, ONE, FIVE}, .leds = LED_FEED | LED_MM, HMM_FRACTION(15) },
{ .display = {BLANK, POINT, ONE, SEVEN}, .leds = LED_FEED | LED_MM, HMM_FRACTION(17) },
{ .display = {BLANK, POINT, TWO, ZERO}, .leds = LED_FEED | LED_MM, HMM_FRACTION(20) },
{ .display = {BLANK, POINT, TWO, TWO}, .leds = LED_FEED | LED_MM, HMM_FRACTION(22) },
{ .display = {BLANK, POINT, TWO, FIVE}, .leds = LED_FEED | LED_MM, HMM_FRACTION(25) },
{ .display = {BLANK, POINT, TWO, SEVEN}, .leds = LED_FEED | LED_MM, HMM_FRACTION(27) },
{ .display = {BLANK, POINT, THREE, ZERO}, .leds = LED_FEED | LED_MM, HMM_FRACTION(30) },
{ .display = {BLANK, POINT, THREE, FIVE}, .leds = LED_FEED | LED_MM, HMM_FRACTION(35) },
{ .display = {BLANK, POINT, FOUR, ZERO}, .leds = LED_FEED | LED_MM, HMM_FRACTION(40) },
{ .display = {BLANK, POINT, FOUR, FIVE}, .leds = LED_FEED | LED_MM, HMM_FRACTION(45) },
{ .display = {BLANK, POINT, FIVE, ZERO}, .leds = LED_FEED | LED_MM, HMM_FRACTION(50) },
{ .display = {BLANK, POINT, FIVE, FIVE}, .leds = LED_FEED | LED_MM, HMM_FRACTION(55) },
{ .display = {BLANK, POINT, SIX, ZERO}, .leds = LED_FEED | LED_MM, HMM_FRACTION(60) },
{ .display = {BLANK, POINT, SEVEN, ZERO}, .leds = LED_FEED | LED_MM, HMM_FRACTION(70) },
{ .display = {BLANK, POINT, EIGHT, FIVE}, .leds = LED_FEED | LED_MM, HMM_FRACTION(85) },
{ .display = {BLANK, ONE | POINT, ZERO, ZERO}, .leds = LED_FEED | LED_MM, HMM_FRACTION(100) },
{ .display = {BLANK, POINT, ZERO, TWO}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(2) },
{ .display = {BLANK, POINT, ZERO, FIVE}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(5) },
{ .display = {BLANK, POINT, ZERO, SEVEN}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(7) },
{ .display = {BLANK, POINT, ONE, ZERO}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(10) },
{ .display = {BLANK, POINT, ONE, TWO}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(12) },
{ .display = {BLANK, POINT, ONE, FIVE}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(15) },
{ .display = {BLANK, POINT, ONE, SEVEN}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(17) },
{ .display = {BLANK, POINT, TWO, ZERO}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(20) },
{ .display = {BLANK, POINT, TWO, TWO}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(22) },
{ .display = {BLANK, POINT, TWO, FIVE}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(25) },
{ .display = {BLANK, POINT, TWO, SEVEN}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(27) },
{ .display = {BLANK, POINT, THREE, ZERO}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(30) },
{ .display = {BLANK, POINT, THREE, FIVE}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(35) },
{ .display = {BLANK, POINT, FOUR, ZERO}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(40) },
{ .display = {BLANK, POINT, FOUR, FIVE}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(45) },
{ .display = {BLANK, POINT, FIVE, ZERO}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(50) },
{ .display = {BLANK, POINT, FIVE, FIVE}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(55) },
{ .display = {BLANK, POINT, SIX, ZERO}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(60) },
{ .display = {BLANK, POINT, SEVEN, ZERO}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(70) },
{ .display = {BLANK, POINT, EIGHT, FIVE}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(85) },
{ .display = {BLANK, ONE | POINT, ZERO, ZERO}, .leds = LED_FEED | LED_MM, HMM_FRACTION_FEED(100) },
};


Expand Down
116 changes: 63 additions & 53 deletions els-f280049c/UserInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

const MESSAGE STARTUP_MESSAGE_2 =
{
.message = { LETTER_E, LETTER_L, LETTER_S, DASH, ONE | POINT, TWO | POINT, ZERO, ZERO },
.message = { LETTER_E, LETTER_L, LETTER_S, DASH, ONE | POINT, THREE | POINT, ZERO, ONE },
.displayTime = UI_REFRESH_RATE_HZ * 1.5
};

Expand All @@ -52,6 +52,8 @@ const MESSAGE SETTINGS_MESSAGE_1 =
.next = &SETTINGS_MESSAGE_2
};

const Uint16 VALUE_BLANK[4] = { BLANK, BLANK, BLANK, BLANK };

UserInterface :: UserInterface(ControlPanel *controlPanel, Core *core, FeedTableFactory *feedTableFactory)
{
this->controlPanel = controlPanel;
Expand All @@ -66,6 +68,10 @@ UserInterface :: UserInterface(ControlPanel *controlPanel, Core *core, FeedTable

this->keys.all = 0xff;

// initialize the core so we start up correctly
core->setReverse(this->reverse);
core->setFeed(loadFeedTable());

setMessage(&STARTUP_MESSAGE_1);
}

Expand All @@ -75,15 +81,23 @@ const FEED_THREAD *UserInterface::loadFeedTable()
return this->feedTable->current();
}

LED_REG UserInterface::calculateLEDs(const FEED_THREAD *selectedFeed)
LED_REG UserInterface::calculateLEDs()
{
// get the LEDs for this feed
LED_REG leds = selectedFeed->leds;
LED_REG leds = feedTable->current()->leds;

// and add a few of our own
leds.bit.POWER = 1;
leds.bit.REVERSE = this->reverse;
leds.bit.FORWARD = ! this->reverse;
if( this->core->isPowerOn() )
{
// and add a few of our own
leds.bit.POWER = 1;
leds.bit.REVERSE = this->reverse;
leds.bit.FORWARD = ! this->reverse;
}
else
{
// power is off
leds.all = 0;
}

return leds;
}
Expand Down Expand Up @@ -114,45 +128,44 @@ void UserInterface :: overrideMessage( void )

void UserInterface :: loop( void )
{
const FEED_THREAD *newFeed = NULL;

// read the RPM up front so we can use it to make decisions
Uint16 currentRpm = core->getRPM();

// display an override message, if there is one
overrideMessage();

// just in case, initialize the first time through
if( feedTable == NULL ) {
newFeed = loadFeedTable();
}

// read keypresses from the control panel
keys = controlPanel->getKeys();

// respond to keypresses
if( currentRpm == 0 )
{
// these keys should only be sensitive when the machine is stopped
if( keys.bit.IN_MM )
{
this->metric = ! this->metric;
newFeed = loadFeedTable();
}
if( keys.bit.FEED_THREAD )
{
this->thread = ! this->thread;
newFeed = loadFeedTable();
if( keys.bit.POWER ) {
this->core->setPowerOn(!this->core->isPowerOn());
}
if( keys.bit.FWD_REV )
{
this->reverse = ! this->reverse;
// feed table hasn't changed, but we need to trigger an update
newFeed = loadFeedTable();
}
if( keys.bit.SET )
{
setMessage(&SETTINGS_MESSAGE_1);

// these should only work when the power is on
if( this->core->isPowerOn() ) {
if( keys.bit.IN_MM )
{
this->metric = ! this->metric;
core->setFeed(loadFeedTable());
}
if( keys.bit.FEED_THREAD )
{
this->thread = ! this->thread;
core->setFeed(loadFeedTable());
}
if( keys.bit.FWD_REV )
{
this->reverse = ! this->reverse;
core->setReverse(this->reverse);
}
if( keys.bit.SET )
{
setMessage(&SETTINGS_MESSAGE_1);
}
}
}

Expand All @@ -161,35 +174,32 @@ void UserInterface :: loop( void )
{
#endif // IGNORE_ALL_KEYS_WHEN_RUNNING

// these keys can be operated when the machine is running
if( keys.bit.UP )
{
newFeed = feedTable->next();
}
if( keys.bit.DOWN )
{
newFeed = feedTable->previous();
// these should only work when the power is on
if( this->core->isPowerOn() ) {
// these keys can be operated when the machine is running
if( keys.bit.UP )
{
core->setFeed(feedTable->next());
}
if( keys.bit.DOWN )
{
core->setFeed(feedTable->previous());
}
}

#ifdef IGNORE_ALL_KEYS_WHEN_RUNNING
}
#endif // IGNORE_ALL_KEYS_WHEN_RUNNING

// if we have changed the feed
if( newFeed != NULL ) {
// update the display
LED_REG leds = this->calculateLEDs(newFeed);
controlPanel->setLEDs(leds);
controlPanel->setValue(newFeed->display);
// update the control panel
controlPanel->setLEDs(calculateLEDs());
controlPanel->setValue(feedTable->current()->display);
controlPanel->setRPM(currentRpm);

// update the core
core->setFeed(newFeed);
core->setReverse(this->reverse);
if( ! core->isPowerOn() )
{
controlPanel->setValue(VALUE_BLANK);
}

// update the RPM display
controlPanel->setRPM(currentRpm);

// write data out to the display
controlPanel->refresh();
}
2 changes: 1 addition & 1 deletion els-f280049c/UserInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class UserInterface
Uint16 messageTime;

const FEED_THREAD *loadFeedTable();
LED_REG calculateLEDs(const FEED_THREAD *selectedFeed);
LED_REG calculateLEDs();
void setMessage(const MESSAGE *message);
void overrideMessage( void );

Expand Down

0 comments on commit 7a5f6fb

Please sign in to comment.