Mehrere bipolar Schrittmotoren Ansteuern, aber wie ????

Hallo Leute,

Ich versuche schon seit längeren einen Sketch zu schreiben komme aber überhaupt nicht weiter.
Ich verwende hierfür 3 Stk pipolar Nema 23 Schrittmotoren, 1 Stk kapazitiven Näherungssensor und 4 Stk Enschalter.
Den Näherungssensor sowie die Endschalter habe ich angeschloßen und mit LED Schaltungen getestet, diese funktionieren, aber ich bekomme keinen sketch hin indem die Motoren damit gesteuert werden können :frowning:

Kann von euch eventuell jemand einen Sketch entwerfen der funktioniert ??
Die Motoren sollten so angesteuert werden:

Bipolar Nema 23 Schrittmotor 1 => S1 = horizontaler Linearantrieb mit 2 Stk Endschaltern
Bipolar Nema 23 Schrittmotor 2 => S2 = vertikaler Linearantrieb mit 2 Stk Endschaltern
Bipolar Nema 23 Schrittmotor 3 => S3 = Immer drehend

1.) S1 dreht im Uhrzeigersin bis vom capazitiven Näherungsensor ein Signal kommt, dannach dreht er noch zusätzlich 45° weiter und stoppt dann.
2.) S3 Schaltet sich ein und dreht im Uhrzeigersin (schaltet nicht aus)
3.) S2 dreht sich im Uhrzeigersinn bis zum Enschalter Nr S2_1 und bleibt hier für 3 Sek. stehen
4.) S2 dreht sich entgegen dem Uhrzeigersinn bis zum Enschalter Nr S2_2 und bleibt dort stehen.

Diese Schleife wird solange abgefahren bis S1 zum Endschalter Nr S1_1 kommt.

Dann wiederholen sich wieder die Punkte 1 bis 4 nur mit der Änderung das S1 jetzt entgegen dem Uhrzeigersinn dreht.

Diese Schleife wird solange abgefahren bis S1 zum Endschalter Nr S1_2 kommt.
Dann dreht sich S1 360° im Uhrzeigersinn und dann werden alle 3 Motoren abgeschaltet.

Kann mir hier jemand aus der Patsche Helfen ???

LG
Christian

Hallo Christian,
Ich kann keinen Fehler finden in dem Code den du nicht gepostest hast.

Ich bin leider immer noch sehr unerfahren im Glalskugel-Hellsehen. (Ich komme einfach nicht dazu das intensiv genug zu üben) :-)))

Ohne den Code kann ich nur einen allgemeine Hinweise geben:

mit Serial.print("1: ....")
mit Serial.print("2: ....")
usw.

jede Menge nummerierte Ausgaben einbauen zum analysieren.

Immer nur eine Sache hinzufügen und dann sofort testen ob es geht.
Damit verbraucht man etwas mehr Zeit weil man ja mehr testet. Aber man spart nachher wieder Zeit ein weil nicht so lange testet bis man einen Programmierfehler gefunden hat.
Aber es gibt eben auch Leute deren Lebensstil es ist immer ganz hektisch zu sein um ihr vorwärts kommen durch viele Hektikfehler runterzubremsen ;-)))

viele Grüße Stefan

Hallo Stefan,

Danke für dein Feedback.
Bei diesem Code sind 2 Schrittmotoren angeschloßen.
S1 = großer Motor, S2 = kleiner Motor

S1 sollte sobald der Kapazitive sensor anspringt abschalten, dies macht S1 jedoch nicht, er dreht munter weiter warum ?

Wie kann ich den Code am besten mit den eilen nummern einfügen ???

Hier der Code

//S1 grosser Motor
//S2 kleine Motor

int Index;
int PUL_S1 = 31;   
int DIR_S1 = 33;
int ENA_S1 = 35;

int DIR_S2 = 4;
int PUL_S2 = 5;   
int ENA_S2 = 6;

int S1_Pause =800;
int S2_Pause =800;

int sensorpin = 52;
int Endschalter_S1_A = 11;

void setup() 
{

  Serial.begin(9600);
  pinMode(sensorpin, INPUT);
  pinMode(Endschalter_S1_A,INPUT);
  pinMode(ENA_S1, OUTPUT); //Enable
  pinMode(PUL_S1, OUTPUT); //Puls 
  pinMode(DIR_S1, OUTPUT); //Direction

  digitalWrite(ENA_S1,LOW);


  pinMode(ENA_S2, OUTPUT); //Enable
  pinMode(PUL_S2, OUTPUT); //Puls 
  pinMode(DIR_S2, OUTPUT); //Direction

  digitalWrite(ENA_S2,LOW);
}



