Salvaging stepper motors from floppy disk drives
In this video I show you how I removed some stepper motors from some old NEC floppy disk drives. These stepper motors are tiny and sensitive, so one has to be careful with the choice of the stepper motor driver. I show a bad and a good example just to demonstrate why it is crucial to match it with an appropriate driver. Usually, the problem is that the driver delivery too much power for these tiny motors and they simply burn down. During my test, I was able to heat up one of the motors above 100°C with the DRV8825 driver, even at its lowest current setting. On the other hand, when I used the EasyDriver circuit, I was able to hold the motor in my hand and operate it. The max temperature I registered was around 40°C only, which is quite OK in my opinion. Conclusion: use the EasyDriver with the lowest power setting for this type of stepper motors.
Wiring schematics
Arduino/STM32 source code
//AccelStepper #include <AccelStepper.h> AccelStepper stepper1(1, PB3, PB4);// pulses/step PB4; Direction PB3 (CCW) AccelStepper stepper2(1, PB8, PB9);// pulses/step PB9; Direction PB8 (CCW) //16x2 LCD #include <LiquidCrystal_I2C.h> //SDA = PB7, SCL = PB6 (STM32) LiquidCrystal_I2C lcd(0x27, 16, 2); //Defining pins const int RotaryCLK1 = PB10; //CLK pin on the rotary encoder const int RotaryDT1 = PB11; //DT pin on the rotary encoder const int RotarySW1 = PB1; //SW pin on the rotary encoder (Button function) const int RotaryCLK2 = PB12; //CLK pin on the rotary encoder const int RotaryDT2 = PB13; //DT pin on the rotary encoder const int RotarySW2 = PB14; //SW pin on the rotary encoder (Button function) //Defining variables int ButtonCounter1 = 0; //counts the button clicks int RotateCounter1 = 0; //counts the encoder clicks // int ButtonCounter2 = 0; int RotateCounter2 = 0; //Statuses //encoder 1 int CLKNow1; int CLKPrevious1; int DTNow1; int DTPrevious1; // encoder 2 int CLKNow2; int CLKPrevious2; int DTNow2; int DTPrevious2; //Timing-related variables float TimeNow, previousInterrupt1, previousInterrupt2; void setup() { //------------------------------------------------------ lcd.begin(); // initialize the lcd lcd.backlight(); //------------------------------------------------------ lcd.setCursor(0,0); //Defining positon to write from first row,first column . lcd.print("Rotary encoder"); lcd.setCursor(0,1); lcd.print("Stepper stepping"); //You can write 16 Characters per line . delay(5000); //wait 1 sec //------------------------------------------------------ //encoder 1 pinMode(PB1, INPUT_PULLUP); //SW pinMode(PB10, INPUT_PULLUP); //DT pinMode(PB11, INPUT_PULLUP); //CLK //encoder 2 pinMode(PB12, INPUT_PULLUP); //SW pinMode(PB13, INPUT_PULLUP); //CLK pinMode(PB14, INPUT_PULLUP); //DT //Store states CLKPrevious1 = digitalRead(RotaryCLK1); DTPrevious1 = digitalRead(RotaryDT1); CLKPrevious2 = digitalRead(RotaryCLK2); DTPrevious2 = digitalRead(RotaryDT2); attachInterrupt(digitalPinToInterrupt(RotaryCLK1), rotate1, CHANGE); attachInterrupt(digitalPinToInterrupt(RotaryCLK2), rotate2, CHANGE); stepper1.setMaxSpeed(1000); //SPEED = Steps / second stepper1.setAcceleration(5000); //ACCELERATION = Steps /(second)^2 stepper2.setMaxSpeed(1000); stepper2.setAcceleration(5000); TimeNow = millis(); //Start timer printLCD(); //print LCD } void loop() { if(millis() - TimeNow > 100) { printLCD(); TimeNow = millis(); } // ButtonPressed1(); ButtonPressed2(); // RunTheMotor1(); RunTheMotor2(); } void printLCD() { //Encoder 1 - related lcd.setCursor(0,0); // Defining positon to write from first row, first column . lcd.print("R1: "); //Rotary encoder 1 lcd.setCursor(4,0); //cursor after the space in the previous string lcd.print(" "); //erase four blocks lcd.setCursor(4,0); //cursor goes back lcd.print(RotateCounter1); //print variable // lcd.setCursor(8,0); lcd.print(" B1: "); lcd.setCursor(13,0); lcd.print(" "); lcd.setCursor(13,0); lcd.print(ButtonCounter1); //--------------------------- //Encoder 2 - related lcd.setCursor(0,1); lcd.print("R2: "); lcd.setCursor(4,1); lcd.print(" "); lcd.setCursor(4,1); lcd.print(RotateCounter2); // lcd.setCursor(8,1); lcd.print(" B2: "); lcd.setCursor(13,1); lcd.print(" "); lcd.setCursor(13,1); lcd.print(ButtonCounter2); } void RunTheMotor1() //function for the motor { stepper1.moveTo(RotateCounter1); while(stepper1.distanceToGo() != 0) { stepper1.runToNewPosition(RotateCounter1); } } void RunTheMotor2() //function for the motor { stepper2.moveTo(RotateCounter2); while(stepper2.distanceToGo() != 0) { stepper2.runToNewPosition(RotateCounter2); } } void rotate1() { CLKNow1 = digitalRead(RotaryCLK1); //Read the state of the CLK pin if (CLKNow1 != CLKPrevious1 && CLKNow1 == 1) { if (digitalRead(RotaryDT1) != CLKNow1) { RotateCounter1++; } else { RotateCounter1--; } } CLKPrevious1 = CLKNow1; // Store last CLK state } void rotate2() { CLKNow2 = digitalRead(RotaryCLK2); if (CLKNow2 != CLKPrevious2 && CLKNow2 == 1) { if (digitalRead(RotaryDT2) != CLKNow2) { RotateCounter2++; } else { RotateCounter2--; } } CLKPrevious2 = CLKNow2; // Store last CLK state } void ButtonPressed1() { if(digitalRead(PB1) == 0) //1 or 0, depends on your wiring also! { if(millis() - previousInterrupt1 > 300) //debounce, sort of. If another click comes within 300 ms, we don't care about it { ButtonCounter1++; //increase value previousInterrupt1 = millis(); } } } void ButtonPressed2() { if(digitalRead(PB14) == 0) //1 or 0, depends on your wiring also! { if(millis() - previousInterrupt2 > 300) //debounce, sort of. If another click comes within 300 ms, we don't care about it { ButtonCounter2++;//increase value previousInterrupt2 = millis(); } } }