TB6600 stepper motor controller.
Fig. 1 TB6600 stepper motor controller.

Connection-Operation TB6600 Stepper Controller with PC Parallel Port

by Lewis Loflin

The TB6600 is a cheap stepper motor controller available in Ebay for about $10. It is single axis and operates bipolar stepper motors from 9-volts to about 40-volts at about 4 amps.

I did two videos and a webpage on using the TB6600 with an Arduino microcontroller. Here I will use this with a PC parallel or printer port.

See the links below for the earlier videos and Arduino.

Using the TB6600 with Arduino:

The goals are as follows:

1) a deeper look at the wiring and connections of the TB6600;

2) demonstrate the use a the parallel port a true 8-bit hardware port;

3) demonstrate the bit manipulations using bitwise operators under C.

Fig. 1 above illustrates the TB6600. It has three control connections (enable, count, direction), four connections for a bipolar stepper motor, and six setup micro switches.

Three of the setup switches select the current limit. The other setup micro-stepping. These will be explained next three slides.

TB6600 stepper motor controller connections, mico-step settings.
Fig. 2 TB6600 stepper motor controller micro-stepping switches.

Micro-Stepping Setup, Common Ground Connections

Let's look at Fig. 2. Note the three control connections for micro-stepping. S1, S2, and S3 are step multipliers for 360 degrees.

For example my motor in the video was 7.5 degrees per step or 48 steps for 360 degrees. A 1.8 degree per step motor requires 200 steps for 360 degrees.

Setting the switches divides the step angel, not the number of steps. Using 4 as an example, dividing 7.5 degrees by 4 = 1.875 degrees per step or 196 steps for 360 degrees.

In the case of the 1.8 degree per step motor, 800 steps are required for 360 degrees.

TB6600 stepper motor controller connections, current settings.
Fig. 3 TB6600 stepper motor controller current limit switches.

Current Limiting

The TB6600 also has built in current limiting which makes motor voltage easier to deal with.

For example I have 5-volt 1-amp stepper motor. Setting switches S4, S5, and S6 to 0.5 amp or 1 amp assures say a 12-volt power (with the correct current rating) can drive the 5-volt motor.

TB6600 stepper motor controller motor connections.
Fig. 4 TB6600 stepper motor controller basic electrical connections.

Home built parallel breakout board.
Fig. 5 Home built parallel breakout board.

Connections and Operation

Fig. 5 is my parallel port breakout board. The actual electrical connections I use is Fig. 2. Or you can buy a CNC parallel port breakout board to do much the same thing.

Power (5-volts) in both cases is derived from a USB port.

See the following:

PC printer port base address is 0x378. This is 8-bit bi-directional. Buffered by 74LS245 set for output. 74LS245 DIR pin 1 HIGH, enable pin 19 OE LOW.

PPORT pins 2-9 (DB25 connector) to 74LS245 pins A1-A8. Output B1-B8 is D0-D7. See spec sheet. Wired with common ground.

T6600 stepper motor controller: PUL+ to PPORT D0, PUL- GRD; Pulse is LOW-HIGH-LOW.


ENA+ to PPORT D2, ENA- GRD. D2 HIGH motor off, D2 LOW motor on. If ENA not connected motor on all times. Motor will be locked, can get hot. Thus ENA LOW locks motor until pulse.

Test Software

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/io.h>

// #include <string.h>
// #include <math.h>
// #include "myfile.h"

#define DATA 0x378  /* parallel port base address */
// D0-D7 pins 2-9

#define STATUS DATA + 1 // inputs only
// base address 0x379 - five bit 3-7
// bit 3 pin 15
// bit 4 pin 13
// bit 5 pin 12
// bit 6 pin 10
// bit 7 pin 11 inverted - HIGH reads LOW

#define CONTROL DATA + 2 // outputs
// base address 0x37A - four bits 0-3
// bit 0 pin 1 inverted
// bit 1 pin 14 inverted
// bit 2 pin 16 not inverted
// bit 3 pin 17 inverted

#define D0 1
#define D1 2
#define D2 4
#define D3 8
#define D4 16
#define D5 32
#define D6 64
#define D7 128

#define HIGH 1
#define LOW 0
#define CW 0
#define CCW 1
#define PUL 1 // 0x378 D0
#define DIR 2 // 0x378 D1
#define ENA 4 // 0x378 D2

#define SW1 8
#define SW2 16
#define SW3 32
#define SW4 64
#define SW5 128

// declare subroutines
void digitalWrite(int, int); // pin, state
void stepperOn(int, int); // steps, step_delay
int readSwitch(int bit);

// uses bits 3-7 with 7 inverted
// all have internal PU to HIGH
// Bitwise AND port data with bit value
int readSwitch(int SW_Number)   {
  int x;
  x = inb(Status) & SW_Number;
  if (x) return 1; // non-zero result
  else return 0;

// set pin state on DB25 pins 2-9 (D0-D7) at 0x378
void digitalWrite(int pinNumber, int state)   {
  unsigned char x, y, z;
  x = inb(DATA); // read data latches
  y = x & pinNumber; // determine pin state HIGH or LOW
  // pinNumber is a numeric value based on powers of 2
  if (state == 0  && y != 0)   {
    z = x & (0xFF - pinNumber); // bitwise AND clear bit
    outb(z, DATA);
  if (state == 1)   {
    z = x | pinNumber; // bitwise OR set bit
    outb(z, DATA);

// D0 is clk, D1 is direction, D2 is enable
// enable LOW to turn on
// 1 is CW, 0 is CCW
void stepperOn(int count, int delayMs)   {
  int x;
  digitalWrite(ENA, LOW); // motor enable
  for (x = 0; x <= count; x++)   {
    printf("Count = %d\n", x);
    //    if (readSwitch(D3) == 0) break;
    digitalWrite(PUL, HIGH);
    digitalWrite(PUL, LOW);
    usleep(delayMs * 1000);
  digitalWrite(ENA, HIGH); // motor off

int main(void)   {

  // must include to access port
  if (ioperm(DATA, 3, 1))
    fprintf(stderr, "Access denied to %x\n", DATA), exit(1);
  printf("Hello world.");
  digitalWrite(PUL, LOW);
  digitalWrite(ENA, HIGH); // off

  while (1) {

    // HIGH is CW, LOW is CCW
    digitalWrite(DIR, CW);
    stepperOn(100, 10);
    sleep(1); // wait 2 sec.
    digitalWrite(DIR, CCW);
    stepperOn(200, 10);
  return 0;


Youtube Videos

View all of my You Tube Videos
Also visit and subscribe to My YouTube Channel

Web site Copyright Lewis Loflin, All rights reserved.
If using this material on another site, please provide a link back to my site.