Go Down

Topic: Stepper fährt zu weit oder zu kurz ? Endschalter Gabellichschranke ? (Read 687 times) previous topic - next topic

achimmcgyver

Hallo zusammen,bin noch Anfänger mit 55 und tu mich schwer mit den ganzen Begriffen.Ich glaube ich lern das nicht mehr,sorry.
Also ich möchte eine Schleifmaschine für  Eishockeyskates bauen.Die Führung mit einem Nema23 ist ca 50cm lang und darauf befindet sich ein kleiner Gleichstrommotor der mit 24V läuft.Mein Problem ist das der Motor auf der Führung nicht ganz an das rechte und linke Ende fährt.Das hängt wohl mit der Drehrate des Nema zusammen.Mir fehlen eben 14cm Fahrweg insgesamt.So nun kann ich des Sketch ja so programmieren das der Motor über die ganze länge fährt und dann aber anschlagen würde.Da helfen wohl nur Endschalter.Hab das mit einer Gabellichtschranke( TCST2103 ) probiert doch die zeigt keine Reaktion.
Als Test habe ich eine Led an 13 des Arduino gesteckt und die leuchtet auch auf wenn ich die Lichtschranke mir einem Stück Papier teste,aber leider kümmert das den Nema nicht.
Also nochmal.
Motor soll einmal nach rechts die ganze Länge fahren dann an Endschalter und gleich wieder zurück an Anfang und stehen bleiben.


Hoffe es kann mir jemand helfen danke.

Code: [Select]
int sensorPin = A2;
int ledPin = 13;
int tasterPin = 11;
int Index;

Void setup ()
int sensorPin = 2;
int ledPin = 13;
int tasterPin = 11;
int Index;

void setup() {
pinMode(ledPin, OUTPUT);
pinMode(sensorPin, INPUT_PULLUP);
pinMode(6, OUTPUT); //Enable
pinMode(5, OUTPUT); //Puls
pinMode(4, OUTPUT); //Direction
pinMode(tasterPin, INPUT);
Serial.begin(9600);
attachInterrupt(0, Endschalter, FALLING);    // Interrupt0 wird bei fallender Flanke auf Pin2
}

void loop() {
digitalWrite(ledPin, LOW);
if (digitalRead(tasterPin) == HIGH) {
  digitalWrite(4, LOW);
  for (Index = 0; Index < 31000; Index++)
  {
    digitalWrite(5, HIGH);
    delayMicroseconds(300);
    digitalWrite(5, LOW);
    delayMicroseconds(300);
  }
  delay(1000);
}
}

