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

The circuit is presented with both drivers (DRV8825 (purple) and EasyDriver (red)). The working principle is the same of both drivers: there is a step and direction pin on both circuits which are controlled by the microcontroller (MCU). Except the E…

The circuit is presented with both drivers (DRV8825 (purple) and EasyDriver (red)). The working principle is the same of both drivers: there is a step and direction pin on both circuits which are controlled by the microcontroller (MCU). Except the EasyDriver, all the other peripherals are connected to the +5 V rail of the MCU. The 16x2 LCD uses i2C protocol to communicate with the MCU (SDA: PB7/[A5], SCL: PB6/[A4] for STM32 [Arduino]). The rotary encoders use 3 pins each (DT, CLK, SW) to connect to the microcontroller. If you use Arduino Uno or Nano, make sure that you connect them to interrupt-capable pins (Pin 2 and 3)! The power source was 20 V 2 A in my case when both drivers were connected to the power supply.



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();
   }
  }  
}

Previous
Previous

ADS1256 - Improved code for faster acquisition

Next
Next

Fast serial communication with Arduino