Drehscheibe 1:120 Nema17 DCC

Hallo Zusammen,
ich bräuchte mal eure Hilfe .

Bin auf der suche nach einem Programm für meine Drehscheibe hab aber noch nix richtiges gefunden. Da ich noch nicht so Fit bin in Programme selber schreiben frage ich mal hier nach Hilfe.

Die Drehscheibe sollte über DCC laufen mit einem Nema17 wo ich über die einzelnen DCC Adresse die Abgänge anfahren kann z.b Gleis 1 Adresse 200 Gleis 2 Adresse 201.

ich Würde gerne alles Gleise mit den jeweiligen Steps Programmieren z.b Gleis 1 100 Steps Gleis 2 150S Steps .

Gleis 0 soll Startpunkt sein über ein Hallsensor.

Habe in der NmraDCC Library ein Beispiel gefunden aber komme nicht mit den Positionen klar.

Vielen Dank schon mal im Voraus.

// DCC Stepper Motor Controller ( A4988 ) Example for Model Railroad Turntable Control
//
// See: https://www.dccinterface.com/product/arduino-model-railway-dcc-stepper-motor-controller-a4988-assembled/
// 
// Author: Alex Shepherd 2020-06-01
// 
// This example requires two Arduino Libraries:
//
// 1) The AccelStepper library from: http://www.airspayce.com/mikem/arduino/AccelStepper/index.html
//
// 2) The NmraDcc Library from: http://mrrwa.org/download/
//
// Both libraries can be found and installed via the Arduino IDE Library Manager
//
// Also checkout the artical I wrote in this project here:
//         http://mrrwa.org/2017/12/23/dcc-controlled-turntable-stepper-motor-driver/ 
//

#include <AccelStepper.h>
#include <NmraDcc.h>

// Define the Arduino input Pin number for the DCC Signal 
#define DCC_PIN     2

// The lines below define the pins used to connect to the A4988 driver module
#define A4988_STEP_PIN      4
#define A4988_DIRECTION_PIN 5
#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

// Uncomment the following line to enable Debug Print of DCC Messages
//#define NOTIFY_DCC_MSG

// 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
#define STEPPER_MAX_SPEED     800   // Sets the maximum permitted speed
#define STEPPER_ACCELARATION  1000  // Sets the acceleration/deceleration rate
#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
#define MOTOR_FULL_STEPS_PER_REVOLUTION 200

// The line below defines any reduction gearbox multiplier. No gearbox = 1 
#define REDUCTION_GEARBOX_RATIO 1

#define STEPS_PER_REVOLUTION (MOTOR_FULL_STEPS_PER_REVOLUTION * REDUCTION_GEARBOX_RATIO)

// The A4988 Driver Board has 3 pins that set the Stepping Mode which are connected to 3 jumpers on the board. 
// Uncomment the line below to match the Boards jumper setting        MS1,     MS2,     MS3
// --------------------------------------------------------------------------------------------
//#define FULL_TURN_STEPS (STEPS_PER_REVOLUTION)      // full steps - MS1=OFF, MS2=OFF, MS3=OFF
//#define FULL_TURN_STEPS (STEPS_PER_REVOLUTION * 2)  // 1/2  steps - MS1=ON,  MS2=OFF, MS3=OFF
#define FULL_TURN_STEPS (STEPS_PER_REVOLUTION * 4)  // 1/4  steps - MS1=OFF, MS2=ON,  MS3=OFF
//#define FULL_TURN_STEPS (STEPS_PER_REVOLUTION * 8)  // 1/8  steps - MS1=ON,  MS2=ON,  MS3=OFF
//#define FULL_TURN_STEPS (STEPS_PER_REVOLUTION * 16) // 1/16 steps - MS1=ON,  MS2=ON,  MS3=ON

#ifndef FULL_TURN_STEPS
#error You need to select one of the FULL_TURN_STEPS to match the A4988 Driver Board jumper settings
#endif