void Endschalter () {
digitalWrite(ledPin, HIGH);

digitalWrite(4, HIGH);
for (Index = 0; Index < 31000; Index++)
{
  digitalWrite(5, HIGH);
  delayMicroseconds(500);
  digitalWrite(5, LOW);
  delayMicroseconds(500);
}
delay(1000);[code]

Tommy56

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.

Außerdem entferne bitte die unnötigen Leerzeilem und formatiere den Code ordentlich (<Strg>+T in der IDE hilft Dir dabei).

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

HotSystems

Gibt es für deinen Thread auch einen Titel, der besser zu einem Arduino-Problem passt.
Dann könnte man den Thread auch besser finden.
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

MicroBahner

#3
Mar 19, 2020, 04:27 pm Last Edit: Mar 19, 2020, 04:44 pm by MicroBahner
Ja, Titel ist reichlich nichtssagend. Den solltest Du mal ändern. Etwa 'Stepper bleibt am Endschalter nicht stehen' oder so ähnlich.

Auch ein paar Kommentare in deinem Sketch wären sehr hilfreich. Aber nicht kommentieren, was die jeweilige Anweisung macht - das sehen wir auch so. Schreibe dazu was Du damit bezwecken willst.

Zum Einen: Dein Interrupt ist unnötig, und vollkommen falsch eingesetzt. Eine Interruptroutine muss immer möglichst kurz sein, und darf auch prinzipiell kein delay() enthalten.
Den Endschalter musst Du direkt im loop abfragen.

Zum anderen: Die for-Schleife ist auch fehl am Platz. Du hast mit 'loop' bereits eine Schleife - die ist vollkommen ausreichend.

Vorschlag ( wenn Du bei deinem Weg ohne Stepper-Lib bleiben willst und auch keine Rampen brauchst ):
Grundstellung ist dein Endschalter. Sobald der Taster gedrückt wurde, fährst Du deine 20000 Steps ( oder eben so viele wie Du bis zum Ende brauchst ) in die eine Richtung. Die Steps zählst Du im loop mit.
Sind die 20000 Steps erreicht, änderst Du die Drehrichtung, und fährst solange, bis der Endschalter wieder aktiv ist. Dann bist Du wieder am Ausgangspunkt.

In etwa nach dem Prinzip ( ungetesteter Peudocode ):
Code: [Select]
void loop() {
  if (digitalRead(tasterPin) == HIGH) {
    startFlag = true;       // Merken, dass der Taster gedrückt wurde und die Bewegung gestartet ist
    vorwaerts = true;       // Stepper dreht zunächst in Vorwärtsrichtung
    Index = 0;
    digitalWrite(dirPin , LOW );
  }
  if ( startFlag ) {
    // mach einen Step
    digitalWrite(5, HIGH);
    delayMicroseconds(500);
    digitalWrite(5, LOW);
    delayMicroseconds(500);
    if ( vorwaerts ) {
      // in Vorwärtsrichtung zähle die Steps
      if ( ++Index > 20000 ) {
        // nach 2000 Steps umkehren
        vorwaerts = false;
        digitalWrite(dirPin , HIGH );
      }
    } else {
      // in Rückwärtsrichtung warte auf Endschalter
      if ( digitalRead( Endschalter ) == LOW ) {
        // Wenn Endschalter erreicht, bewegung stoppen
        startFlag = false;
      }
    }
  }
}

Beim Zurückfahren macht es gegebenenfalls Sinn, die Steps auch mitzuzählen, damit der Stepper bei Ausfall des Endschalters nicht ewig dreht. Und im Setup musst Du dann noch kontrollieren, ob der Stepper am Endschalter steht, und ihn gegebenenfalls dorthin fahren.

Edit: Code korrigiert ( ist aber immer noch 'roh' und ungetestet ;) )
Gruß, Franz-Peter

melez

Du hast einen Schrittmotor, keinen Gleichstrommotor, oder?
Und nach 20.000 Schritten hat er eine Strecke von 36cm (50cm-14cm) geschafft, oder?
Dann lasse ihn halt gute 27.000 Schritte fahren und fertig. Kannst dir die Lichtschranke sparen.

Übrigens:
In einer ISR darfst du keine Delay verwenden.
Siehe: https://www.arduino.cc/reference/de/language/functions/external-interrupts/attachinterrupt/

achimmcgyver

Hallo und erst mal danke für die vielen Infos.
Hab mir schon gedacht das ich viel falsch gemacht habe.
Das mit dem Code richtig darstellen muss ich noch üben aber ich habs einfach reinkopiert.
Die Überschrift ist Misst ja sehe ich ein.
Dann hab ich einen Gleichstrommotor (7000U/min 24V) auf dem sitzt die Diamantschleifscheibe mit 40mm Durchmesser und natürlich einen Nema 23.
Mit Stepps meint ihr pro 360° also wieviel mal der sich dreht ? Ok.
Ich habe in der Zeile "Index" bis 31000 eingestellt dann ist Schluss.Der Schlitten fährt exakt immer haargenau 80mm bis Ende recht und links.Wenn ich mehr wie 31000 einstelle fährt er drüber.Deswegen einen Endschalter.

Wie kann ich den Titel noch ändern ?

HotSystems

