Turntable Project Help

Hello everyone. I am a model railroad fan and have been working on a turntable project. I have followed numerous threads in other forums. I believe I have found the exact scenario I'm trying to create, but I do NOT know how to put these two together.

So here is what I have. I am using a stepperonline Nema 17 stepper motor with a TB6600 Driver.

The project that I have spent the most time following, they are using an Adafruit Stepper/motor hat as part of the equation. Here is the project I've been following. There is a photo of the interface that connects the DCC, and a hall effect sensor to the adafruit board. I want to keep this same wiring diagram, but instead of going to the adafruit board, I need to go directly to the Arduino uno.

Now I also need to send the outputs to the TB6600 stepper Driver.

So basically what I want to do is EXACTLY what this code is doing:

////////////////////////////////////////////////////////////////////////////////
//
// DCC Turntable Control Test Routines

#include <DCC_Decoder.h>
#include <AccelStepper.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Defines and structures
//
#define kDCC_INTERRUPT            0

typedef struct
{
    int               address;                // Address to respond to

} DCCAccessoryAddress;

DCCAccessoryAddress gAddresses[8];

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// Adafruit Setup

Adafruit_MotorShield AFMStop(0x60); // Default address, no jumpers

// Connect stepper with 200 steps per revolution (1.8 degree)
// to the M3, M4 terminals (blue,yellow,green,red)

Adafruit_StepperMotor *myStepper2 = AFMStop.getStepper(200, 2);

// you can change these to SINGLE, DOUBLE, INTERLEAVE or MICROSTEP!

// wrapper for the motor! (3200 Microsteps/revolution)
void forwardstep2() {  
  myStepper2->onestep(FORWARD, MICROSTEP);
}
void backwardstep2() {  
  myStepper2->onestep(BACKWARD, MICROSTEP);
}

// Now we'll wrap the stepper in an AccelStepper object

