Nick Romeo
Published © LGPL

Lathe - Electronic Lead Screw

A servo-driven lead screw using Arduino to calculate proper spindle and lead screw speeds for cutting English and metric threads with VFD.

IntermediateShowcase (no instructions)54,840
Lathe - Electronic Lead Screw

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1

Hand tools and fabrication machines

Crimp Tool, Heavy-Duty
Crimp Tool, Heavy-Duty
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires

Story

Read more

Schematics

Servo Controller Schematic

Spindle VFD Schematic

Code

LeadScrewV2

Arduino
With rapid mode
// included libraries
// liquid crystal l2c library and lcd function
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
#include <AccelStepper.h>
AccelStepper stepper(AccelStepper::DRIVER,10,9);
// Speed sensor variables
const int SensorPin = 2;        // the number of the IR sensor input pin
int sensorState;                // the current state from the input pin
int lastSensorState = LOW;      // the previous InputState from the input pin
long lastDebounceTime = 0.00;   // the last time the output pin was toggled
long debounceDelay = 1.00;      // the debounce time; increase if the output flickers
long time;
long endTime;
long startTime;
volatile float RPM = 0.00;
float stepperRPM = 0.00;
float lnTime = 0.00;
int lcdRPM = 0;
int lastRPM = 0;

//button variables
const int n = 2;
const int buttonPin[n] = {3,4};
int buttonState[n] = {LOW,LOW};
int lastButtonState[n]= {LOW,LOW};
bool buttonFlags[n] = {LOW, LOW};

//three way switch variables
const int leftPin = 6;
const int rightPin = 5;

//screen variables
const int x = 2;
int currentX = 0;
int currentY = 0;
String screens[x][5] = {{"TPI","Dir","LatheRPM ","ServoRPM","tpi/mm"}, {"Pitch","Dir","LatheRPM","ServoRPM","tpi/mm"}};

//user input variables
const int nTPI = 18;
const int nPitch = 11;
int tpi[nTPI] = {256, 128, 64, 56, 48, 40, 32, 24, 20, 18, 16, 14, 13, 12, 11, 10, 9, 8};
int currentTPI = 0;
float pitch[nPitch]={0.40, 0.45, 0.50, 0.70, 0.70, 0.80, 1.00, 1.25, 1.50, 2.00, 2.50};
int currentPitch = 0;
//String dir[2] = {"CW ","CCW"};
//String currentDir = "CW";

//internal timer to send data
unsigned long prevMillis = 0;
const long interval = 1000;

//lathe parameters
float servoRPM = 0.00;
//int direction = 1;

