โปรเจกต์ Lathe - Electronic Lead Screw
ระบบ Lead Screw ที่ขับเคลื่อนด้วย Servo โดยใช้ Arduino เพื่อคำนวณความเร็ว Spindle และ Lead Screw ที่เหมาะสมสำหรับการตัดเกลียว English และ Metric ด้วย VFD
ระบบ Lead Screw ที่ขับเคลื่อนด้วย Servo โดยใช้ Arduino เพื่อคำนวณความเร็ว Spindle และ Lead Screw ที่เหมาะสมสำหรับการตัดเกลียว English และ Metric ด้วย VFD
Project Supporter Team
โพสต์โดย
โปรเจกต์นี้เริ่มต้นจากความต้องการง่ายๆ คือ ผมต้องการความสามารถในการตัดเกลียวเมตริกบนเครื่องกลึง Atlas Craftsman ของผม และต้องการลดความยุ่งยากในการเปลี่ยนเฟืองสำหรับชุดขับ Lead Screw ด้วยตัวเอง หลังจากค้นหาข้อมูลบนเว็บแล้ว ผมไม่พบข้อมูลที่ดีพอเกี่ยวกับการสร้างหรือการซื้อ Electronic Lead Screw ดังนั้นผมจึงตัดสินใจเริ่มลงมือทำเอง นอกจากนี้ ผมยังตัดสินใจเพิ่ม VFD เพื่อควบคุมความเร็ว Spindle ของมอเตอร์ด้วย
เนื่องจากระบบขับเคลื่อน Spindle ที่ใช้ VFD เป็นระบบที่แยกจาก Electronic Lead Screw ผมจึงแบ่งมันออกเป็นสองส่วน คือ ระบบขับเคลื่อน Spindle และระบบขับเคลื่อน Lead Screw
ระบบขับเคลื่อน Spindle นั้นค่อนข้างตรงไปตรงมา โดยเปลี่ยนมอเตอร์ขับเคลื่อนแบบ Single-phase เป็นแบบ Three-phase และขับเคลื่อนด้วย VFD
ระบบขับเคลื่อน Lead Screw ใช้ Arduino เพื่อสร้างระบบที่เหมือนกับกระปุกเกียร์อิเล็กทรอนิกส์ Arduino จะอ่านค่าความเร็ว Spindle และปรับค่า RPM ของ Servo ให้สอดคล้องกับอัตราส่วนที่ถูกต้องตามที่ผู้ใช้ป้อนข้อมูลเพื่อสร้างเกลียวแบบเมตริกหรือเกลียวแบบนิ้ว (English threads) มีการใช้หน้าจอ LCD ร่วมกับปุ่มกดแบบ Momentary สองปุ่มสำหรับ User Interface สิ่งนี้ช่วยให้ผู้ใช้สามารถเลือกได้ว่าจะใช้หน่วยเมตริกหรือหน่วยนิ้ว รวมถึงเลือกขนาดเกลียว เมื่อเลือกเกลียวหรือระยะ Pitch ที่ต้องการได้แล้ว จะมีการใช้สวิตช์แบบ 3 ทาง (3-way switch) เพื่อหมุนมอเตอร์ในทิศทาง CW หรือ CCW เมื่อมอเตอร์ทำงาน หน้าจอ LCD จะไม่มีการอัปเดต และคุณจะไม่สามารถเปลี่ยนระยะ Pitch ของเกลียวได้จนกว่ามอเตอร์จะหยุดทำงาน
ผมตัดสินใจซื้อชุดมอเตอร์ 1/3hp 3ph และ VFD จาก eBay ขนาดโครงมอเตอร์ (Frame size) ใกล้เคียงกับมอเตอร์ 1/2hp 1ph เดิม ดังนั้นจึงสามารถติดตั้งแทนที่ได้ทันที
สำหรับระบบขับเคลื่อน ผมยังได้ซื้อตัวกรอง EMI แบบ Inline มาด้วย (VFD ของ TECO รุ่นนี้ปล่อยสัญญาณรบกวนออกมามากและไปรบกวนการทำงานของ Arduino) ตัวกรอง EMI ถูกติดตั้งไว้ที่ฝั่ง Power Supply ที่จ่ายไฟเข้า VFD
มีการใช้วงแหวน Ferrite เพื่อลดสัญญาณรบกวนที่เดินทางจาก VFD ไปยังมอเตอร์
มีการใช้สวิตช์เปิด/ปิดเพื่อให้พลังงานกับระบบขับเคลื่อน Spindle และ Lead Screw โดยติดตั้งไว้ที่บานประตูแผงควบคุม
VFD สามารถใช้งานร่วมกับ Potentiometer ภายนอกได้เช่นกัน ซึ่งจำเป็นสำหรับการควบคุมความเร็วมอเตอร์ขณะใช้งานเครื่องกลึง Potentiometer ขนาด 10k ทำงานได้ดี และมันถูกติดตั้งไว้บนกล่องเก็บ Arduino
อุปกรณ์เหล่านี้ถูกประกอบเข้าด้วยกันในกล่อง NEMA 4 และเดินสายเชื่อมต่อกัน (ผมเป็นสายเครื่องกล อย่าไปใส่ใจกับสายไฟที่ดูยุ่งเหยิงนะครับ)
มีการใช้ Power Supply ขนาด 24v 20a เพื่อจ่ายไฟให้กับ Stepper Motor (คุณอาจใช้ Power Supply ที่มีแอมแปร์น้อยกว่านี้ได้) Power Supply ถูกติดตั้งไว้ในกล่อง VFD
ผมตัดสินใจเลือกใช้ Stepper Motor ขนาด NEMA 23 ที่มีแรงบิด 3Nm ถ้าผมย้อนกลับไปทำใหม่ได้ ผมจะขยับขึ้นไปใช้ NEMA 24 เพราะมอเตอร์ตัวนี้มีกำลังเพียงพอแค่สำหรับการตัดเกลียวโดยไม่ค้าง (Stalling) เท่านั้น
มีการใช้ขายึดเหล็กเพื่อติดตั้งมอเตอร์บนโต๊ะงานของเครื่องกลึง
ใช้ Timing Pulley ขนาด 14t 3/8in L สำหรับเฟืองขับ Pinion บน Stepper
สำหรับ Timing Pulley บน Lead Screw ผมใช้ Timing Pulley ขนาด 22t 3/8in L พร้อมอะแดปเตอร์ Taper Lock ตัวอะแดปเตอร์มีขนาดรูเจาะ 0.75 นิ้ว พร้อมร่องลิ่ม (Keyway) แบบเดียวกับที่ตรงกับ Lead Screw เดิม ไม่จำเป็นต้องดัดแปลงเครื่องกลึงแต่อย่างใด
ด้านล่างคือภาพของ Stepper Motor พร้อมระบบสายพาน Synchronous ผมตัดส่วนล่างของฝาครอบนิรภัยออกเพื่อให้ครอบทับ Stepper Motor ได้พอดีและปิดฝาได้

