Unipolar, Optoisolated Stepper Driver
Unipolar, Optoisolated Stepper Driver

Download: PCB (svg) (300K)
Arduino Code (3K)

Schematic of the unipolar optoisolated stepper driver

Assembled PCB of the unipolar optoisolated stepper driver

Pictured: An optoisolated (the computer is separated from the motor’s power supply by an air gap. The control signals are transmitted over a LED / photodiode pair) unipolar stepper driver.

There is one caveat: if the power source is high-current, the “thicker” traces will need to have a layer of solder tinned to them:
Udnerside of the PCB of the unipolar optoisolated stepper driver, showing the tinned traces for high current

I’ve also written a test suite for the Arduino, enjoy:

int LED = 13;
int A_1 = 8;
int A_2 = 9;
int B_1 = 10;
int B_2 = 11;
int DELAY_MS = 200;

void single_step(int cycles)
{
  // Apply power to one winding at a time.
  //
  // 1a 1000
  // 1b 0010
  // 2a 0100
  // 2b 0001

  for (int i=0; i < cycles; i++)
  {
    digitalWrite(A_1, HIGH);
    delay(DELAY_MS);
    digitalWrite(A_1, LOW);
    digitalWrite(A_2, HIGH);
    delay(DELAY_MS);
    digitalWrite(A_2, LOW);
    digitalWrite(B_1, HIGH);
    delay(DELAY_MS);
    digitalWrite(B_1, LOW);
    digitalWrite(B_2, HIGH);
    delay(DELAY_MS);
    digitalWrite(B_2, LOW);
  }
}

void double_step(int cycles)
{
  // Apply power to two windings at a time.
  // ~= 1.4x torque over single-stepping.
  //
  // 1a 1100
  // 1b 0011
  // 2a 0110
  // 2b 1001
  digitalWrite(B_2, HIGH);
  for (int i=0; i < cycles; i++)
  {
    digitalWrite(A_1, HIGH);
    delay(DELAY_MS);
    digitalWrite(B_2, LOW);
    digitalWrite(A_2, HIGH);
    delay(DELAY_MS);
    digitalWrite(A_1, LOW);
    digitalWrite(B_1, HIGH);
    delay(DELAY_MS);
    digitalWrite(A_2, LOW);
    digitalWrite(B_2, HIGH);
    delay(DELAY_MS);
    digitalWrite(B_1, LOW);
  }
  digitalWrite(B_2, LOW);
}

void half_step(int cycles)
{
  // Combine single and double stepping to take half-steps.
  // ~= 2x angular resolution over single or double stepping.
  //
  // 1a 11000001
  // 1b 00011100
  // 2a 01110000
  // 2b 00000111
  digitalWrite(A_1, HIGH);
  for (int i=0; i < cycles; i++)
  {
    delay(DELAY_MS);
    digitalWrite(A_2, HIGH);
    delay(DELAY_MS);
    digitalWrite(A_1, LOW);
    delay(DELAY_MS);
    digitalWrite(B_1, HIGH);
    delay(DELAY_MS);
    digitalWrite(A_2, LOW);
    delay(DELAY_MS);
    digitalWrite(B_2, HIGH);
    delay(DELAY_MS);
    digitalWrite(B_1, LOW);
    delay(DELAY_MS);
    digitalWrite(A_1, HIGH);
    delay(DELAY_MS);
    digitalWrite(B_2, LOW);
  }
  digitalWrite(A_1, LOW);
}

void blink_led(int times)
{
  for (int i=0; i < times; i++)
  {
    digitalWrite(LED, HIGH);
    delay(DELAY_MS);
    digitalWrite(LED, LOW);
    delay(DELAY_MS);
  }
}

void setup()
{
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
  pinMode(A_1, OUTPUT);
  digitalWrite(A_1, LOW);
  pinMode(A_2, OUTPUT);
  digitalWrite(A_2, LOW);
  pinMode(B_1, OUTPUT);
  digitalWrite(B_1, LOW);
  pinMode(B_2, OUTPUT);
  digitalWrite(B_2, LOW);
}

void loop()
{
  blink_led(1);
  single_step(6);
  blink_led(2);
  double_step(6);
  blink_led(3);
  half_step(6 / 2);
}

Leave a Comment?

Send me an email, then I'll place our discussion on this page (with your permission).


Return | About/Contact