// This constant is useful to know the number of steps to rotate the turntable 180 degrees for the back entrance position
#define HALF_TURN_STEPS (FULL_TURN_STEPS / 2)

// Home Position Sensor Input
#define HOME_SENSOR_PIN 3
#define HOME_SENSOR_ACTIVE_STATE HIGH

// This structure holds the values for a turntable position wiht the DCC Address, Front Position in Steps from Home Sensor
typedef struct
{
  int dccAddress;
  int positionFront;
  int positionBack;
}
TurnoutPosition;

// The constant HOME_POSITION_DCC_ADDRESS is the base DCC Accessory Decoder Address for the Home Position
// with each subsequent position numbered sequentially from there  
#define POSITION_01_DCC_ADDRESS 200

// I decided to divide the turntable up into 10 Positions using #defines and mathc so it all scales with changes
// to the MS1,MS2,MS3 stepping jumpers above and to make the math tidy, but you assign positions how ever you like
#define POSITION_01 (HALF_TURN_STEPS / 10)

// This array contains the Turnout Positions which can have lines added/removed to suit your turntable 
TurnoutPosition turnoutPositions[] = {
  {POSITION_01_DCC_ADDRESS + 0, POSITION_01 * 1, POSITION_01 * 1 + HALF_TURN_STEPS },
  {POSITION_01_DCC_ADDRESS + 1, POSITION_01 * 2, POSITION_01 * 2 + HALF_TURN_STEPS },
  {POSITION_01_DCC_ADDRESS + 2, POSITION_01 * 3, POSITION_01 * 3 + HALF_TURN_STEPS },
  {POSITION_01_DCC_ADDRESS + 3, POSITION_01 * 4, POSITION_01 * 4 + HALF_TURN_STEPS },
  {POSITION_01_DCC_ADDRESS + 4, POSITION_01 * 5, POSITION_01 * 5 + HALF_TURN_STEPS },
  {POSITION_01_DCC_ADDRESS + 5, POSITION_01 * 6, POSITION_01 * 6 + HALF_TURN_STEPS },
  {POSITION_01_DCC_ADDRESS + 6, POSITION_01 * 7, POSITION_01 * 7 + HALF_TURN_STEPS },
  {POSITION_01_DCC_ADDRESS + 7, POSITION_01 * 8, POSITION_01 * 8 + HALF_TURN_STEPS },
  {POSITION_01_DCC_ADDRESS + 8, POSITION_01 * 9, POSITION_01 * 9 + HALF_TURN_STEPS },
  {POSITION_01_DCC_ADDRESS + 9, POSITION_01 *10, POSITION_01 *10 + HALF_TURN_STEPS },
};

// --------------------------------------------------------------------------------------------
// 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))

// Setup the AccelStepper object for the A4988 Stepper Motor Driver
AccelStepper stepper1(AccelStepper::DRIVER, A4988_STEP_PIN, A4988_DIRECTION_PIN);

// Dcc Accessory Decoder object
NmraDcc  Dcc ;

// Variables to store the last DCC Turnout message Address and Direction  
uint16_t lastAddr = 0xFFFF ;
uint8_t lastDirection = 0xFF;
int     lastStep = 0;


void processTurnoutCommand(uint16_t Addr, uint8_t Direction, uint8_t OutputPower)
{
  Serial.print(F("processTurnoutCommand: "));
  
  for (int i = 0; i < MAX_TURNOUT_POSITIONS ; i++)
  {
    if ((Addr == turnoutPositions[i].dccAddress) && ((Addr != lastAddr) || (Direction != lastDirection)) && OutputPower)
    {
      lastAddr = Addr ;
      lastDirection = Direction ;
      
      Serial.print(F("Moving to "));
      Serial.print(Direction ? F("Front") : F("Back"));
      Serial.print(F(" Position: "));
      Serial.print(i, DEC);
      Serial.print(F(" @ Step: "));

#ifdef A4988_ENABLE_PIN
      stepper1.enableOutputs();
#endif

      int newStep;
      if(Direction)
        newStep = turnoutPositions[i].positionFront;
      else
        newStep = turnoutPositions[i].positionBack;

      Serial.print(newStep, DEC);
      
      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;
    }
  }
}


