I built a simple coil winder to make guitar pickups (simple coil on a bobbin in which the core is made of rod magnets):
Basically I am happy with my little machine in every respect except for speed. I would like for it to go about 3x faster without using any gears - IT HAS TO BE DIRECT DRIVE.
When I wind a pickup by hand by just clamping the bobbin into a lathe, it takes just a few minutes. With my Arduino winder, I start it winding, turn off the lights, and let it run for 32mins up to > 1hr. I would like for the Arduino winder to hit about 1000 RPM.
I am using the Easy Driver board to drive this stepper to get the rotation: Stepper motor NEMA 17 76oz/in 11V | eBay
I am powering the Arduino and the Easy Driver with a smallish 9v DC transformer (at 12v the Easy Driver goes directly from too hot to stalling). Also the servo is powered from the Easy Driver 5v output pin.
I am open to making my code better, trying a more robust driver board, buying a PSU, etc. I'm probably not willing to design my own board or anything like that - I'm looking for a quick fix, not another whole project. I just don't know what I need to do to make the same basic project MUCH FASTER.
Here is my code in case there are any opportunities for more speed there.
#include <Servo.h>
//User Variables - Use these to customize the coil.
int turnsCount = 7800; //how many turns
float bobbinHeight = .436; //height in inches
int turnsPerLayer = 120; // how may turns per traverse?
#define DIR_PIN 8
#define STEP_PIN 9
Servo myservo;
// Variables and Constants - Do Not Edit ************************
// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
// Variables will change:
int ledState = HIGH; // the current state of the output pin
int buttonState; // the current reading from the input pin
int lastButtonState = LOW; // the previous reading from the input pin
// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 50; // the debounce time; increase if the output flickers
int stage = 0; //enter 2 to use set variables
int pos = 3; // variable to store the servo position
float stepSpeed=.02; //stepper speed to feed into rotateDeg loop
//pulley diameter is 0.378 inches, therefore its total max travel is 0.593761, so each clicks moves it about 0.00329867
const float totalTravel = 0.593761; //inches that each degree of servo rotation moves the traverse belt
float moveBy = bobbinHeight/turnsPerLayer;
float currDist = 0.000000; // running tally of distance from starting point
int servoDir=1; // direction of servo, i.e. traverse movement. 1 for up and -1 for down
//Setup**********************************************************
void setup() {
Serial.begin(9600); // open the serial port at 9600 bps:
pinMode(DIR_PIN, OUTPUT);
pinMode(STEP_PIN, OUTPUT);
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(buttonPin, HIGH);
Serial.begin(9600); // open the serial port at 9600 bps:
myservo.attach(6); // attaches the servo on pin 6 to the servo object LD
myservo.write(3); // set up servo in position at edge of bobbin
}
//Main Loop******************************************************
void loop(){
// read the state of the switch into a local variable:
int reading = digitalRead(buttonPin);
// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonState = reading;
if(reading == LOW){ //this is definitely a debounced button press
stage += 1;
delay(1000);
}
}
//Stage 1 - button has been pressed, machine is winding the pickup
if (stage == 1){
if (stepSpeed < 1){ //still ramping up speed
stepSpeed += .02;
}
if (turnsCount>0){ //still winding - stepper only turns inside this loop
//rotate a specific number of degrees
rotateDeg(360, stepSpeed);
turnsCount-=1;
//servo code ****************************************************************
currDist=servoDir*moveBy+currDist;
if(currDist>=bobbinHeight){ //reached limit, start moving back toward 0
servoDir=-1;
currDist=bobbinHeight;
}
if(currDist<=0){ //at 0, start moving up again
servoDir=1;
currDist=0;
}
pos=(currDist/totalTravel*180)+3; //write new servo rotation based on calculations
myservo.write(pos);
Serial.print("remaining: ");
Serial.print(turnsCount); //print the current stage
Serial.print(" \n");
}
}
}
// turns the stepper one full revolution *************************
void rotateDeg(float deg, float speed){
//rotate a specific number of degrees (negitive for reverse movement)
//speed is any number from .01 -> 1 with 1 being fastest - Slower is stronger
int dir = (deg > 0)? HIGH:LOW;
digitalWrite(DIR_PIN,dir);
int steps = abs(deg)*(1/0.225);
float usDelay = (1/speed) * 70;
for(int i=0; i < steps; i++){
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(usDelay);
digitalWrite(STEP_PIN, LOW);
delayMicroseconds(usDelay);
}
}