Schrittmotor mit Joystick steuern

Hallo zusammen.
Da ich die Z Achse meiner Hobbydrehbank mit einem Schrittmotor verbaut habe, musste ich mich mit der Steuerung mittels Arduino auseinander setzen.
Da ich schon etwas älteres Semester bin und mich mit programmieren von Sketches überfordert bin, hatte ich mich auf die suche eines fertigen Sketch gemacht und bin nach langer suche fündig geworden.
So Schön so Gut. Ich hatte meine Drehbank noch mit 2 Endschalter versehen, und schaff es einfach nicht
die Endschalter im Sketch rein zu programmieren ohne das Fehlermeldungen erscheinen. Auf Schreibweise
und Zeichensetzung habe ich geachtet. Da ich auch nicht so toll englich kann bin ich nur am rätseln.
Wenn ich hier einen Fachmann-frau finden würde der mir dabei behilflich wäre in den Sketch 2 Endschalter zu integrieren würde ich mich freuen und wäre sehr dankbar.
Der ursprüngliche Sketch ist von einer Andrea Lombardo !

/*
* Controllo di due motori passo passo con Arduino e un Joystick
*
* Autore  : Andrea Lombardo
* Web     : http://www.lombardoandrea.com
* Post    : http://wp.me/p27dYH-KQ
*/ 

//Inclusione delle librerie
#include <AccelStepper.h>
#include <Bounce2.h>

//definizione delle costanti dei pin di Arduino
const int ledEnable = 13; //il led on board ci mostrerà lo stato di attivazione dei motori
const int pinSwEnable = 7;  //il bottone presente nel modulo joystick che abilita o disabilita il controllo
const int pinEnable = 8;  //i pin che comandano lo stato ENABLE dei driver A4988 sono in collegati in serie per questo basta un solo pin per gestirli entrambi

unsigned long debounceDelay = 10; //millisecondi per il debonuce del bottone

const int jX = A0;  //pin analogico che legge i valori per le X
const int stepX = 3;  //pin digitale che invia i segnali di STEP al driver delle X
const int dirX = 4; //pin digitale che invia il segnale DIREZIONE al driver delle X
long speedX, valX, mapX;  //variabili di gestione movimenti motore X

const int jY = A1;  //pin analogico che legge i valori per le Y
const int stepY = 5;  //pin digitale che invia i segnali di STEP al driver delle Y
const int dirY = 6; //pin digitale che invia il segnale DIREZIONE al driver delle Y
long speedY, valY, mapY;  //variabili di gestione movimenti motore Y

//variabili utilizzate dalla libreria AccelStepper
const int maxSpeed = 1000;  //stando alla documentazione della libreria questo valore può essere impostato fino a 4000 per un Arduino UNO
const int minSpeed = 0; //velocità minima del motore
const float accelerazione = 50.0; //numero di step al secondo in accelerazione

const int treshold = 30;  //la lettura dei potenziometri non è mai affidabile al 100%, questo valore aiuta a determinare il punto da considerare come "Stai fermo" nei movimenti
long tresholdUp, tresholdDown;  //variabili di servizio per espletare il compito descritto sopra

boolean abilitato, muoviX, muoviY, enable;  //variabili di gestione dei movimenti

Bounce btnEnable = Bounce();  //istanzia un bottone dalla libreria Bounce

//istanzia i motori
AccelStepper motoreX(AccelStepper::DRIVER, stepX, dirX);
AccelStepper motoreY(AccelStepper::DRIVER, stepY, dirY);

void setup() {
 //inizializza valori
 speedX = speedY = 0;
 enable = false;

 //definizione delle modalità dei pin
 pinMode(ledEnable, OUTPUT);
 pinMode(pinEnable, OUTPUT);

 pinMode(pinSwEnable, INPUT_PULLUP); //l'input dello switch ha bisogno di essere settato come INPUT_PULLUP

 digitalWrite(ledEnable, enable);
 digitalWrite(pinEnable, !enable); //I driver A4988 disabilitano i comandi al motore se sul pin ENABLE ricevono un segnale HIGH per questo motivo il valore è opposto a quello del LED

 //configura il bottone del joystick utilizzando la libreria Bounce
 btnEnable.attach(pinSwEnable);
 btnEnable.interval(debounceDelay);

 //calcola range valori entro i quali considerare la posizione del joystick come "Stai fermo"
 tresholdDown = (maxSpeed / 2) - treshold;
 tresholdUp = (maxSpeed / 2) + treshold;

 //configura parametri dei motori
 motoreX.setMaxSpeed(maxSpeed);
 motoreX.setSpeed(minSpeed);
 motoreX.setAcceleration(accelerazione);

 motoreY.setMaxSpeed(maxSpeed);
 motoreY.setSpeed(minSpeed);
 motoreY.setAcceleration(accelerazione);
}