void loop() {
  
  int sensorstate = digitalRead(sensorpin);
  if (sensorstate == 1) 
  {
    Serial.println("Klinge nicht erkannt");
  } 
  else 
  {
    Serial.println("Klinge erkannt");
  }
  delay(100);


  
  digitalWrite(DIR_S1,HIGH);

  for(Index = 0; Index < 4000; Index++)

  if (sensorstate == 1) 
  {
    digitalWrite(PUL_S1,HIGH); 
    delayMicroseconds(S1_Pause); 
    digitalWrite(PUL_S1,LOW); 
    delayMicroseconds(S1_Pause); 
  }
  else
  {
    digitalWrite(ENA_S1,LOW);
  }
  delay(500);


  digitalWrite(DIR_S2,HIGH);

  for(Index = 0; Index < 800; Index++)
  {
    digitalWrite(PUL_S2,HIGH);
    delayMicroseconds(S2_Pause);
    digitalWrite(PUL_S2,LOW);
    delayMicroseconds(S2_Pause);
  }
  delay(1000);
}

LG
Christian

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

Hallo Christian,
während deiner for-Schleife:

for(Index = 0; Index < 4000; Index++)

wird der sensorpin garnicht mehr abgefragt. Damit kann sich auch sensorstate nicht mehr ändern. Deshalb dreht der Motor immer die vollen 4000 Steps, egal was am sensorpin passiert.

Du solltest erwägen, für die Ansteuerung der Steppermotore eine entsprechende ( nicht blockierende ) Lib zu verwenden ( z.B. AccelStepper oder meine MobaTools ). Das erleichtert vieles.

Deine Beschreibung verstehe ich auch nicht:

christian_auer_11:
1.) S1 dreht im Uhrzeigersin bis vom capazitiven Näherungsensor ein Signal kommt, dannach dreht er noch zusätzlich 45° weiter und stoppt dann.
...

Diese Schleife wird solange abgefahren bis S1 zum Endschalter Nr S1_1 kommt.

Wie kann S1 zum Endschalter kommen, wenn er vorher gestoppt wurde?

P.S. Du musst - wie von Tommy geschrieben - die '*' in den Code-Tags entfernen, sonst funktioniert das nicht.

Hallo Christian,

na das mit dem Code-einfügen hat ja fast geklappt keine Sternchen vor dem Wort code

hier ein um debug-output ergänzter code zum analysieren was dein code wirklich macht

//S1 grosser Motor
//S2 kleine Motor

int Index;
int PUL_S1 = 31;
int DIR_S1 = 33;
int ENA_S1 = 35;

int DIR_S2 = 4;
int PUL_S2 = 5;
int ENA_S2 = 6;

int S1_Pause = 800;
int S2_Pause = 800;

int sensorpin = 52;
int Endschalter_S1_A = 11;

void setup()
{

  Serial.begin(9600);
  pinMode(sensorpin, INPUT);
  pinMode(Endschalter_S1_A, INPUT);
  pinMode(ENA_S1, OUTPUT); //Enable
  pinMode(PUL_S1, OUTPUT); //Puls
  pinMode(DIR_S1, OUTPUT); //Direction

  digitalWrite(ENA_S1, LOW);


  pinMode(ENA_S2, OUTPUT); //Enable
  pinMode(PUL_S2, OUTPUT); //Puls
  pinMode(DIR_S2, OUTPUT); //Direction

  digitalWrite(ENA_S2, LOW);
}



void loop() {

  int sensorstate = digitalRead(sensorpin);
  if (sensorstate == 1)
  {
    Serial.println("Klinge nicht erkannt");
  }
  else
  {
    Serial.println("Klinge erkannt");
  }
  delay(100);



  digitalWrite(DIR_S1, HIGH);
  Serial.println("1: direkt vor for (Index = 0; Index < 4000; Index++)");

  for (Index = 0; Index < 4000; Index++)
    Serial.println("2: direkt nach for (Index = 0; Index < 4000; Index++)");

    Serial.println("3: direkt vor if (sensorstate == 1)");
    if (sensorstate == 1)
    {
      Serial.println("4: if (sensorstate == 1) ist true");
      digitalWrite(PUL_S1, HIGH);
      delayMicroseconds(S1_Pause);
      digitalWrite(PUL_S1, LOW);
      delayMicroseconds(S1_Pause);
      
    }
    else
    {
      digitalWrite(ENA_S1, LOW);
      Serial.println("5: if (sensorstate == 1) ist false ==> else digitalWrite(ENA_S1, LOW);");
    }
  delay(500);


  digitalWrite(DIR_S2, HIGH);

  Serial.println("6: direkt vor for (Index = 0; Index < 800; Index++)");
  for (Index = 0; Index < 800; Index++)
  {
    Serial.println("7: for (Index = 0; Index < 800; Index++)");
    digitalWrite(PUL_S2, HIGH);
    delayMicroseconds(S2_Pause);
    digitalWrite(PUL_S2, LOW);
    delayMicroseconds(S2_Pause);
  }
  delay(1000);
}