Beides, Sketch in Code-Tags und Titel, kannst du noch nachträglich ändern und das solltest du auch aus den schon geschriebenen Gründen machen. Wie das geht, wurde ja geschrieben.
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

MicroBahner

Wenn ich mehr wie 31000 einstelle fährt er drüber.Deswegen einen Endschalter.
Mit
Code: [Select]
int Index;hast Du einen Zahlenbereich von -32768 ... 32767. Wenn Du darüber hinausgehst gibt's unvorhergesehene Ergebnisse. Ansonsten musst Du mit der richtigen Stepzahl auch genau bis zum Ende des Schlittens fahren können. Bei zuviel geht's natürlich darüber hinaus.
Du kannst natürlich auch an beiden Enden einen Endschalter anbauen. Dann könntest Du aber auch da einen DC-Motor nehmen und bräuchtest keinen Stepper.

Gruß, Franz-Peter

achimmcgyver

Ich glaube ich bin zu doof um das mit dem Editor hier zu posten.Kann ich den Sketch direkt einfügen ?

achimmcgyver

Mit
Code: [Select]
int Index;
hast Du einen Zahlenbereich von -32768 ... 32767. Wenn Du darüber hinausgehst gibt's unvorhergesehene Ergebnisse. Ansonsten musst Du mit der richtigen Stepzahl auch genau bis zum Ende des Schlittens fahren können. Bei zuviel geht's natürlich darüber hinaus.
Du kannst natürlich auch an beiden Enden einen Endschalter anbauen. Dann könntest Du aber auch da einen DC-Motor nehmen und bräuchtest keinen Stepper.



danke das habe ich schon gemacht.Der fährt keinen Milimeter weiter wie die 80mm vor Ende der Schiene.
Was mach ich falsch ?

HotSystems

Ich glaube ich bin zu doof um das mit dem Editor hier zu posten.Kann ich den Sketch direkt einfügen ?
Tommy hat doch geschrieben, ohne die Sterne.
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

achimmcgyver

Ja wer lesen kann ist klar im Vorteil.Sorry

HotSystems

Ja wer lesen kann ist klar im Vorteil.Sorry
Ok, hat ja jetzt funktioniert und wir können den besser lesen.

Und gleich die Anmerkung:
Warum hast du da 2 mal setup() drin ?
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

MicroBahner

danke das habe ich schon gemacht.Der fährt keinen Milimeter weiter wie die 80mm vor Ende der Schiene.
Was mach ich falsch ?
Wenn Du mehr Steps brauchst, muss Du deinen 'Index' als 'long' definieren:
Code: [Select]
long Index;
Wenn Du keine negativen Werte benötigst, reicht evtl. auch
Code: [Select]
unsigned int Index;
Dann kommst Du so etwa bis 65000.
Gruß, Franz-Peter

achimmcgyver

Ok danke werde ich testen.
Habe jetzt mal so geändert ohne Endschalter.
Code: [Select]


int tasterPin = 11;
int Index;

void setup()                                      
{                                                      
pinMode(6, OUTPUT); //Enable                                                      
pinMode(5, OUTPUT); //Puls                
pinMode(4, OUTPUT); //Direction          
pinMode(tasterPin,INPUT);

digitalWrite(6,LOW);                            
}                                                      

void loop()                                        
                                                      
{

if (digitalRead(tasterPin)==HIGH){            

 digitalWrite(4,HIGH);                            
 
 for(Index = 0; Index <30000; Index++)
  
{
 
 digitalWrite(5,HIGH);                              
 delayMicroseconds(500);                        
 digitalWrite(5,LOW);                            
 delayMicroseconds(500);                        

}
    
 delay(1000);                                      
 digitalWrite(4,LOW);                            

 for(Index = 0; Index <30000; Index++)    
{
  digitalWrite(5,HIGH);                            
  delayMicroseconds(500);                    
  digitalWrite(5,LOW);                          
  delayMicroseconds(500);                      
}
  delay(1000);
}
} [code]
[/code]

Go Up