An opportunity came to hande recently - an old PC was scrapped and it had a DVD drive in ti. I took the chance to totally disassemble it and discovered a lovely stepper motor with gearing and so forth to make it into a linear actuator.
The problem was, how to drive the beast. Firstly, it was obviously a stepper motor as it had > 2 leads coming from it. How was it wired up, though. Well, firstly I got a voltmeter and worked out that it was simply to 20 ohm coils. This means it was a dreaded bipolar stepper - harder to drive than unipolar.
I decided to have a go. I soldered on some power leads and hooked it up to my DFRobot L298 Motor shield. Then, I had to write the code.
It turns out that there is no ready source code for this handy. Basically, the motor has to be driven by a dual h-bridge arrangement working the coils using digital square waves that go between +5 and -5V through 0V. This can be seen roughly as sine waves. They waves need to be about 90 degress out of phase.
Basically, the DFRobot board allows you to control the speed and direction of each motor only. I built a function to set speeed and direction of each motor based on the steps 0->7 in the diagrams. Each step waas a function. I put these functions into an array of function pointers and simply called them in order to get movement. Stepping back throught the table gave reverse motion.
Here's the simple code:
int E1 = 6;
int M1 = 7;
int E2 = 5;
int M2 = 4;
#define DELAY 2
#define PWR 200
void
MotorsOff()
{
analogWrite(E1, 0); //PWM Speed Control
analogWrite(E2, 0); //PWM Speed Control
}
void
Step0()
{
// 0
digitalWrite(M1,HIGH);
analogWrite(E1, PWR); //PWM Speed Control
digitalWrite(M2, HIGH);
analogWrite(E2, 0); //PWM Speed Control
delay(DELAY);
}
void
Step1()
{
// 1
digitalWrite(M1,HIGH);
analogWrite(E1, PWR); //PWM Speed Control
digitalWrite(M2, HIGH);
analogWrite(E2, PWR); //PWM Speed Control
delay(DELAY);
}
void
Step2()
{
// 2
digitalWrite(M1,HIGH);
analogWrite(E1, 0); //PWM Speed Control
digitalWrite(M2, HIGH);
analogWrite(E2, PWR); //PWM Speed Control
delay(DELAY);
}
void
Step3()
{
// 3
digitalWrite(M1,LOW);
analogWrite(E1, PWR); //PWM Speed Control
digitalWrite(M2, HIGH);
analogWrite(E2, PWR); //PWM Speed Control
delay(DELAY);
}
void
Step4()
{
// 4
digitalWrite(M1,LOW);
analogWrite(E1, PWR); //PWM Speed Control
digitalWrite(M2, HIGH);
analogWrite(E2, 0); //PWM Speed Control
delay(DELAY);
}
void
Step5()
{
// 5
digitalWrite(M1,LOW);
analogWrite(E1, PWR); //PWM Speed Control
digitalWrite(M2, LOW);
analogWrite(E2, PWR); //PWM Speed Control
delay(DELAY);
}
void
Step6()
{
// 6
digitalWrite(M1,LOW);
analogWrite(E1, 0); //PWM Speed Control
digitalWrite(M2, LOW);
analogWrite(E2, PWR); //PWM Speed Control
delay(DELAY);
}
void
Step7()
{
// 7
digitalWrite(M1,HIGH);
analogWrite(E1, PWR); //PWM Speed Control
digitalWrite(M2, LOW);
analogWrite(E2, PWR); //PWM Speed Control
delay(DELAY);
}
#define NUM_STEPS 8
int *steps[NUM_STEPS] = {(int *)Step0,(int *)Step1,(int *)Step2,(int *)Step3,(int *)Step4,(int *)Step5,(int *)Step6,(int *)Step7};
void setup()
{
pinMode(M1, OUTPUT);
pinMode(M2, OUTPUT);
}
void loop()
{
int i;
void (*j)();
for (i = 0; i < 450; i++)
{
j = (void (*)())steps[i % NUM_STEPS];
(*j)();
}
MotorsOff();
delay(1000);
for (i = 450; i > 0; i--)
{
j = (void (*)())steps[i % NUM_STEPS];
(*j)();
}
}