void loop() {

 //esegui funzione di controllo e lettura del bottone che determina lo stato di abilitazione
 checkEnable();

 digitalWrite(ledEnable, enable);  //mostra stato di abilitazione tramite il led su pin 13
 digitalWrite(pinEnable, !enable); //imposta valore opposto sui pin ENABLE dei driver

 //esegui lettura analogica dei valori provenienti dai potenziometri del joystick
 valX = analogRead(jX);
 valY = analogRead(jY);

 //mappa i valori letti in funzione della velocità inima e massima
 mapX = map(valX, 0, 1023, minSpeed, maxSpeed);
 mapY = map(valY, 0, 1023, minSpeed, maxSpeed);

 //esegui funzione di comando dei motori
 pilotaMotori(mapX, mapY);

}

void pilotaMotori(long mapX, long mapY) {

 if (mapX <= tresholdDown) {
   //x va indietro
   speedX = -map(mapX, tresholdDown, minSpeed,   minSpeed, maxSpeed);
   muoviX = true;
 } else if (mapX >= tresholdUp) {
   //x va avanti
   speedX = map(mapX,  maxSpeed, tresholdUp,  maxSpeed, minSpeed);
   muoviX = true;
 } else {
   //x sta fermo
   speedX = 0;
   muoviX = false;
 }

 if (mapY <= tresholdDown) {
   //y va giù
   speedY = -map(mapY, tresholdDown, minSpeed,   minSpeed, maxSpeed);
   muoviY = true;
 } else if (mapY >= tresholdUp) {
   //y va su
   speedY = map(mapY,  maxSpeed, tresholdUp,  maxSpeed, minSpeed);
   muoviY = true;
 } else {
   //y sta fermo
   speedY = 0;
   muoviY = false;
 }

 if (muoviX) {
   motoreX.setSpeed(speedX);
   motoreX.run();
 } else {
   motoreX.stop();
 }

 if (muoviY) {
   motoreY.setSpeed(speedY);
   motoreY.run();
 } else {
   motoreY.stop();
 }
}


void checkEnable() {

 btnEnable.update();

 if (btnEnable.fell()) {
   enable = !enable;
 }

}

Liebe Grüße vom Falken!

Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Dann ist er auch auf mobilen Geräten besser lesbar.
Das kannst Du auch noch nachträglich ändern.

Gruß Tommy

(deleted)

hm also einen sketch mit italienischen Bezeichnern finde ich schwer zu analysieren.

Verstehe ich das richtig die Funktionalität die du brauchst ist über einen analogen Joystick für XY =
eine X-Achse und eine Y-Achse steuern.

Steuern läuft so ab: Joystick in Mittelposition momentane Position wird gehalten.
Joystick wird ein bisschen aus der Neutralposition ausgelenkt Schrittmotor läuft langsam
Joystick wird stark aus der Neutralposition ausgelenkt Schrittmotor läuft schnell

Am Anfang eine Referenzfahrt machen damit die Steuerung weiß wo der Schrittmotor steht
Wenn ein Endschalter betätigt wird Motor anhalten auch wenn Joystick den Befehl "fahren" vorgibt.

Das ganze für X-Achse und für Y-Achse?
Ist die Funktionalität so richtig beschrieben?

viele Grüße Stefan

Hallo Falke,
ich kann auch kein italienisch; habe mal ein paar Zeilen übersetzt (deepl liefert manchmal lustige Ergebniss).
Es scheint mir aber so, als sei der Sketch für zwei Achsen. Wenn Du nur Z ansteuern willst hast Du vermutlich eine der beiden stillgelegt.
Dann wäre es schön, wenn Du Deinen Sketch (noch ohne Endschalter) bereitstellst.