AccelStepper stepper2(forwardstep2, backwardstep2);

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Decoder Init 
//
void ConfigureDecoder()
{
    gAddresses[0].address = 200;
    gAddresses[1].address = 201;
    gAddresses[2].address = 202;
    gAddresses[3].address = 203;
    gAddresses[4].address = 204;
    gAddresses[5].address = 205;
    gAddresses[6].address = 206;
    gAddresses[7].address = 207;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Basic accessory packet handler 
//
void BasicAccDecoderPacket_Handler(int address, boolean activate, byte data)
{
        // Convert NMRA packet address format to human address
    address -= 1;
    address *= 4;
    address += 1;
    address += (data & 0x06) >> 1;
    
    boolean enable = (data & 0x01) ? 1 : 0;
    
    for(int i=0; i<(int)(sizeof(gAddresses)/sizeof(gAddresses[0])); i++)
    {
        if( address == gAddresses[i].address )
        {
            Serial.print("Basic addr: ");
            Serial.print(address,DEC);
            Serial.print("   activate: ");
            Serial.println(enable,DEC);
            
            if( enable )
            {
                switch (i) {
                  case 1:
                    stepper2.moveTo(200);
                  break;
                  case 2:
                    stepper2.moveTo(400);
                  break;
                  case 3:
                    stepper2.moveTo(600);
                  break;
                  case 4:
                    stepper2.moveTo(800);
                  break;
                  case 5:
                    stepper2.moveTo(1000);
                  break;
                  case 6:
                    stepper2.moveTo(1200);
                  break;
                  case 7:
                    stepper2.moveTo(1400);
                  break;
                }
            }else{
                switch (i) {
                  case 1:
                    stepper2.moveTo(1800);
                  break;
                  case 2:
                    stepper2.moveTo(2000);
                  break;
                  case 3:
                    stepper2.moveTo(2200);
                  break;
                  case 4:
                    stepper2.moveTo(2400);
                  break;
                  case 5:
                    stepper2.moveTo(2600);
                  break;
                  case 6:
                    stepper2.moveTo(2800);
                  break;
                  case 7:
                    stepper2.moveTo(3000);
                  break;
                }
            }
        }
    }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Setup
//
void setup() 
{ 
   Serial.begin(9600);
   
   AFMStop.begin(); // Start the shield
  
  //configure pin3 as an input and enable the internal pull-up resistor
  pinMode(3, INPUT_PULLUP);
  //read the sensor (open collector type) value into a variable
  int sensorVal = digitalRead(3);
   
  //set stepper motor speed and acceleration 
  stepper2.setMaxSpeed(30.0);
  stepper2.setAcceleration(20.0);
//  stepper2.moveTo(800);

// if near reference point move away
  sensorVal = digitalRead(3);
  while (sensorVal == LOW) {
    sensorVal = digitalRead(3);
    forwardstep2();
      delay(50);
  }
  
// step forward to sensor index point
  while (sensorVal == HIGH) {
    sensorVal = digitalRead(3);
    forwardstep2();
      delay(50);
  }
   
   DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true);
   ConfigureDecoder();
   DCC.SetupDecoder( 0x00, 0x00, kDCC_INTERRUPT );
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Main loop
//
void loop()
{
    static int addr = 0;
    
        ////////////////////////////////////////////////////////////////
        // Loop DCC library
    DCC.loop();
    
        ////////////////////////////////////////////////////////////////
        // Bump to next address to test
    if( ++addr >= (int)(sizeof(gAddresses)/sizeof(gAddresses[0])) )
    {
        addr = 0;
    }
    
    stepper2.run();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

The difference is that I do NOT want to use the adafruit stepper hat, I want to use my external TB6600 Driver instead.

I really hope this makes sense.

I don't know how to fix the code to do this.

I think this is really a hardware question. Please post some links to the existing and desired hardware, and a diagram showing how you want to use it.

sounds like you just need a library that supports the TB 6600 driver.

i recently completed adding a encoder to an old Walther's turntable. Does your stepper motor have sufficient resolution to align with the rails at any position?

how do you locate the 0th position?

I have ran several programs I've found with the TB6600 and the nema 17 stepper motor, and it's very accurate. The picture I posted above is a circuit I've already built. It takes the dcc signals and sends them the arduino. The 3 wire connector on the top left of the pic is a hall effect sensor. This is what locates home.

Another thing. The program I posted above is EXACTLY what I want. The only difference is that I need to remove the adafruit stuff. Every sample program I've seen using the TB6600 doesn't have any special libraries. This program here works very will with my motor and driver. However, it doesn't have DCC inputs, or a home point setting using a sensor. Plus it's using serial imputs from the serial monitor.

// test code for 
// CNC Single Axis 4A TB6600 Stepper Motor Driver Controller 
// use Serial Monitor to control 115200 baud


word  X;
word NX;
int MoveSpeed=600; //step in Microseconds
String     inputString = "help\n"; // a string to hold incoming data
boolean stringComplete = true;     // whether the string is completet
boolean        ComData = false;    // whether com data is on when motors are moving will slow them down

# define X_ENgnd  2 //ENA-(ENA) stepper motor enable , active low     Gray 
# define X_EN_5v  3 //ENA+(+5V) stepper motor enable , active low     Orange
# define X_DIRgnd 4 //DIR-(DIR) axis stepper motor direction control  Blue
# define X_DIR_5v 5 //DIR+(+5v) axis stepper motor direction control  Brown
# define X_STPgnd 6 //PUL-(PUL) axis stepper motor step control       Black
# define X_STP_5v 7 //PUL+(+5v) axis stepper motor step control       RED


void setup() {// *************************************************************     setup
pinMode (X_ENgnd ,OUTPUT); //ENA-(ENA)
pinMode (X_EN_5v ,OUTPUT); //ENA+(+5V)
pinMode (X_DIRgnd,OUTPUT); //DIR-(DIR)
pinMode (X_DIR_5v,OUTPUT); //DIR+(+5v)
pinMode (X_STPgnd,OUTPUT); //PUL-(PUL)
pinMode (X_STP_5v,OUTPUT); //PUL+(+5v)
pinMode (13,OUTPUT);
digitalWrite (X_ENgnd,  LOW); //ENA-(ENA)
digitalWrite (X_EN_5v, HIGH); //ENA+(+5V) low=enabled
digitalWrite (X_DIRgnd, LOW); //DIR-(DIR)
digitalWrite (X_DIR_5v, LOW); //DIR+(+5v)
digitalWrite (X_STPgnd, LOW); //PUL-(PUL)
digitalWrite (X_STP_5v, LOW); //PUL+(+5v)

Serial.begin(115200);
}

void serialEvent()// ********************************************************      Serial in
{ while (Serial.available()) 
  {
    char inChar = (char)Serial.read();            // get the new byte:
    if (inChar > 0)     {inputString += inChar;}  // add it to the inputString:
    if (inChar == '\n') { stringComplete = true;} // if the incoming character is a newline, set a flag so the main loop can do something about it: 
  }
}
void Help(){ // **************************************************************   Help
 Serial.println("Commands step by step guide");
 Serial.println("Type hello -sends TB6600 Tester Ready ");
 Serial.println("Type xon  -turns TB6600 on");
 Serial.println("Type x+Number(0-60000) eg x1904 -to set next move steps");
 Serial.println("Type mx -to make motor move to next postion");
 Serial.println("Type cdon -turns on postion data when moving will increase time of step");
 Serial.println("Type x0");
 Serial.println("Type mx");
 Serial.println("Type s+Number(0-2000) eg s500 -to set Microseconds betwean steps");
 Serial.println("Type s2000");
 Serial.println("Type x300");
 Serial.println("Type mx");
 Serial.println("Type xoff -turns TB6600 off");
 Serial.println("Type cdoff -turns off postion data when moving");
 
 

 inputString="";
}
void Hello(){ // **************************************************************   Hello
 Serial.println("TB6600 Tester Ready");
 inputString="";
}
void ENAXON(){ // *************************************************************   ENAXON
 Serial.println("ENAXON");
 digitalWrite (X_EN_5v, LOW);//ENA+(+5V) low=enabled
 inputString="";
}
void ENAXOFF(){  // ***********************************************************   ENAXOFF
 Serial.println("ENAXOFF");
 digitalWrite (X_EN_5v, HIGH);//ENA+(+5V) low=enabled
 inputString="";
}
void MSpeed(){  // ************************************************************   MoveSpeed
 inputString.setCharAt(0,' ');
 MoveSpeed=inputString.toInt();
 Serial.print("Speed=");
 Serial.println(MoveSpeed);
 inputString="";
}
void ComDataON(){  // *********************************************************   ComDataON
 ComData=true;
 Serial.println("ComDataOn");
 inputString="";
}
void ComDataOFF(){  // ********************************************************   ComDataOFF
 ComData=false;
 Serial.println("ComDataOFF");
 inputString="";
}
void NextX(){ // **************************************************************    NextX
 inputString.setCharAt(0,' ');
 NX=inputString.toInt();
 Serial.print("NX=");
 Serial.println(NX);
 inputString="";
}
void MoveX(){ // **************************************************************    Move
int xt;
if (NX>X)
{xt=NX-X; digitalWrite (X_DIR_5v,LOW);xt=1;}
else
{xt=X-NX; digitalWrite (X_DIR_5v,HIGH);xt=-1;}
if (ComData==true)
{for (; X !=NX; X=X+xt)
{    digitalWrite (X_STP_5v, HIGH);
     Serial.print("X=");
     delayMicroseconds (MoveSpeed);
     digitalWrite (X_STP_5v, LOW);
     delayMicroseconds (MoveSpeed);
     Serial.println(X+100000);
}}
else
{for (; X !=NX; X=X+xt)
{    digitalWrite (X_STP_5v, HIGH);
     delayMicroseconds (MoveSpeed);
     digitalWrite (X_STP_5v, LOW);
     delayMicroseconds (MoveSpeed);
}}
Serial.print("X=");
Serial.println(X);
//X=NX;

inputString="";
}
void loop()  // **************************************************************     loop
{
 serialEvent(); 
 if (stringComplete) 
 {
  if (inputString=="help\n")      {Help();}
  if (inputString=="hello\n")     {Hello();}  
  if (inputString=="xon\n")       {ENAXON();}   
  if (inputString=="xoff\n")      {ENAXOFF();}
  if (inputString=="cdon\n")      {ComDataON();}
  if (inputString=="cdoff\n")     {ComDataOFF();}
  if (inputString=="mx\n")        {MoveX();}
  if (inputString.charAt(0)=='s')   {MSpeed();}
  if (inputString.charAt(0)=='x')   {NextX();} 
  
  if (inputString !="") {Serial.println("BAD COMMAND="+inputString);}// Serial.print("\n"); }// "\t" tab      
  inputString = ""; stringComplete = false; // clear the string:
 }

}

The only difference is that I need to remove the adafruit stuff.

which are those?

it doesn't have DCC inputs,

does this mean it lacks the hardware interface or software?

doesn't have ... home point setting using a sensor

The 3 wire connector on the top left of the pic is a hall effect sensor. This is what locates home.

are you lacking the software?

it's using serial imputs from the serial monitor.

don't you want this for debugging?

The program I posted in my original post does exactly what I need it to do. The problem is its using an adafruit stepper shield. I want to use my TB6600. So I need to remove the adafruit code and make the program work with the TB6600 driver instead.

I have been spending alot of time thinking about this whole project. The original project was written to control a model railroad turntable using a stepper motor and DCC. This is GREAT, because it's exactly what I want to do. However, they are using the Adafruit stepper/servo hat in the project, and I do NOT want to use this. The reason is because I noticed that everything moves so much smoother with the TB6600 driver.

So I'd like to keep this thread together since it's all related to my first question. I would like to start off though with the program that got me started on all of this.

////////////////////////////////////////////////////////////////////////////////
//
// DCC Turntable Control Test Routines

#include <DCC_Decoder.h>
#include <AccelStepper.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Defines and structures
//
#define kDCC_INTERRUPT            0

typedef struct
{
    int               address;                // Address to respond to

} DCCAccessoryAddress;

DCCAccessoryAddress gAddresses[8];

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// Adafruit Setup

Adafruit_MotorShield AFMStop(0x60); // Default address, no jumpers

// Connect stepper with 200 steps per revolution (1.8 degree)
// to the M3, M4 terminals (blue,yellow,green,red)

Adafruit_StepperMotor *myStepper2 = AFMStop.getStepper(200, 2);

// you can change these to SINGLE, DOUBLE, INTERLEAVE or MICROSTEP!

// wrapper for the motor! (3200 Microsteps/revolution)
void forwardstep2() {  
  myStepper2->onestep(FORWARD, MICROSTEP);
}
void backwardstep2() {  
  myStepper2->onestep(BACKWARD, MICROSTEP);
}

// Now we'll wrap the stepper in an AccelStepper object

AccelStepper stepper2(forwardstep2, backwardstep2);

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Decoder Init 
//
void ConfigureDecoder()
{
    gAddresses[0].address = 200;
    gAddresses[1].address = 201;
    gAddresses[2].address = 202;
    gAddresses[3].address = 203;
    gAddresses[4].address = 204;
    gAddresses[5].address = 205;
    gAddresses[6].address = 206;
    gAddresses[7].address = 207;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Basic accessory packet handler 
//
void BasicAccDecoderPacket_Handler(int address, boolean activate, byte data)
{
        // Convert NMRA packet address format to human address
    address -= 1;
    address *= 4;
    address += 1;
    address += (data & 0x06) >> 1;
    
    boolean enable = (data & 0x01) ? 1 : 0;
    
    for(int i=0; i<(int)(sizeof(gAddresses)/sizeof(gAddresses[0])); i++)
    {
        if( address == gAddresses[i].address )
        {
            Serial.print("Basic addr: ");
            Serial.print(address,DEC);
            Serial.print("   activate: ");
            Serial.println(enable,DEC);
            
            if( enable )
            {
                switch (i) {
                  case 1:
                    stepper2.moveTo(200);
                  break;
                  case 2:
                    stepper2.moveTo(400);
                  break;
                  case 3:
                    stepper2.moveTo(600);
                  break;
                  case 4:
                    stepper2.moveTo(800);
                  break;
                  case 5:
                    stepper2.moveTo(1000);
                  break;
                  case 6:
                    stepper2.moveTo(1200);
                  break;
                  case 7:
                    stepper2.moveTo(1400);
                  break;
                }
            }else{
                switch (i) {
                  case 1:
                    stepper2.moveTo(1800);
                  break;
                  case 2:
                    stepper2.moveTo(2000);
                  break;
                  case 3:
                    stepper2.moveTo(2200);
                  break;
                  case 4:
                    stepper2.moveTo(2400);
                  break;
                  case 5:
                    stepper2.moveTo(2600);
                  break;
                  case 6:
                    stepper2.moveTo(2800);
                  break;
                  case 7:
                    stepper2.moveTo(3000);
                  break;
                }
            }
        }
    }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Setup
//
void setup() 
{ 
   Serial.begin(9600);
   
   AFMStop.begin(); // Start the shield
  
  //configure pin3 as an input and enable the internal pull-up resistor
  pinMode(3, INPUT_PULLUP);
  //read the sensor (open collector type) value into a variable
  int sensorVal = digitalRead(3);
   
  //set stepper motor speed and acceleration 
  stepper2.setMaxSpeed(30.0);
  stepper2.setAcceleration(20.0);
//  stepper2.moveTo(800);

// if near reference point move away
  sensorVal = digitalRead(3);
  while (sensorVal == LOW) {
    sensorVal = digitalRead(3);
    forwardstep2();
      delay(50);
  }
  
// step forward to sensor index point
  while (sensorVal == HIGH) {
    sensorVal = digitalRead(3);
    forwardstep2();
      delay(50);
  }
   
   DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true);
   ConfigureDecoder();
   DCC.SetupDecoder( 0x00, 0x00, kDCC_INTERRUPT );
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Main loop
//
void loop()
{
    static int addr = 0;
    
        ////////////////////////////////////////////////////////////////
        // Loop DCC library
    DCC.loop();
    
        ////////////////////////////////////////////////////////////////
        // Bump to next address to test
    if( ++addr >= (int)(sizeof(gAddresses)/sizeof(gAddresses[0])) )
    {
        addr = 0;
    }
    
    stepper2.run();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

As you can see in the program here, they are defining the Adafruit board in the beginning. IN several places in the code, it calls on stepper2 which was defined in the beginning. I get this. I would like to use this stepper2 to send the dir and pulse signals to my TB6600 driver.

Now while I've been thinking this through, I can see it's not quite as easy as defining the stepper2 as an output. So this is where I get confused.

Could someone please point me in the right direction? I'm NOT asking for this to be written for me. I'm asking for direction to get me on track.

Thank you in advance.