die einfachste Variante Code als Code-section im Forum zu posten ist
Rechtsklick in der Arduino-IDE und "für Forum kopieren" auswählen

dann im Forums-Textfenster einfügen.
viele Grüße Stefan

Hallo Stefan,
vorsicht, deine Ausgaben verändern den Ablauf vollständig, da Christian nach der for-Schleife keine {} gesetzt hat ( was man eigentlich IMMER machen sollte !). Dadurch gehört jetzt nur noch das erste Serial.println zur for-Schleife.

Hallo MicroBahner,

S1 fährt über eine Länge von insgesamt ca. 3m.
Der Kapazitiven Sensor Stoppt S1 auf diesen 3m ca. alle 10cm.
Erst wenn S1 am Ende angekommen ist (bei den 3m) sollte die Drehrichtung Durch den Endschalter Nr S1_1 umgekehrt werden und S1 sollte wieder die 3m Rückwärts zum Anfang fahren wobei auch beim Rückwärtsfahren S1 alle ca. 10cm vom Kapazitiven Sensor angehalten werden sollte.
Am Afang (bei 0m) fährt S1 dann gegen den Endschalter Nr S1_2.

LG
Christian

Hallo Stefan,

habe deinen korrigierten Code auf den Arduino gespielt, funktioniert leider nicht.
Ich habe mal was von dem befehl milis gelesen, habe aber keine Idee wich ich diesen hier anwenden kann.

Meinst Du wäre das eine Idee, damit dann der Kpazitive sensor immer gelesen werden kann ??

christian_auer_11:
Der Kapazitiven Sensor Stoppt S1 auf diesen 3m ca. alle 10cm.

Und wann soll er sich wieder weiterdrehen?

christian_auer_11:
Ich habe mal was von dem befehl milis gelesen, habe aber keine Idee wich ich diesen hier anwenden kann.

Nutze eine nicht blockierende Lib für die Stepperansteuerung und lies dann den Sensor während der Bewegung aus.

christian_auer_11:
Meinst Du wäre das eine Idee, damit dann der Kpazitive sensor immer gelesen werden kann ??

Ja.

Wenn Du Eingänge abfragen willst, benötigst Du blockadearmen Code, da sind delay und blockierende Schleifen tabu.

Ich wiederhole den Tipp von #4: Verwende die MobaTools!

MicroBahner:
Und wann soll er sich wieder weiterdrehen?
Nutze eine nicht blockierende Lib für die Stepperansteuerung und lies dann den Sensor während der Bewegung aus.

Weiterdrehen sollte er sich nachdem der Schritt 4 Ausgeführt wurde.
Evtl müsste man S1 ein paar Schritte drehen lassen (ca 3cm Weglänge) damit der kapazitiven Sensor kein Signal gibt und erst dann wieder nachdem kapazitiven Sensorstatus abfragen lassen (nach ca 7 cmmüsste der Sensor wieder anspringen und S1 stoppen)

Gibt es die Moba Libary auch für bipolare schrittmotoren ? In den 2 Beispielen waren nur unipolare schrittmotoren

christian_auer_11:
Gibt es die Moba Libary auch für bipolare schrittmotoren ?

Ja, Parameter "A4988" für Treiber mit STEP und DIR. Beispiel

christian_auer_11:
Gibt es die Moba Libary auch für bipolare schrittmotoren ? In den 2 Beispielen waren nur unipolare schrittmotoren

Ein Beispiel für bipolare fehlt in der Lib leider noch, aber die Lib kann das schon. Hier ist auch noch ein anderes Beispiel aus dem Forum ( 'A4988' == 'STEPDIR' )

MicroBahner:
Ein Beispiel für bipolare fehlt in der Lib leider noch, ...

Könnte ja eventuell zusammen mit STEPDIR auf die ToDo-Liste ::slight_smile:

Steht schon drauf :wink:

christian_auer_11:
Hallo Stefan,

habe deinen korrigierten Code auf den Arduino gespielt, funktioniert leider nicht.
Ich habe mal was von dem befehl milis gelesen, habe aber keine Idee wich ich diesen hier anwenden kann.

Meinst Du wäre das eine Idee, damit dann der Kpazitive sensor immer gelesen werden kann ??