ผมใช้ Microstepper Driver เพื่อเป็นอินเทอร์เฟซระหว่าง Arduino และ Stepper Motor ตัว Driver ใช้ไฟจาก Power Supply 24v เพื่อสร้างพัลส์ให้กับ Stepper ตามสัญญาณจาก Arduino ผมติดตั้งตัวนี้ไว้ที่ด้านล่างของโต๊ะงานใกล้กับ Stepper โดยไม่ได้ใส่ไว้ในแผง VFD เนื่องจากมีสัญญาณ EMI มากเกินไป
ในการวัด RPM ของ Spindle ผมใช้ Sensor Hall Effect แบบเหนี่ยวนำ (Inductive Hall Effect Sensor) รุ่นนี้ เนื่องจากมันมาพร้อมกับจอ LCD ของตัวเอง ผมจึงสามารถใช้เพื่อสอบเทียบการคำนวณความเร็วของ Arduino ได้ ผมติดแม่เหล็กไว้ที่ Spindle ตามที่แสดงในภาพด้านล่าง

ผมใช้เคสพลาสติกขนาดเล็กสำหรับใส่หน้าจอ LCD, Arduino, Breadboard และสวิตช์ต่างๆ
เคสพลาสติก
Arduino
LCD
ปุ่มกด (Push buttons)
สวิตช์ 3 ทาง (3-way switch)