// This function is called from the Library whenever a normal DCC Turnout Packet is received
void notifyDccAccTurnoutBoard (uint16_t BoardAddr, uint8_t OutputPair, uint8_t Direction, uint8_t OutputPower)
{
  uint16_t Addr = ((BoardAddr - 1) * 4) + OutputPair + 1;

  Serial.print(F("notifyDccAccTurnoutBoard: "));
  Serial.print(Addr,DEC) ;
  Serial.print(',');
  Serial.print(Direction,DEC) ;
  Serial.print(',');
  Serial.println(OutputPower, HEX) ;

  processTurnoutCommand(Addr, Direction, OutputPower);
};

#ifdef DISABLE_OUTPUTS_IDLE
bool lastIsRunningState ;
#endif 

void setupStepperDriver()
{
#ifdef A4988_ENABLE_PIN
  stepper1.setPinsInverted(false, false, true); // Its important that these commands are in this order
  stepper1.setEnablePin(A4988_ENABLE_PIN);    // otherwise the Outputs are NOT enabled initially
#endif
   
  stepper1.setMaxSpeed(STEPPER_MAX_SPEED);        // Sets the maximum permitted speed
  stepper1.setAcceleration(STEPPER_ACCELARATION); // Sets the acceleration/deceleration rate
  stepper1.setSpeed(STEPPER_SPEED);               // Sets the desired constant speed for use with runSpeed()

#ifdef A4988_ENABLE_PIN
  stepper1.enableOutputs();
#endif

#ifdef DISABLE_OUTPUTS_IDLE
  lastIsRunningState = stepper1.isRunning();
#endif
}

bool moveToHomePosition()
{
  Serial.println(F("Finding Home Sensor...."));

  pinMode(HOME_SENSOR_PIN, INPUT_PULLUP);

#ifdef ALWAYS_MOVE_NEGATIVE
  stepper1.move(0 - (FULL_TURN_STEPS * 2));
#else
  stepper1.move(FULL_TURN_STEPS * 2);
#endif  
  while(digitalRead(HOME_SENSOR_PIN) != HOME_SENSOR_ACTIVE_STATE)
    stepper1.run();

  if(digitalRead(HOME_SENSOR_PIN) == HOME_SENSOR_ACTIVE_STATE)
  {
    stepper1.stop();
    stepper1.setCurrentPosition(0);
    Serial.println(F("Found Home Position - Setting Current Position to 0"));
    return true;
  }
  else
    Serial.println(F("Home Position NOT FOUND - Check Sensor Hardware"));

  return false;  
}

void setupDCCDecoder()
{
  Serial.println(F("Setting up DCC Decorder..."));

  // Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
  // Many Arduino Cores now support the digitalPinToInterrupt() function that makes it easier to figure out the
  // Interrupt Number for the Arduino Pin number, which reduces confusion. 
#ifdef digitalPinToInterrupt
  Dcc.pin(DCC_PIN, 0);
#else
  Dcc.pin(0, DCC_PIN, 1);
#endif
  
  // Call the main DCC Init function to enable the DCC Receiver
  Dcc.init( MAN_ID_DIY, 10, CV29_ACCESSORY_DECODER, 0 );
}