// =========================== setup ===========================
void setup()
{
  lcd.init();
  lcd.backlight();
  lcd.begin(20,4);
  Serial.begin(9600);
  for(int i=0; i < n; i++)
  {
    pinMode(buttonPin[i], INPUT);
    //Serial.print("Button: ");
    //Serial.println(buttonPin[i]);
  }
  pinMode(SensorPin, INPUT);
  endTime = 0;
  printScreen();
  // stepper stuff
  stepper.setEnablePin(8);
  stepper.disableOutputs();
  stepper.setMaxSpeed(2250);
  stepper.setAcceleration(300);
}
// =========================== main loop ===========================
void loop()
{
  setButtonFlags();
  resolveButtonFlags();
  sendData();
  speedSensor();
  if (digitalRead(leftPin) == HIGH)
  {
    //direction = 1;
    lcd.setCursor(4,1);
    lcd.print("CW ");
    lcd.setCursor(9,3);
    lcd.println(servoRPM);
    lcd.rightToLeft();
    lcd.print("   ");
    lcd.leftToRight();
    lcd.setCursor(9,2);
    lcd.println(lcdRPM);
    lcd.rightToLeft();
    lcd.print("   ");
    lcd.leftToRight();
    delay(5);
    stepper.enableOutputs();
    stepper.setSpeed(stepperRPM);  
    stepper.run();
    while(stepper.isRunning())
    {
      speedSensor();
      stepper.setSpeed(stepperRPM);  
      stepper.run();
      if(digitalRead(buttonPin[1]) == HIGH)
      {
        stepper.setSpeed(-1500);
        stepper.run();
      }
      if(digitalRead(leftPin)==LOW)
      {
        stepper.disableOutputs();
        lcd.setCursor(4,1);
        lcd.print("OFF");
        break;
      }
    }
  }
  else if (digitalRead(rightPin) == HIGH)
  {
    //direction = -1.00;
    lcd.setCursor(4,1);
    lcd.print("CCW");
    lcd.setCursor(9,3);
    lcd.println(servoRPM);
    lcd.rightToLeft();
    lcd.print("   ");
    lcd.leftToRight();
    lcd.setCursor(9,2);
    lcd.println(lcdRPM);
    lcd.rightToLeft();
    lcd.print("   ");
    lcd.leftToRight();
    delay(5);
    stepper.enableOutputs();
    stepper.setSpeed(-stepperRPM);  
    stepper.run();
    while(stepper.isRunning())
    {
      speedSensor();
      stepper.setSpeed(-1*stepperRPM);  
      stepper.run();
      if(digitalRead(buttonPin[1]) == HIGH)
      {
        stepper.setSpeed(1500);
        stepper.run();
      }
      if(digitalRead(rightPin)==LOW)
      {
        stepper.disableOutputs();
        lcd.setCursor(4,1);
        lcd.print("OFF");
        break;
      }
    }
  }
}
// =========================== set input flags ===========================
void setButtonFlags() 
{
  for(int i=0; i < n; i++)
  {
    buttonState[i] = digitalRead(buttonPin[i]);
    delay[1];
    if(buttonState[i] != lastButtonState[i])
    {
      if(buttonState[i] == HIGH)
      {
        //Serial.print("Button: ");
        //Serial.println(buttonPin[i]);
        buttonFlags[i] = HIGH;
      }
    }
    lastButtonState[i] = buttonState[i];
  }
}
// =========================== resolve button flags ===========================
void resolveButtonFlags() 
{
  for(int i = 0; i < n; i++)
  {
    if(buttonFlags[i] == HIGH)
    {
      buttonAction(i);
      buttonFlags[i] = LOW;
      printScreen();
    }
  }
}
// =========================== button action ===========================
void buttonAction(int button) 
{
  if (button == 0)
  {
    if (currentX == x-1)
    {
      currentX = 0;
    }
    else
    {
      currentX++;
    }
  }
  if (button == 1)
  {
    if (currentX == 0)
    {
      if(currentTPI == nTPI-1)
      {
        currentTPI = 0;
      }
      else
      {
        currentTPI++;
      }
    }
  else if (currentX == 1)
    {
      if(currentPitch == nPitch-1)
      {
        currentPitch = 0;
      }
      else
      {
        currentPitch++;
      }
    }
  }
}
// =========================== print screen ===========================
void printScreen() 
{
  lcd.clear();
  lcd.print(screens[currentX][0]);
  lcd.setCursor(0,1);
  lcd.print(screens[currentX][1]);
  lcd.setCursor(0,2);
  lcd.print(screens[currentX][2]);
  lcd.setCursor(0,3);
  lcd.print(screens[currentX][3]);
  lcd.setCursor(14,0);
  lcd.print(screens[currentX][4]);
  if(currentX == 0)
  {
    lcd.setCursor(4,0);    
    lcd.println(tpi[currentTPI]);
    lcd.rightToLeft();
    lcd.print("   ");
    lcd.leftToRight();
    lcd.setCursor(4,1);
    lcd.print("OFF");
  }
  else if (currentX == 1)
  {
    lcd.setCursor(6,0);
    lcd.println(pitch[currentPitch]);
    lcd.rightToLeft();
    lcd.print("   ");
    lcd.leftToRight();
    lcd.setCursor(4,1);
    lcd.print("OFF"); 
  }
}
// =========================== Speed Sensor loop ===========================
void speedSensor() 
{
  time = millis();
  int currentSensorState = digitalRead(SensorPin);

  if (currentSensorState != lastSensorState)
  {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay)
  {
    if (currentSensorState != sensorState)
    {
      sensorState = currentSensorState;
      if (sensorState == LOW) 
      {
        calculateRPM(); // Real RPM from sensor
        if (currentX == 0)
        {
          englishCalc();
        }
        else if (currentX == 1)
        {
          metricCalc();
        }
      }
    }
  }
  lastSensorState = currentSensorState;
  lcdRPM = RPM;
}

// =========================== RPM calculation ===========================
void calculateRPM()
{
  startTime = lastDebounceTime;
  lnTime = startTime - endTime;
  RPM = 60000.00 / (startTime - endTime);
  endTime = startTime;
}
// =========================== send speed data ===========================
void sendData()
{
  unsigned long currentMillis = millis();
  if(currentMillis - prevMillis >= interval)
  {
    prevMillis = currentMillis;
    lcd.setCursor(9,2);
    lcd.println(lcdRPM);
    lcd.rightToLeft();
    lcd.print("   ");
    lcd.leftToRight();
    lcd.setCursor(9,3);
    lcd.println(servoRPM);
    lcd.rightToLeft();
    lcd.print("   ");
    lcd.leftToRight();
    lcdRPM = 0;
  }
}
// =========================== english stepper speed ===========================
void metricCalc()
{
    stepperRPM = 1.529 * 0.315 * 400 * RPM * pitch[currentPitch] / 60.00;
    servoRPM = 0.482 * RPM * pitch[currentPitch];
}
// =========================== metric stepper speed ===========================
void englishCalc()
{
    stepperRPM = 1.529 * 8.00 * 400.00 * RPM / ( tpi[currentTPI] * 60.00 );
    servoRPM = 1.529 * 8.00 * RPM / tpi[currentTPI];
}