โปรแกรมมีฟังก์ชันการทำงานอยู่ไม่กี่ส่วน โดยมีการใช้ไลบรารี LiquidCrystal_I2C และ AccelStepper หน้าจอถูกตั้งค่าโดยใช้อาร์เรย์ (Array) เพื่อให้สามารถปรับขยายได้ มีการใช้ตัวแปร X เพื่อระบุหน่วย Metric เทียบกับ English และตัวแปร y จะพิมพ์แต่ละฟิลด์ข้อมูลลงบนหน้าจอ
const int x = 2;
int currentX = 0;
String screens[x][5] = {{"TPI","Dir","LatheRPM ","ServoRPM","tpi/mm"}, {"Pitch","Dir","LatheRPM","ServoRPM","tpi/mm"}};
ลูปสำหรับตั้งค่าแฟลกของปุ่ม (Set button flags loop) ใช้ For loop เพื่ออ่านสถานะของปุ่มกดและส่งสัญญาณหากสถานะมีการเปลี่ยนแปลง
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;
}
}
Resolve button flags จะทริกเกอร์การทำงานของปุ่มกดหากปุ่มมีการเปลี่ยนสถานะ
void resolveButtonFlags()
{
for(int i = 0; i < n; i++)
{
if(buttonFlags[i] == HIGH)
{
buttonAction(i);
buttonFlags[i] = LOW;
printScreen();
}
}
}
ลูปการทำงานของปุ่ม (Button action loop) จะกำหนดว่าจะต้องทำอะไรเมื่อมีการกดปุ่มบางปุ่มในขณะที่หน้าจอบางหน้าจอกำลังแสดงผลอยู่ เช่น เมื่อคุณอยู่ในหน้าจอ Metric และคุณกดปุ่ม A ค่า Pitch จะเปลี่ยนไป แต่ถ้าคุณอยู่ในโหมด English ค่า TPI จะเปลี่ยนแทน
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++;
}
}
ลูป Sensor ความเร็ว (Speed sensor loop) ใช้การ Debounce เพื่อทริกเกอร์ลูปคำนวณ RPM ของ Spindle และลูป RPM ของ Stepper โดย RPM ของ Stepper จะเปลี่ยนเพียงครั้งเดียวต่อการหมุนหนึ่งรอบของ Spindle และจะคำนวณเป็นหน่วย English หรือ Metric ตามหน้าจอที่คุณเลือกอยู่
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();
}
}
}
}
ลูปส่งข้อมูล (Send data loop) จะทำงานในขณะที่ Stepper ไม่ได้เดินเครื่อง และใช้สำหรับส่งข้อมูลไปยังหน้าจอ LCD ในขณะที่ Stepper กำลังทำงาน ลูปนี้จะไม่ทำงานเนื่องจากจะทำให้ตัวประมวลผลของ Arduino ทำงานช้าลง
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;
}
}
การคำนวณความเร็ว Stepper อ้างอิงจากจำนวนเกลียวต่อนิ้วของ Lead Screw (ในกรณีนี้คือ 8TPI), อัตราทดเกียร์ของสายพาน Synchronous (ในกรณีนี้คือ 1.529), ค่า Micro steps (ในกรณีนี้คือ 400) และค่า RPM
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];
}
นี่คือ Loop หลัก (Main loop) เมื่อคุณสั่งให้ Stepper ทำงาน จะมีเพียงลูป Sensor ความเร็วเท่านั้นที่ทำงานร่วมกับฟังก์ชันไลบรารีสำหรับตั้งความเร็ว Stepper และคำสั่ง if เพื่อหยุดมอเตอร์
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;
}
}
}
}
*อัปเดต*
ผมได้เพิ่มคำสั่ง if เพื่อให้ในขณะที่โปรแกรมอยู่ในโหมดการตัด/การทำเกลียว หากคุณกดปุ่ม Momentary สีน้ำเงินค้างไว้ Stepper จะทำงานในทิศทางย้อนกลับ (Reverse) ในโหมดเคลื่อนที่เร็ว (Rapid mode) เพื่อการตัดวัสดุอย่างรวดเร็ว
if(digitalRead(buttonPin[1]) == HIGH)
{
stepper.setSpeed(1500);
stepper.run();
}
โดยรวมแล้วระบบทำงานได้ดี หากคุณกำลังตัดเกลียว อย่าเพิ่งหยุด Servo Motor เพราะจะทำให้ Spindle และ Lead Screw หลุดจังหวะกัน และคุณจะไม่สามารถกลึงซ้ำตามแนวเกลียวเดิมได้ หากผมมีเวลามากกว่านี้ ผมจะติดตั้ง Encoder บน Stepper Motor เพื่อสร้างระบบควบคุมแบบวงปิด (Closed Control Loop) เพื่อให้ Spindle และ Lead Screw สามารถซิงโครไนซ์ตามตำแหน่ง (Position) ได้ด้วย แต่แบบนี้ก็ถือว่าทำงานได้ดีและผมสามารถตัดเกลียวเมตริกด้วยการตั้งค่านี้ได้ตราบใดที่ Servo ยังคงทำงานอยู่ (เพียงแค่ปลดชุดแคร่ Carriage ออกตามปกติ) ด้านล่างนี้คือรายการอุปกรณ์และคำอธิบายเบื้องต้นของแต่ละรายการสำหรับสร้างโปรเจกต์นี้พร้อมกับ Schematics
แผนผังการเดินสายไฟและ Source Code ถูกแนบมาด้วย คุณควรจะสามารถนำชิ้นส่วนเหล่านี้มาประกอบเข้าด้วยกัน อัปโหลด Code และเริ่มกลึงงานได้เลย
ขอบคุณที่ติดตามอ่านครับ!
Nick
email: nsr5058@gmail.com
สนับสนุนเพื่อรับ Source Code หรือแอปพลิเคชันสำหรับโปรเจกต์นี้
ประเมิน Project
เอาฟอร์มยาวออกจากท้ายหน้า Project แล้ว เหลือเป็นปุ่มให้กดไปกรอกหน้าเดียว ตัวใหญ่ เว้นบรรทัดเยอะ อ่านง่ายกว่า
รีวิวจากคนใช้งานจริง
ถ้าเคยสั่งงาน เคยอ่านหน้านี้แล้วได้ประโยชน์ หรือมีข้อเสนอแนะ ฝากรีวิวไว้ได้เลย
ยังไม่มีรีวิวบนหน้านี้ ถ้าเคยใช้งานหรือมีข้อเสนอแนะ เขียนเป็นคนแรกได้เลย