Nixdestotrotz hier ein paar Hinweise zum Einbau der Schalter in diesen Code:

  • Vor setup() gehören die Pin-Definitionen (wo die Schalter angeschlossen sind) und ggf. auch noch (globale) Variablen, die den Zustand aufnehmen
  • In loop() wird jetzt der Jopystick gelesen - da auch die Endschalter lesen (die sind aber digital)
  • In der Motorsteuer-Funktion kann dann auf die Schalter reagiert werden.

Hier das Ergebnis - minimal invasiv, mit maximal sprechenden Namen und ohne möglichst “kurzen” Code haben zu wollen.
ACHTUNG: Das nicht getestet und natürlich technisch Schwachsinn, weil beide (X und Y) beim Auslösen egal welchen Schalters angehalten werden.

/*
  Controllo di due motori passo passo con Arduino e un Joystick

  Autore  : Andrea Lombardo
  Web     : http://www.lombardoandrea.com
  Post    : http://wp.me/p27dYH-KQ
*/

//Inclusione delle librerie
#include <AccelStepper.h>
#include <Bounce2.h>

//definizione delle costanti dei pin di Arduino
// Definition der Arduino-Pin-Konstanten
const int ledEnable = 13; //il led on board ci mostrerà lo stato di attivazione dei motori
                          // die Bordkarte zeigt uns den Aktivierungsstatus der Triebwerke
const int pinSwEnable = 7;  //il bottone presente nel modulo joystick che abilita o disabilita il controllo
                            // die Taste im Joystick-Modul, die die Steuerung aktiviert oder deaktiviert
const int pinEnable = 8;  //i pin che comandano lo stato ENABLE dei driver A4988 sono in collegati in serie per questo basta un solo pin per gestirli entrambi
                          // Die Pins, die den ENABLE-Status der A4988-Treiber steuern, sind in Reihe geschaltet, so dass Sie nur einen Pin benötigen, um beide zu verwalten.

unsigned long debounceDelay = 10; //millisecondi per il debonuce del bottone
                                  // Millisekunden für die Knopfentgratung

const int jX = A0;  //pin analogico che legge i valori per le X
                    // analoge Pin-Lesewerte für Xs
const int stepX = 3;  //pin digitale che invia i segnali di STEP al driver delle X
                      // digitaler Pin, der STEP-Signale an den X-Treiber sendet
const int dirX = 4; //pin digitale che invia il segnale DIREZIONE al driver delle X
                    // digitaler Pin, der das DIRECTION-Signal an den X-Treiber sendet
long speedX, valX, mapX;  //variabili di gestione movimenti motore X
                          // X Variablen zur Steuerung der Motorbewegung

const int jY = A1;  //pin analogico che legge i valori per le Y
const int stepY = 5;  //pin digitale che invia i segnali di STEP al driver delle Y
const int dirY = 6; //pin digitale che invia il segnale DIREZIONE al driver delle Y
long speedY, valY, mapY;  //variabili di gestione movimenti motore Y

//variabili utilizzate dalla libreria AccelStepper
const int maxSpeed = 1000;  //stando alla documentazione della libreria questo valore può essere impostato fino a 4000 per un Arduino UNO
const int minSpeed = 0; //velocità minima del motore
const float accelerazione = 50.0; //numero di step al secondo in accelerazione

const int treshold = 30;  //la lettura dei potenziometri non è mai affidabile al 100%, questo valore aiuta a determinare il punto da considerare come "Stai fermo" nei movimenti
long tresholdUp, tresholdDown;  //variabili di servizio per espletare il compito descritto sopra

boolean abilitato, muoviX, muoviY, enable;  //variabili di gestione dei movimenti

Bounce btnEnable = Bounce();  //istanzia un bottone dalla libreria Bounce

//istanzia i motori
AccelStepper motoreX(AccelStepper::DRIVER, stepX, dirX);
AccelStepper motoreY(AccelStepper::DRIVER, stepY, dirY);

// Pin-Definitionen für die Endschalter
const byte pinEndSchalterOben  = 10;		// PRÜFEN, ob Pin 10 noch frei ist!
const byte pinEndSchalterUnten = 11;		// PRÜFEN, ob Pin 11 noch frei ist!
// Zustand der Endschalter
byte  zustandEndSchalterOben;
byte  zustandEndSchalterUnten;

