This is adapted from a sketch written by Ray from the RMWeb Forum. Thank you Ray for your inspiration and help.
// DCC Turntable Control - Ian Jeffery
#include <DCC_Decoder.h>
#include <AccelStepper.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
//
// Defines and structures
//
#define cDCC_INTERRUPT 0
typedef struct
{
int address;
int stationFront;
int stationBack;
}
DCCAccessoryAddress;
DCCAccessoryAddress gAddresses[17];
int cNudge = 5; // nudge it forward a few steps.
#define cStartOfNudgeAddresses 12
//
// 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);
}
void release2()
{
Serial.println(F("Powering Down Motor "));
myStepper2->release();
}
// Now we'll wrap the stepper in an AccelStepper object
AccelStepper stepper2(forwardstep2, backwardstep2);
#define entryStation 906
//
// Decoder Init
//
void ConfigureDecoder()
{
// this is home
gAddresses[0].address = 299;
gAddresses[0].stationFront = 10;
gAddresses[0].stationBack = 3190;
gAddresses[1].address = 200;
gAddresses[1].stationFront = 906;
gAddresses[1].stationBack = 2506;
gAddresses[2].address = 201;
gAddresses[2].stationFront = 1692;
gAddresses[2].stationBack = 82;
gAddresses[3].address = 202;
gAddresses[3].stationFront = 1802;
gAddresses[3].stationBack = 202;
gAddresses[4].address = 203;
gAddresses[4].stationFront = 1921;
gAddresses[4].stationBack = 321;
gAddresses[5].address = 204;
gAddresses[5].stationFront = 2040;
gAddresses[5].stationBack = 428;
gAddresses[6].address = 205;
gAddresses[6].stationFront = 2142;
gAddresses[6].stationBack = 536;
gAddresses[7].address = 206;
gAddresses[7].stationFront = 2266;
gAddresses[7].stationBack = 1100;
gAddresses[8].address = 207;
gAddresses[8].stationFront = 2392;
gAddresses[8].stationBack = 1300;
gAddresses[9].address = 208;
gAddresses[9].stationFront = 2515;
gAddresses[9].stationBack = 1500;
gAddresses[10].address = 209;
gAddresses[10].stationFront = 2634;
gAddresses[10].stationBack = 1700;
gAddresses[11].address = 210;
gAddresses[11].stationFront = 2736;
gAddresses[11].stationBack = 1900;
// these are the nudge addresses
gAddresses[12].address = 300;
gAddresses[13].address = 301;
gAddresses[14].address = 302;
gAddresses[15].address = 303;
// this is the powerdown address
gAddresses[16].address = 399;
}
void moveTurnTable(int position)
{
// This moves the turntable, and then shuts off the power to the motor
Serial.print(F("Moving to Position : "));
Serial.println(position, DEC);
stepper2.moveTo(position);
Serial.print("Distance to Position : ");
Serial.println(abs(stepper2.distanceToGo()), DEC);
while (abs(stepper2.distanceToGo()) > 0)
{
stepper2.run();
}
Serial.print(F("Moved to Position."));
delay(1000);
release2();
}
//
// Accessory packet handler - This is where we react to DCC Addresses
//
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;
Serial.print(F("Basic addr: "));
Serial.print(address, DEC);
Serial.print(F(" activate: "));
Serial.println(enable, DEC);
for (int i = 0; i<(int)(sizeof(gAddresses) / sizeof(gAddresses[0])); i++)
{
if (address == gAddresses[i].address)
{
Serial.print(F("Moving to Station : "));
Serial.println(i, DEC);
if (enable)
{
if (i < cStartOfNudgeAddresses)
{
moveTurnTable(gAddresses[i].stationFront);
break;
}
else
switch (i)
{
// nudge addresses
case 12:
Serial.print(F("Nudging forward 5 steps : "));
moveTurnTable(stepper2.currentPosition() + cNudge);
break;
case 13:
Serial.print(F("Nudging forward 10 steps : "));
moveTurnTable(stepper2.currentPosition() + (cNudge * 2));
break;
case 14:
Serial.print(F("Nudging forward 50 steps : "));
moveTurnTable(stepper2.currentPosition() + (cNudge * 4));
break;
case 15:
Serial.print(F("Nudging forward 100 steps : "));
moveTurnTable(stepper2.currentPosition() + (cNudge * 20));
break;
case 16:
Serial.println(F("Powering Down Motor "));
release2();
break;
}
}
else
{
if (i < cStartOfNudgeAddresses)
{
moveTurnTable(gAddresses[i].stationBack);
break;
}
else
switch (i)
{
// nudge addresses
case 12:
Serial.print(F("Nudging backwards 5 steps : "));
moveTurnTable(stepper2.currentPosition() - cNudge);
break;
case 13:
Serial.print(F("Nudging backwards 10 steps : "));
moveTurnTable(stepper2.currentPosition() - (cNudge * 2));
break;
case 14:
Serial.print(F("Nudging backwards 50 steps : "));
moveTurnTable(stepper2.currentPosition() - (cNudge * 4));
break;
case 15:
Serial.print(F("Nudging backwards 100 steps : "));
moveTurnTable(stepper2.currentPosition() - (cNudge * 20));
break;
case 16:
Serial.println(F("Powering Down Motor "));
release2();
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(100.0);
stepper2.setAcceleration(20.0);
//
// if near reference point move away
sensorVal = digitalRead(3);
while (sensorVal == LOW) {
sensorVal = digitalRead(3);
forwardstep2();
delay(25);
}
// step forward to sensor index point
while (sensorVal == HIGH) {
sensorVal = digitalRead(3);
forwardstep2();
delay(25);
}
stepper2.setMaxSpeed(35.0);
Serial.println(F("Moving to entry station"));
stepper2.moveTo(entryStation);
stepper2.runToPosition();
delay(2000);
// Power down the Stepper Motor
release2();
DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true);
ConfigureDecoder();
DCC.SetupDecoder(0x00, 0x00, cDCC_INTERRUPT);
}
//
// Main loop
//
void loop()
{
// Loop DCC library
DCC.loop();
// Loop the Stepper Motor Library
stepper2.run();
}