leadScrewV1

Arduino
// included libraries
// liquid crystal l2c library and lcd function
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
#include <AccelStepper.h>
AccelStepper stepper(AccelStepper::DRIVER,10,9);
// Speed sensor variables
const int SensorPin = 2;        // the number of the IR sensor input pin
int sensorState;                // the current state from the input pin
int lastSensorState = LOW;      // the previous InputState from the input pin
long lastDebounceTime = 0.00;   // the last time the output pin was toggled
long debounceDelay = 5.00;      // the debounce time; increase if the output flickers
long time;
long endTime;
long startTime;
volatile float RPM = 0.00;
float stepperRPM = 0.00;
float lnTime = 0.00;
int lcdRPM = 0;
int lastRPM = 0;

//button variables
const int n = 2;
const int buttonPin[n] = {3,4};
int buttonState[n] = {LOW,LOW};
int lastButtonState[n]= {LOW,LOW};
bool buttonFlags[n] = {LOW, LOW};

//three way switch variables
const int leftPin = 6;
const int rightPin = 5;

//screen variables
const int x = 2;
int currentX = 0;
int currentY = 0;
String screens[x][5] = {{"TPI","Dir","LatheRPM ","ServoRPM","tpi/mm"}, {"Pitch","Dir","LatheRPM","ServoRPM","tpi/mm"}};

//user input variables
const int nTPI = 18;
const int nPitch = 11;
int tpi[nTPI] = {256, 128, 64, 56, 48, 40, 32, 24, 20, 18, 16, 14, 13, 12, 11, 10, 9, 8};
int currentTPI = 0;
float pitch[nPitch]={0.40, 0.45, 0.50, 0.70, 0.70, 0.80, 1.00, 1.25, 1.50, 2.00, 2.50};
int currentPitch = 0;
//String dir[2] = {"CW ","CCW"};
//String currentDir = "CW";

//internal timer to send data
unsigned long prevMillis = 0;
const long interval = 1000;

//lathe parameters
float servoRPM = 0.00;
//int direction = 1;