void setup() {
  //inizializza valori
  speedX = speedY = 0;
  enable = false;

  //definizione delle modalità dei pin
  pinMode(ledEnable, OUTPUT);
  pinMode(pinEnable, OUTPUT);

  pinMode(pinSwEnable, INPUT_PULLUP); //l'input dello switch ha bisogno di essere settato come INPUT_PULLUP

  digitalWrite(ledEnable, enable);
  digitalWrite(pinEnable, !enable); //I driver A4988 disabilitano i comandi al motore se sul pin ENABLE ricevono un segnale HIGH per questo motivo il valore è opposto a quello del LED

  //configura il bottone del joystick utilizzando la libreria Bounce
  btnEnable.attach(pinSwEnable);
  btnEnable.interval(debounceDelay);

  //calcola range valori entro i quali considerare la posizione del joystick come "Stai fermo"
  tresholdDown = (maxSpeed / 2) - treshold;
  tresholdUp = (maxSpeed / 2) + treshold;

  //configura parametri dei motori
  motoreX.setMaxSpeed(maxSpeed);
  motoreX.setSpeed(minSpeed);
  motoreX.setAcceleration(accelerazione);

  motoreY.setMaxSpeed(maxSpeed);
  motoreY.setSpeed(minSpeed);
  motoreY.setAcceleration(accelerazione);

  // Konfiguration der Endschalter
  // Annahme: Die Schalter schalten nach GND (d.h. wenn geschlossen liegt GND-Pegel am Pin)
  pinMode(pinEndSchalterOben,  INPUT_PULLUP);
  pinMode(pinEndSchalterUnten, INPUT_PULLUP);
}

void loop() {

  //esegui funzione di controllo e lettura del bottone che determina lo stato di abilitazione
  checkEnable();

  digitalWrite(ledEnable, enable);  //mostra stato di abilitazione tramite il led su pin 13
  digitalWrite(pinEnable, !enable); //imposta valore opposto sui pin ENABLE dei driver

  //esegui lettura analogica dei valori provenienti dai potenziometri del joystick
  valX = analogRead(jX);
  valY = analogRead(jY);

  // Endschalter lesen
  zustandEndSchalterOben  = digitalRead(pinEndschalterOben);
  zustandEndSchalterUnten = digitalRead(pinEndschalterUnten);


  //mappa i valori letti in funzione della velocità inima e massima
  mapX = map(valX, 0, 1023, minSpeed, maxSpeed);
  mapY = map(valY, 0, 1023, minSpeed, maxSpeed);

  //esegui funzione di comando dei motori
  pilotaMotori(mapX, mapY);
}

void pilotaMotori(long mapX, long mapY) {

  if (mapX <= tresholdDown) {
    //x va indietro
    // x geht rückwärts
    speedX = -map(mapX, tresholdDown, minSpeed,   minSpeed, maxSpeed);
    muoviX = true;
  } else if (mapX >= tresholdUp) {
    //x va avanti
    // x geht weiter
    speedX = map(mapX,  maxSpeed, tresholdUp,  maxSpeed, minSpeed);
    muoviX = true;
  } else {
    //x sta fermo
    // x bleibt stehen
    speedX = 0;
    muoviX = false;
  }

  if (mapY <= tresholdDown) {
    //y va giù
    speedY = -map(mapY, tresholdDown, minSpeed,   minSpeed, maxSpeed);
    muoviY = true;
  } else if (mapY >= tresholdUp) {
    //y va su
    speedY = map(mapY,  maxSpeed, tresholdUp,  maxSpeed, minSpeed);
    muoviY = true;
  } else {
    //y sta fermo
    speedY = 0;
    muoviY = false;
  }

  // einer der Endschalter hat ausgelöst - anhalten
  if ((zustandEndschalterOben == LOW) || (zustandEndschalterUnten == LOW)) {
    speedX = 0;
    muoviX = false;
    speedY = 0;
    muoviY = false;
  }

  if (muoviX) {
    motoreX.setSpeed(speedX);
    motoreX.run();
  } else {
    motoreX.stop();
  }

  if (muoviY) {
    motoreY.setSpeed(speedY);
    motoreY.run();
  } else {
    motoreY.stop();
  }
}


void checkEnable() {

  btnEnable.update();

  if (btnEnable.fell()) {
    enable = !enable;
  }

}

Gruß Walter