void setup()
{
  Serial.begin(115200);
  uint8_t maxWaitLoops = 255;
  while(!Serial && maxWaitLoops--)  // Wait for the USB Device to Enumerate
    delay(20);
    
  Serial.println(F("\nExample Stepper Motor Driver for DCC Turntable Control"));

  Serial.print(F("Full Rotation 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++)
  {
    Serial.print(F("DCC Addr: "));
    Serial.print(turnoutPositions[i].dccAddress);

    Serial.print(F(" Front: "));
    Serial.print(turnoutPositions[i].positionFront);

    Serial.print(F(" Back: "));
    Serial.println(turnoutPositions[i].positionBack);
  }
  
  setupStepperDriver();
  if(moveToHomePosition());
  { 
    setupDCCDecoder();

    // Fake a DCC Packet to cause the Turntable to move to Position 1
    processTurnoutCommand(POSITION_01_DCC_ADDRESS, 1, 1);
  }
}

void loop()
{
  // You MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation
  Dcc.process();

  // Process the Stepper Library
  stepper1.run();

#ifdef DISABLE_OUTPUTS_IDLE
  if(stepper1.isRunning() != lastIsRunningState)
  {
    lastIsRunningState = stepper1.isRunning();
    if(!lastIsRunningState)
    {
      stepper1.disableOutputs();
      Serial.println(F("Disable Stepper Outputs"));
    }
  }
#endif  
}

#ifdef  NOTIFY_DCC_MSG
void notifyDccMsg( DCC_MSG * Msg)
{
  Serial.print("notifyDccMsg: ") ;
  for(uint8_t i = 0; i < Msg->Size; i++)
  {
    Serial.print(Msg->Data[i], HEX);
    Serial.write(' ');
  }
  Serial.println();
}
#endif

Dann musst du ein bischen mehr Hirnschlaz investieren und/oder beschreiben was nicht funktioniert.

Hallo

ist ja ein toller Empfang hier im Forum als erstes hab ich Geschieben das ich noch nicht so fit bin im Programmieren .

aber egal eventuell brauchst du ein Brille oder so weil ich habe geschrieben was ich haben möchte.

Die Drehscheibe sollte über DCC laufen mit einem Nema17 wo ich über die einzelnen DCC Adresse die Abgänge anfahren kann z.b Gleis 1 Adresse 200 Gleis 2 Adresse 201.

ich Würde gerne alles Gleise mit den jeweiligen Steps Programmieren z.b Gleis 1 100 Steps Gleis 2 150S Steps .

Gleis 0 soll Startpunkt sein über ein Hallsensor.

Also:
Funktion 1 drücken Tastfunktion soll die Drehscheibe auf Position 0 fahren
Funktion 2 drücken Tastfunktion soll die Drehscheibe auf Position 1 fahren Steps z.b 50
u.s.w
Funktion 8 drücken Tastfunktion soll die Drehscheibe auf Position 8 fahren Steps z.b 380

Das Programm was ich gefunden habe macht nix davon

Auftragsarbeiten sind in einer anderen Rubrik des Forums angesiedelt.

Gruß Tommy

Nur so am Rande, Nema17 sagt nichts über dein Motor, außer Befestigung

sorry habe mich falsch ausgedrückt mit möchte ich haben .

konnte mir einer das Programm eventuell helfen beim umstricken so das es funktioniert oder erklären wie ich in dem anderen Programm die Steps ändern kann.

Ich denke mal das muss ich ja hier machen
{POSITION_01_DCC_ADDRESS + 1, POSITION_01 * 2, POSITION_01 * 2 + HALF_TURN_STEPS },

Mein Motor ist ein 42×42×23mm 4.1V 1A 4 Lead 1.8 Deg Bipolar Step Parts - 17HS4023 mit A4988 Treiber und das ganze wollte ich mit einem Arduino Nano machen

Und was funktioniert jetzt nicht?

Die Bühne fährt nie die Positionen gleich an immer wieder unterschiedlich

Stimmt das mit deinem Setup überein?

// Home Position Sensor Input
#define HOME_SENSOR_PIN 3
#define HOME_SENSOR_ACTIVE_STATE HIGH

ich hab den Active State auf LOW gesetzt damit wenn die Bühne vorbei fährt geht der Hallsensor an und bleibt dann auch stehen

// Home Position Sensor Input
#define HOME_SENSOR_PIN 3
#define HOME_SENSOR_ACTIVE_STATE LOW

Also an den Ton hier im Forum musst du dich gewöhnen. Einfach ignorieren.

Im Prinzip ist das ganze eine Mathematische Aufgabe.

Dazu gehst du wie folgt vor.
Du suchst dir das Datenblatt des Motors.
Darin findest du Angaben zu Schrittweite /Halbschrittunterstützung Risiko des Schrittausfall etc.
Nun musst du nur noch einen Kreis malen. Und dann die Positionen ausrechnen.
Um Ungenauigkeiten zur vermeiden, das wie bei einer Motor-Festplatte handhaben.
Also jeden Anfahren die 0 Position anfahren und dann in einen Rutsch durch bis zum Ziel. Dabei logoweis bei der 0 Position die Bühne auch genau auf 0 justieren.

Was die Ansteuerung selbst angeht, kann ich dir aus über 30 Jahren Programmierer-Erfahrung sagen. Es ist 100 x schwerer durch den Code eines fremden durchzublicken, als selbst was zu coden.

Hier mal ein Beispiel wie man das mit einen Schrittmotor macht.

Grundsätzlich ist die Ansteuerung immer gleich. Die Frag ist nur, was für ein Treiberchip für welchen Motor .

Ich habe mal gerade nach den Nema-17 gegooglet. Ein Motor mit 3000 Schritt/min. finde ich persönlich sehr übertrieben. Und völlig unrealistisch (was das Modell angeht). Und ich glaube nicht, das der sich so perfekt positionieren lässt.
Falls du das Ding hast, kannst du es ja ausprobieren und mir sagen das ich mich irre.

Ich würde versuchen rauszufinden wieviel Kraft du max. brauchst um die Drehscheibe anzufahren. Und dann einen Schrittmotor suchen der da besser geeignet ist.
Die Alternative ist ein Zusatzgetriebe. Was dann die Drehscheibe antreibt. Das würde auch die Zielgenauigkeit (Und die ist das wichtigste) verbessern.

Gruß

Pucki

Zeige mall bitte das habe alle daten für den Stepper gefunden nur nicht das.

Heißt das, dass es jetzt funktioniert wie es soll?

Google : nema 17 datenblatt

1 Treffer bei mir.


NEMA17 SCHRITTMOTOR

Joy-IT
https://joy-it.net › files › NEMA17-06_Datenblatt
](https://joy-it.net/files/files/Produkte/NEMA17-06/NEMA17-06_Datenblatt.pdf)

PDF

Bei unserer NEMA 17 Serie handelt es sich um Hochdrehmoment- schrittmotoren, die Drehzahlen von bis zu 3000 U/min erreichen kön-.

3 Seiten


Gruß

Pucki

Warum nicht? Ist ein Stepper nicht DC Motor.
Dazu verwechselst was, Schritte sind nicht RPM nur zu Info, Hast falsch gelesen in deinem Beispiel?
och Pucki blamiere dich nicht.

Dazu es steht dort nicht schritte nur RPM, und was wichtig ist es ist nicht der Stepper!
Mach dich mall schlau was NEMA17 Bedeutet, dan passiert dir so was nicht.

Ich habe dazwischen noch ein Planeten Getriebe die Bühne dreht schön langsam.

Ich möchte doch nur die Positionen einstellen können weil ich mit den werten die im Programm stehen nix anfangrn kann .

Ich glaube das ihr arduino Profis zu weit denkt. Ich will nur den weg den sie fahren soll verändern mit einmal Funktiontaste drücken .

Funktioniert jetzt das Homing oder nicht?

Ja das geht

Ich muss jetzt nur die Position ändern und das weis ich nicht wie ich das machen muss.

Gibt s auch ein Option das der Stepper bei der jeweilige Position fest stehen bleibt (Blockiert).

Eine Frage mit der ich mich nicht auskenne. Aber, Du hast ein Planeten Getriebe. Wieviel Spiel hat dieses. Und was für ein Übersetzungsverhältniss?