// =========================== setup ========================================
void setup()
{
  lcd.init();
  lcd.backlight();
  lcd.begin(20,4);
  Serial.begin(9600);
  for(int i=0; i < n; i++)
  {
    pinMode(buttonPin[i], INPUT);
    //Serial.print("Button: ");
    //Serial.println(buttonPin[i]);
  }
  pinMode(SensorPin, INPUT);
  endTime = 0;
  printScreen();
  // stepper stuff
  stepper.setEnablePin(8);
  stepper.disableOutputs();
  stepper.setMaxSpeed(2502);
  stepper.setAcceleration(300);
}
// =========================== main loop ====================================
void loop()
{
  setButtonFlags();
  resolveButtonFlags();
  sendData();
  speedSensor();
  if (digitalRead(leftPin) == HIGH)
  {
    //direction = 1;
    lcd.setCursor(4,1);
    lcd.print("CW ");
    lcd.setCursor(9,3);
    lcd.println(servoRPM);
    lcd.rightToLeft();
    lcd.print("   ");
    lcd.leftToRight();
    lcd.setCursor(9,2);
    lcd.println(lcdRPM);
    lcd.rightToLeft();
    lcd.print("   ");
    lcd.leftToRight();
    delay(5);
    stepper.enableOutputs();
    stepper.setSpeed(stepperRPM);  
    stepper.run();
    while(stepper.isRunning())
    {
      speedSensor();
      stepper.setSpeed(stepperRPM);  
      stepper.run();
      if(digitalRead(leftPin)==LOW)
      {
        stepper.disableOutputs();
        lcd.setCursor(4,1);
        lcd.print("OFF");
        break;
      }
    }
  }
  else if (digitalRead(rightPin) == HIGH)
  {
    //direction = -1.00;
    lcd.setCursor(4,1);
    lcd.print("CCW");
    lcd.setCursor(9,3);
    lcd.println(servoRPM);
    lcd.rightToLeft();
    lcd.print("   ");
    lcd.leftToRight();
    lcd.setCursor(9,2);
    lcd.println(lcdRPM);
    lcd.rightToLeft();
    lcd.print("   ");
    lcd.leftToRight();
    delay(5);
    stepper.enableOutputs();
    stepper.setSpeed(-stepperRPM);  
    stepper.run();
    while(stepper.isRunning())
    {
      speedSensor();
      stepper.setSpeed(-1*stepperRPM);  
      stepper.run();
      if(digitalRead(rightPin)==LOW)
      {
        stepper.disableOutputs();
        lcd.setCursor(4,1);
        lcd.print("OFF");
        break;
      }
    }
  }
}
// =========================== set input flags ===========================
void setButtonFlags() 
{
  for(int i=0; i < n; i++)
  {
    buttonState[i] = digitalRead(buttonPin[i]);
    delay[1];
    if(buttonState[i] != lastButtonState[i])
    {
      if(buttonState[i] == HIGH)
      {
        //Serial.print("Button: ");
        //Serial.println(buttonPin[i]);
        buttonFlags[i] = HIGH;
      }
    }
    lastButtonState[i] = buttonState[i];
  }
}
// =========================== resolve button flags =========================
void resolveButtonFlags() 
{
  for(int i = 0; i < n; i++)
  {
    if(buttonFlags[i] == HIGH)
    {
      buttonAction(i);
      buttonFlags[i] = LOW;
      printScreen();
    }
  }
}
// =========================== button action ===============================
void buttonAction(int button) 
{
  if (button == 0)
  {
    if (currentX == x-1)
    {
      currentX = 0;
    }
    else
    {
      currentX++;
    }
  }
  if (button == 1)
  {
    if (currentX == 0)
    {
      if(currentTPI == nTPI-1)
      {
        currentTPI = 0;
      }
      else
      {
        currentTPI++;
      }
    }
  else if (currentX == 1)
    {
      if(currentPitch == nPitch-1)
      {
        currentPitch = 0;
      }
      else
      {
        currentPitch++;
      }
    }
  }
}
// =========================== print screen ===========================
void printScreen() 
{
  lcd.clear();
  lcd.print(screens[currentX][0]);
  lcd.setCursor(0,1);
  lcd.print(screens[currentX][1]);
  lcd.setCursor(0,2);
  lcd.print(screens[currentX][2]);
  lcd.setCursor(0,3);
  lcd.print(screens[currentX][3]);
  lcd.setCursor(14,0);
  lcd.print(screens[currentX][4]);
  if(currentX == 0)
  {
    lcd.setCursor(4,0);    
    lcd.println(tpi[currentTPI]);
    lcd.rightToLeft();
    lcd.print("   ");
    lcd.leftToRight();
    lcd.setCursor(4,1);
    lcd.print("OFF");
  }
  else if (currentX == 1)
  {
    lcd.setCursor(6,0);
    lcd.println(pitch[currentPitch]);
    lcd.rightToLeft();
    lcd.print("   ");
    lcd.leftToRight();
    lcd.setCursor(4,1);
    lcd.print("OFF"); 
  }
}
// =========================== Speed Sensor loop ===========================
void speedSensor() 
{
  time = millis();
  int currentSensorState = digitalRead(SensorPin);

  if (currentSensorState != lastSensorState)
  {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay)
  {
    if (currentSensorState != sensorState)
    {
      sensorState = currentSensorState;
      if (sensorState == LOW) 
      {
        calculateRPM(); // Real RPM from sensor
        if (currentX == 0)
        {
          englishCalc();
        }
        else if (currentX == 1)
        {
          metricCalc();
        }
      }
    }
  }
  lastSensorState = currentSensorState;
  lcdRPM = RPM;
}

// =========================== RPM calculation ===========================
void calculateRPM()
{
  startTime = lastDebounceTime;
  lnTime = startTime - endTime;
  RPM = 60000.00 / (startTime - endTime);
  endTime = startTime;
}
// =========================== send speed data ===========================
void sendData()
{
  unsigned long currentMillis = millis();
  if(currentMillis - prevMillis >= interval)
  {
    prevMillis = currentMillis;
    lcd.setCursor(9,2);
    lcd.println(lcdRPM);
    lcd.rightToLeft();
    lcd.print("   ");
    lcd.leftToRight();
    lcd.setCursor(9,3);
    lcd.println(servoRPM);
    lcd.rightToLeft();
    lcd.print("   ");
    lcd.leftToRight();
    lcdRPM = 0;
  }
}
// =========================== english stepper speed ========================
void metricCalc()
{
    stepperRPM = 1.529 * 0.315 * 400 * RPM * pitch[currentPitch] / 60.00;
    servoRPM = 0.482 * RPM * pitch[currentPitch];
}
// =========================== metric stepper speed =========================
void englishCalc()
{
    stepperRPM = 1.529 * 8.00 * 400.00 * RPM / ( tpi[currentTPI] * 60.00 );
    servoRPM = 1.529 * 8.00 * RPM / tpi[currentTPI];
}

Credits

Nick Romeo

Nick Romeo

0 projects • 32 followers
Mechanical Engineer

Comments