improved DCCInterface_TurntableControl example to:

- Added selectable Movement Strategy: Positive Direction Only, Negative Direction Only, Shortest Distance
- Made Disabling Output on Idle optional
This commit is contained in:
Alex Shepherd
2020-06-01 18:49:00 +12:00
parent f3da07c739
commit 3abb683d8d
2 changed files with 84 additions and 28 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.development
*.zip

View File

@@ -1,8 +1,8 @@
// DCC Stepper Motor Controller ( A4988 ) Example for Model Railroad Turntable Control // DCC Stepper Motor Controller ( A4988 ) Example for Model Railroad Turntable Control
// //
// See: https://www.dccinterface.com/how-to/assemblyguide/ // See: https://www.dccinterface.com/product/arduino-model-railway-dcc-stepper-motor-controller-a4988-assembled/
// //
// Author: Alex Shepherd 2017-12-04 // Author: Alex Shepherd 2020-06-01
// //
// This example requires two Arduino Libraries: // This example requires two Arduino Libraries:
// //
@@ -22,12 +22,22 @@
// The lines below define the pins used to connect to the A4988 driver module // The lines below define the pins used to connect to the A4988 driver module
#define A4988_STEP_PIN 4 #define A4988_STEP_PIN 4
#define A4988_DIRECTION_PIN 5 #define A4988_DIRECTION_PIN 5
// Uncomment the next line to enable Powering-Off the Stepper when its not running to reduce heating the motor and driver
#define A4988_ENABLE_PIN 6 #define A4988_ENABLE_PIN 6
#ifdef A4988_ENABLE_PIN
// Uncomment the next line to enable Powering-Off the Stepper when its not running to reduce heating the motor and driver
//#define DISABLE_OUTPUTS_IDLE
#endif
// By default the stepper motor will move the shortest distance to the desired position.
// If you need the turntable to only move in the Positive/Increasing or Negative/Decreasing step numbers to better handle backlash in the mechanism
// Then uncomment the appropriate line below
//#define ALWAYS_MOVE_POSITIVE
//#define ALWAYS_MOVE_NEGATIVE
// The lines below define the stepping speed and acceleration, which you may need to tune for your application // The lines below define the stepping speed and acceleration, which you may need to tune for your application
#define STEPPER_MAX_SPEED 800 // Sets the maximum permitted speed #define STEPPER_MAX_SPEED 800 // Sets the maximum permitted speed
#define STEPPER_ACCELARATION 1000 // Sets the acceleration/deceleration rate #define STEPPER_ACCELARATION 1000 // Sets the acceleration/deceleration rate
#define STEPPER_SPEED 300 // Sets the desired constant speed for use with runSpeed() #define STEPPER_SPEED 300 // Sets the desired constant speed for use with runSpeed()
// The line below defines the number of "Full Steps" your stepper motor does for a full rotation // The line below defines the number of "Full Steps" your stepper motor does for a full rotation
@@ -92,6 +102,9 @@ TurnoutPosition turnoutPositions[] = {
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
// You shouldn't need to edit anything below this line unless you're needing to make big changes... ;) // You shouldn't need to edit anything below this line unless you're needing to make big changes... ;)
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
#if defined(ALWAYS_MOVE_POSITIVE) && defined(ALWAYS_MOVE_NEGATIVE)
#error ONLY uncomment one of ALWAYS_MOVE_POSITIVE or ALWAYS_MOVE_NEGATIVE but NOT both
#endif
#define MAX_TURNOUT_POSITIONS (sizeof(turnoutPositions) / sizeof(TurnoutPosition)) #define MAX_TURNOUT_POSITIONS (sizeof(turnoutPositions) / sizeof(TurnoutPosition))
@@ -104,11 +117,12 @@ NmraDcc Dcc ;
// Variables to store the last DCC Turnout message Address and Direction // Variables to store the last DCC Turnout message Address and Direction
uint16_t lastAddr = 0xFFFF ; uint16_t lastAddr = 0xFFFF ;
uint8_t lastDirection = 0xFF; uint8_t lastDirection = 0xFF;
int lastStep = 0;
// This function is called whenever a normal DCC Turnout Packet is received // This function is called whenever a normal DCC Turnout Packet is received
void notifyDccAccTurnoutOutput( uint16_t Addr, uint8_t Direction, uint8_t OutputPower ) void notifyDccAccTurnoutOutput( uint16_t Addr, uint8_t Direction, uint8_t OutputPower )
{ {
Serial.print("notifyDccAccTurnoutOutput: ") ; Serial.print(F("notifyDccAccTurnoutOutput: "));
Serial.print(Addr,DEC) ; Serial.print(Addr,DEC) ;
Serial.print(','); Serial.print(',');
Serial.print(Direction,DEC) ; Serial.print(Direction,DEC) ;
@@ -131,23 +145,50 @@ void notifyDccAccTurnoutOutput( uint16_t Addr, uint8_t Direction, uint8_t Output
#ifdef A4988_ENABLE_PIN #ifdef A4988_ENABLE_PIN
stepper1.enableOutputs(); stepper1.enableOutputs();
#endif #endif
if (Direction)
{ int newStep;
Serial.println(turnoutPositions[i].positionFront, DEC); if(Direction)
stepper1.moveTo(turnoutPositions[i].positionFront); newStep = turnoutPositions[i].positionFront;
break;
}
else else
{ newStep = turnoutPositions[i].positionBack;
Serial.println(turnoutPositions[i].positionBack, DEC);
stepper1.moveTo(turnoutPositions[i].positionBack); Serial.print(newStep, DEC);
break;
} Serial.print(F(" Last Step: "));
Serial.print(lastStep, DEC);
int diffStep = newStep - lastStep;
Serial.print(F(" Diff Step: "));
Serial.print(diffStep, DEC);
#if defined ALWAYS_MOVE_POSITIVE
Serial.print(F(" Positive"));
if(diffStep < 0)
diffStep += FULL_TURN_STEPS;
#elif defined ALWAYS_MOVE_NEGATIVE
Serial.print(F(" Negative"));
if(diffStep > 0)
diffStep -= FULL_TURN_STEPS;
#else
if(diffStep > HALF_TURN_STEPS)
diffStep = diffStep - FULL_TURN_STEPS;
else if(diffStep < -HALF_TURN_STEPS)
diffStep = diffStep + FULL_TURN_STEPS;
#endif
Serial.print(F(" Move: "));
Serial.println(diffStep, DEC);
stepper1.move(diffStep);
lastStep = newStep;
break;
} }
} }
}; };
#ifdef A4988_ENABLE_PIN #ifdef DISABLE_OUTPUTS_IDLE
bool lastIsRunningState ; bool lastIsRunningState ;
#endif #endif
@@ -161,8 +202,12 @@ void setupStepperDriver()
stepper1.setMaxSpeed(STEPPER_MAX_SPEED); // Sets the maximum permitted speed stepper1.setMaxSpeed(STEPPER_MAX_SPEED); // Sets the maximum permitted speed
stepper1.setAcceleration(STEPPER_ACCELARATION); // Sets the acceleration/deceleration rate stepper1.setAcceleration(STEPPER_ACCELARATION); // Sets the acceleration/deceleration rate
stepper1.setSpeed(STEPPER_SPEED); // Sets the desired constant speed for use with runSpeed() stepper1.setSpeed(STEPPER_SPEED); // Sets the desired constant speed for use with runSpeed()
#ifdef A4988_ENABLE_PIN #ifdef A4988_ENABLE_PIN
stepper1.enableOutputs();
#endif
#ifdef DISABLE_OUTPUTS_IDLE
lastIsRunningState = stepper1.isRunning(); lastIsRunningState = stepper1.isRunning();
#endif #endif
} }
@@ -173,14 +218,19 @@ bool moveToHomePosition()
pinMode(HOME_SENSOR_PIN, INPUT_PULLUP); pinMode(HOME_SENSOR_PIN, INPUT_PULLUP);
#ifdef ALWAYS_MOVE_NEGATIVE
stepper1.move(0 - (FULL_TURN_STEPS * 2));
#else
stepper1.move(FULL_TURN_STEPS * 2); stepper1.move(FULL_TURN_STEPS * 2);
#endif
while(digitalRead(HOME_SENSOR_PIN) != HOME_SENSOR_ACTIVE_STATE) while(digitalRead(HOME_SENSOR_PIN) != HOME_SENSOR_ACTIVE_STATE)
stepper1.run(); stepper1.run();
if(digitalRead(HOME_SENSOR_PIN) == HOME_SENSOR_ACTIVE_STATE) if(digitalRead(HOME_SENSOR_PIN) == HOME_SENSOR_ACTIVE_STATE)
{ {
Serial.println(F("Found Home Position - Setting Current Position to 0")); stepper1.stop();
stepper1.setCurrentPosition(0); stepper1.setCurrentPosition(0);
Serial.println(F("Found Home Position - Setting Current Position to 0"));
return true; return true;
} }
else else
@@ -210,28 +260,32 @@ void setup()
Serial.print(F("Full Rotation Steps: ")); Serial.print(F("Full Rotation Steps: "));
Serial.println(FULL_TURN_STEPS); Serial.println(FULL_TURN_STEPS);
Serial.print(F("Movement Strategy: "));
#if defined ALWAYS_MOVE_POSITIVE
Serial.println(F("Positive Direction Only"));
#elif defined ALWAYS_MOVE_NEGATIVE
Serial.println(F("Negative Direction Only"));
#else
Serial.println(F("Shortest Distance"));
#endif
for(uint8_t i = 0; i < MAX_TURNOUT_POSITIONS; i++) for(uint8_t i = 0; i < MAX_TURNOUT_POSITIONS; i++)
{ {
Serial.print("DCC Addr: "); Serial.print(F("DCC Addr: "));
Serial.print(turnoutPositions[i].dccAddress); Serial.print(turnoutPositions[i].dccAddress);
Serial.print(" Front: "); Serial.print(F(" Front: "));
Serial.print(turnoutPositions[i].positionFront); Serial.print(turnoutPositions[i].positionFront);
Serial.print(" Back: "); Serial.print(F(" Back: "));
Serial.println(turnoutPositions[i].positionBack); Serial.println(turnoutPositions[i].positionBack);
} }
setupStepperDriver(); setupStepperDriver();
if(moveToHomePosition()); if(moveToHomePosition());
{ {
setupDCCDecoder(); setupDCCDecoder();
#ifdef A4988_ENABLE_PIN
stepper1.enableOutputs();
#endif
// Fake a DCC Packet to cause the Turntable to move to Position 1 // Fake a DCC Packet to cause the Turntable to move to Position 1
notifyDccAccTurnoutOutput(POSITION_01_DCC_ADDRESS, 1, 1); notifyDccAccTurnoutOutput(POSITION_01_DCC_ADDRESS, 1, 1);
} }
@@ -245,7 +299,7 @@ void loop()
// Process the Stepper Library // Process the Stepper Library
stepper1.run(); stepper1.run();
#ifdef A4988_ENABLE_PIN #ifdef DISABLE_OUTPUTS_IDLE
if(stepper1.isRunning() != lastIsRunningState) if(stepper1.isRunning() != lastIsRunningState)
{ {
lastIsRunningState = stepper1.isRunning(); lastIsRunningState = stepper1.isRunning();