The motor that spins the metal disk inside your drive is a stepper motor. This means it has different coils inside as you can see from the four wire used to control it. If you make a motor rotating without applying any current it generates a voltage out of its connectors.
So when you rotate the metal disk with your fingers the motor generates a voltage from the four connectors. Because it is a stepper motor it generates a sinusoidal waveform on each connector and each wave differs from others by phase. Using this signal coming out from the motor you can understand if the motor is rotating and how fast is rotating, and using the phase difference you can know if it turns clockwise or anti-clockwise.
None that you have to use an hard disk that has 4 wires on the stepper motor.
2. Open the hard disk: Control board.First of all you need to remove the little control board.
Once you put apart the control board you need to remove all the screws to open the drive.
Note: Maybe there are some screws under the label, if you can't open it after you removed all the screws try to remove the adhesive label.
Now your hard disk is opened and what remains to do is to remove all the mechanics that move the reading/writing head.
Where there was the control board now you can see the stepper motor wires. Solder four wires to each pin and then connect 3 wires to Analog input 0, 1, 2 and the other wire to ground.
The code is based on two main functions: interpolate and readEncoder
. The function readEncoder
reads the output voltage of each pin of the stepper motor and returns the velocity of the rotation. After the stepper output is read by the Arduino the value returned is used by the interpolate function that increment or decrement the variable "actual
".
The loop function is very minimal, it only refreshes the "actual
" variable by calling the interpolate function and then prints it to the serial monitor.
/**
HD Encoder
Created by Cristian Maglie
**/
int actual = -1;
int encActual = -1;
void setup()
{
Serial.begin(9600);
}
int readEncoder() {
int p1 = analogRead(1);
int p2 = analogRead(2);
int p3 = analogRead(3);
if (p1+p2+p3==0)
return -1;
int l = p1+p2+p3;
int x = (p2-p3)*86;
int y = p1*100 - (p2+p3)*50;
int p=-1;
if (y>0) {
if (abs(x) < y*57/100)
p=0;
else
p=(x<0) ? 5 : 1;
}
else {
if (abs(x) < -y*57/100)
p=3;
else
p=(x<0) ? 4 : 2;
}
return p;
}
boolean interpolate() {
int delta[11] = {
-1, -2, 0, +2, +1, 0, -1, -2, 0, +2, +1
};
int v = readEncoder();
if (v==-1)
return false;
if (actual==-1) {
actual = 0;
encActual = v;
return true;
}
int d = delta[v-encActual+5];
actual += d;
encActual = v;
return true;
}
void loop()
{
if (interpolate())
Serial.println(actual);
delay(20);
}
Comments
Please log in or sign up to comment.