Schrittmotor mit Accelstepper - 500 mal hin und her, danach stoppen, aber wie?

Hallo zusammen

Ich bin neu hier und hab auch noch nicht viel Erfahrung mit Arduino programmieren. Daher wäre ich echt froh um eure Hilfe.

Ich arbeite in meiner Freizeit an einem Uhrenbeweger, gesteuert durch einen Schrittmotor. Dieser ist an einem TMC2100 angeschlossen. Im Moment bin ich soweit, dass über eine Startfläche auf dem Touchscreen (touch == 2) der Motor startet und endlos hin und her schwappt. Nach jeweils zwei Umdrehungen wechselt er die Richtung, das Ganze mit Beschleunigung und Entschleunigung. Den Lauf kann stoppe ich durch eine Stoppfläche auf dem Touchscreen (touch == 1). Soweit alles ok.

Ich hätte aber gerne eine weitere Schaltfläche (hier als Touch == 3 definiert), wo der Schrittmotor die Arbeit wie oben beschrieben aufnimmt und nach 500 Wechsel selbständig stoppt. Danach soll ich die Auswahl haben, entweder diese Funktion nochmals zu starten und wieder 500 mal hin- und her schwappen oder über die Startfläche (touch ==2) den Endlosbetrieb wieder zu starten.

Ich hab alles mögliche probiert, bin schon seit ein paar Wochen hier blockiert und finde einfach keinen Weg. Könnt ihr mir bitte helfen?

Hier der Code den ich soweit mal habe. Zur besseren Übersicht hab ich mal alles herausgelöscht, was nicht direkt mit dem Schrittmotor zu tun hat.

#include <AccelStepper.h>

// Define a stepper and the pins it will use
AccelStepper stepper(AccelStepper::DRIVER, 24, 26);
const int POWER_PIN = 28; //Stromversorgung für TMC2100
int i;

void setup() {

pinMode(POWER_PIN, OUTPUT);
digitalWrite(POWER_PIN, HIGH);
 
  {
   stepper.setMaxSpeed(400);
   stepper.setAcceleration(200);
   stepper.moveTo(800);
  }
}



void loop() {
 
 TSPoint p = ts.getPoint();
 pinMode(XM, OUTPUT);
 pinMode(YP, OUTPUT);
 if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
   p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
   p.y = map(p.y, TS_MINY, TS_MAXY, tft.height(), 0);
   Serial.print("("); Serial.print(p.x);
   Serial.print(", "); Serial.print(p.y);
   Serial.println(")");
   if (p.x > 130 && p.x < 250) {
     if (p.y > 70 && p.y < 150) {
       touch = 1;
     }
   }
   if (p.x > 130 && p.x < 250) {
     if (p.y > 200 && p.y < 280) {
       touch = 2;
     }
   }
   if (p.x > 280 && p.x < 400) {
     if (p.y > 70 && p.y < 150) {
       touch = 3;
     }
   }
 }


 if (touch == 1) {
   motoroff();
   }

 if (touch == 2) {
   motor();
   }
 
 for (int i = 0; i <= 2; i++)  {
      Serial.println(i);
      }

 if ((touch == 3) && (i <= 500)) {
   motor();
    }
   else {
   motoroff();
   }

}
void motor()  {

 // If at the end of travel go to the other end
 if (stepper.distanceToGo() == 0)
    stepper.moveTo(-stepper.currentPosition());
 
    stepper.run();
}

void motoroff() {

 // If at the end of travel go to the other end
 if (stepper.distanceToGo() == 0)
    stepper.moveTo(800);

    stepper.run();
}

Vielen Dank im Voraus, Grüsse aus der Schweiz!
Mauro

Hi

Benutze sprechende Variablen-Namen.
In der FOR, Die nur 0-1 im seriellen Monitor ausgibt, ist 'i' ok, aber im Sketch?
Dann: Dein Sketch prüft bei touch==3, ob 'i' kleiner als 500 ist.
Mehr passiert mit 'i' aber auch nicht - hier ist Keiner, Der 'i' nach einem Schwapp um 1 hochzählt.
Weiter müsste man 'i' auch wieder auf Null setzen, wenn die Zählerei neu gestartet werden soll.

Code bitte in Code-Tags, vorher in der IDE gerne STRG+T gedrückt und unnötige Leerzeilen rausgenommen.
Die Code-Tags kannst Du jederzeit im Anfangspost 'nachrüsten'.

MfG

Versuche mal dies:

    if (p.x > 280 && p.x < 400) {
      if (p.y > 70 && p.y < 150) {
        touch = 3;
        i = 0;
      }
    }
  }

  if (touch == 1) {
    motoroff();
  }

  if (touch == 2) {
    motor();
  }

  if ((touch == 3) && (i <= 500)) {
    motor();
    i++;
  }
  else {
    motoroff();
  }
}

Hi

Das wird nicht klappen - das 'i' hochzählen muß in der motor()-Funktion gemacht werden und dort auch nur, wenn der Motor 'angekommen' ist.
So läuft die loop() 500x durch, dabei werden keine oder nur sehr wenige Steps generiert und der Motor geht auf 'motoraus()' und fährt zur End-Position 800.

MfG

....
  if (touch == 3) {
     if (i<500){
          motor();
     }else{
          motoroff();
     }
  }
....
void motor()  {
 // If at the end of travel go to the other end
 if (stepper.distanceToGo() == 0){
    stepper.moveTo(-stepper.currentPosition());
    i++;
  }
  stepper.run();
}

MfG

@Agmue, vielen Dank für den Tipp, jedoch hatte postmaster-ino recht, die Zählung musste in der Motor()Funktion geschehen, sonst zählt es einfach Vollgas hoch.

@postmaster-ino vielen lieben Dank, endlich ein Lichtblick!

Es funktioniert, jedoch muss ich nach erfolgreichem Durchlauf den Zähler i ja wieder auf null setzen, damit ich die Funktion ja auf Wunsch nochmals aufrufen kann. Hab das Eine oder Andere probiert, hatte aber keinen Erfolg. Kannst du mir zeigen, wo ich den Zähler i auf null setzen kann?

postmaster-ino:
Das wird nicht klappen -

Stimmt, danke für die Korrektur :slight_smile:

FMC72:
Es funktioniert, jedoch muss ich nach erfolgreichem Durchlauf den Zähler i ja wieder auf null setzen, damit ich die Funktion ja auf Wunsch nochmals aufrufen kann.

In #2 habe ich ein i = 0; drin, zumindest das könnte ja richtig sein, oder?

Hi

Bei touch=3 wird doch i auf 0 gesetzt?!?
(Also Da, wo der Touch erkannt wird und die Variable touch auf 3 gesetzt wird)
Das müsste doch, wenn man erneut auf dem Display die 3 tippt, klappen?

Packe Serial.print in die einzelnen IFs, damit Du im Terminal sehen kannst, wo der Arduino wie abbiegt.

MfG

Hallo agmue und postmaster.ino

Ich weiss gar nicht wie euch danken, diese paar Posts hin und her waren extrem hilf- und lernreich für mich. Mir fehlt einfach (noch) die Kreativität beim programmieren. Ich wäre nie darauf gekommen, ein i++ komplett woanders hin zu setzen.

Zur letzten Aussage/Frage von euch: Ich hatte i = 0 überall hingesetzt, nur nicht beim touch = 3. Danke agmue für den Tipp, dementsprechend @postmaster,ino: Nein, hatte ich nicht gesetzt gehabt. Hab's jetzt nachgeholt und jetzt funktioniert alles! Ich find das echt super hier, vielen lieben Dank euch beiden!!!!