mein Beispiel ist keine Korrektur sondern dient rein der Analyse um nachzuvollziehen was in deinem Code tatsächlich passiert. Microbahner hat auf etwas wichtiges hingewiesen es gibt noch keine Klammern um den code unterhalb der For-Schleife was alles zur For-Schleife dazugehören soll.

In post #11 hast du eine detaillierte Beschreibung gemacht. Damit kann man jetzt wirklich weiterhelfen.
Aus dem Ablauf:
Wenn Anfangsschalter betätigt Motor Stop schalte auf Fahrrichtung "vorwärts"
Wenn Enschalter betätigt Motor Stop schalte Fahrtrichtung auf "rückwärts"

1.) Fahre bis kap. Sensor anspricht
2.) Anhalten
3.) Fahre weiter bis KapSensor kein Signal mehr gibt (kapSensor hat seine "Erkennungsstelle" verlassen)

evtl. kommen ja noch weitere Dinge hinzu.
Je nachdem ob für den Schrittmotor eine Drehzahl genügt mit der man ihn aus dem Stand heraus loslegen lassen kann oder ob er weiter beschleunigen soll braucht man evtl. eine weitere Unterteilung in
"Anfahren"
"Beschleunigen"
"Abbremsen"

Auch bei nur drei Schritten würde ich eine sogenannte statemachine empfehlen.

Die Abfrage der Anfangs/Endschalter und des kap-Sensors muss sozusagen nach jedem Schritt des Schrittmotors erfolgen.

@MicroBahner:
Aus der Anwendung in diesem Thread wäre toll wenn es eine konfigurierbare Funktion "Referenzfahrt" gäbe
Fahre Schrittmotor bis IO-Pin schaltet dann Drehrichtung umkehren und langsam fahren bis IO-Pin wieder zurückschaltet.

evtl. noch eine Variante
Fahre bis IO-Pin schaltet, vom Schritt an dem IO-pin geschaltet hat noch n Schritte fahren danei abbremsen und bei Schritt "n" anhalten

Das wäre super wenn es das in den MobaTools sozusagen "innen drin" gibt.
Die Alternative ist ganz viele Aufrufe
mache einen Schritt (oder ein paar Schritte) dann Sensor abfragen.
Wenn Sesor (noch) nicht geschaltet hat repeat

So was müsste doch in Modellbahnanwendungen auch vorkommen oder nicht?

viele Grüße Stefan

Hallo Stefan,

StefanL38:
Fahre bis IO-Pin schaltet, vom Schritt an dem IO-pin geschaltet hat noch n Schritte fahren danei abbremsen und bei Schritt "n" anhalten

Das wäre super wenn es das in den MobaTools sozusagen "innen drin" gibt.
Die Alternative ist ganz viele Aufrufe
mache einen Schritt (oder ein paar Schritte) dann Sensor abfragen.
Wenn Sesor (noch) nicht geschaltet hat repeat

So was müsste doch in Modellbahnanwendungen auch vorkommen oder nicht?

Ja, das kommt immer vor, wo mit dem Stepper absolut positioniert werden soll. Da die MoToStepper Klasse die Schritte im Hintergrund ausführt, dies aber auch jederzeit beeinflussbar/abbrechbar ist, braucht man für so eine Referenzfahrt gar nicht so viele Aufrufe.

Ob ich das als eigene Methode realisiere ... ich weis nicht, irgendwie braucht's dann jeder wieder ein bisschen anders ;). Was aber sicher eine gute Idee ist, sowas als Beispiel aufzunehmen. Das werde ich auf jeden Fall machen ( ich werkel eh gerade ein wenig an der nächsten Version ).

MicroBahner:
Hallo Stefan,Ja, das kommt immer vor, wo mit dem Stepper absolut positioniert werden soll. Da die MoToStepper Was aber sicher eine gute Idee ist, sowas als Beispiel aufzunehmen.

Hallo MicroBahner, meinst Du wäre meine Aufgabenstellung eventuell etwas für dein Beispiel :slight_smile: ??
Bin noch ganz neu in dem Thema mit Arduino, ohne gute Beispiele tut man sich als Anfänger relativ schwer so etwas von alleine zusammenzubringen.
Ein sanfter An bzw. Abschaltvorgang wie von Stefan beschrieben wäre auch eine tolle Ergänzung, für mein Beispiel aber nicht zwingend notwendig.

LG
Christian

christian_auer_11:
Hallo MicroBahner, meinst Du wäre meine Aufgabenstellung eventuell etwas für dein Beispiel :slight_smile: ??

Ein Beispiel mit Referenzfahrt habe ich in Arbeit, dürfte ich das in diesem Thema veröffentlichen und als Bibliotheksbeispiel vorschlagen?