Steuerung eines Kamerasliders

Fototobi94:
Selbsthemmend bedeutet, dass sich der Schlitten ohne die Drehung der Gewindestange nicht verschieben lässt. Schneckenradgetriebe sind auch selbsthemmend. Das hat nichts mit Schwergängigkeit zu tun.

Ich verstehe diese Bedenken auch nicht. Das Drehmoment deines Motors kann ich jetzt nicht einschätzen, aber im Prinzip ist das überhaupt kein Problem. Ich habe das schon oft gemacht (nicht mit dem Arduino). Mit den Standard L293/L298 Treibern und 08/15 Schrittmotoren. Da braucht es nichts besonders dazu.

Wenn es sehr schnell gehen muss und man viel Masse bewegen muss ist das was anderes. Wobei bei der maximalen Geschwindigkeit natürlich auch die Steigung des Gewindes eine Rolle spielt.

Das kann ich doch über zwei while-Schleifen lösen, oder nicht?

Auf dem Arduino ist es generell besser man verwendet loop() als Schleife und macht if-Abfragen. Dann kann man noch andere Dinge tun. Wenn du wirklich nur fahren willst, dann tut es auch while.

Hallo,
ich kenne die "Accelstepper" nicht.
Laufen denn diese Beispiele bei Dir sauber durch?
http://www.airspayce.com/mikem/arduino/AccelStepper/examples.html

Wenn nicht, dann hast Du im Sketch einen Fehler.
Die Beispiele sollten schon laufen.
Gruß und Spaß
Andreas

Hallo,

wenn du mit "Arduino Accelstepper" suchst, gibts eigentlich paar brauchbare Seiten in deutsch.

Wenn du einen Motortreiber hast, mit Takt und Richtungseingang, dann brauchste jedoch das alles nicht.
Im Grunde programmierst du dir einen LED-Blinker mit variabler Ein/Aus Zeit. Wobei Ein/Aus immer gleich lang ist, also symmetrisch. Damit steuerst du später die Geschwindigkeit in bestimmten Grenzen, weil das der Takt ist.

Dann brauchst du noch einen links/rechts Enable Ausgang bzw. ist das manchmal auch einer zusammengefasst der zwischen Low/High unterscheidet.

Mit dem Takt zählst du noch einen Variable. Also deine Schritte. Mit links enable runter. Mit rechts enable hoch. Zum Bsp. Somit weist du immer wo die gerade stehst. Die nullst du am Anfang beim Homing (Referenzfahrt) oder zwischendurch bei Bedarf, wenn Encoderfehler kommt (falls vorhanden) oder sonstiges.

Wenn du nicht auf Referenzfahrt bist, kannste diesen "Home-Sensor" als einen Begrenzungssensor ansehen. Du brauchst also nur jeweils einen Sensor pro Seite, Die schalten im Normalbetrieb den Takt ab. Also Enable aus. Not-Aus sozusagen.

Beim Homing mußte eine gewisse Schalthysterese beachten/berücksichtigen. Mußte dann für dich festlegen welche Flanke deine Null wird. 2x am Sensor hin/her fahren ist eigentlich normal. Vielleicht kannste die Sensoren ganz modern ausführen. Hallsensor mit kleinen Magnet. TLE4905L und Magnet Südpol zeigt zum Sensor. Ich spiele gerade damit rum, deshalb die Erwähnung. Gabellichtschranke geht natürlich auch.

SkobyMobil:
Hallo,
wenn es dieser Motor ist, dann muß dein Schlitten ziemlich klein sein.
Das Ding hat keine Kraft, es sei denn, es hängt ein Getriebe an der Welle. Das würde auch Deine
falschen Schritte erklären.

Hallo,
das kann ich aus der Praxis bestätigen. Horizontal slides sind kein Problem, sobald aber vertikal in Spiel kommt um die 45° ist Tutti... (Zu wenig Kraft, zum Pos. halten, bzw eine DSLR hochschleppen)
Ich bin mittlerweile wieder auf ein Getriebemotor gewechselt, der lächelt nur über mein DSLR :slight_smile:

Ich würde dir vorschlagen mach ein Proto-Aufbau und kucke ob er deine Kamera packt.
Erspart einen haufen Frustmomente :slight_smile:

Das kann ich doch über zwei while-Schleifen lösen, oder nicht?

Schleifen-Alarm:
Bei der Arduino-Programmierung ist eine Schleife schon vorgegeben, die heisst loop().

Alles andere legt den Verdacht auf falschen Denkansatz nahe.

Hallo,
ich weiß ja nicht…
Wenn ich das richtig verstanden habe, dann nutzt Du eine gemeine M8 Gewinde-
Stange. Länge 1000mm, Fahrweg 950mm.
Für diesen Weg brauchst Du 152000 Schritte.

Kann es sein, das Du diese in Deinem Sketch falsch deklariert hast. In den
Sketchen hier, taucht "xxxStep" als "Int" auf.

Mit Deinen Schritten fliegst Du da ganz schnell aus dem Wertebereich raus.
Kann es sein, das da etwas in Deinen Berechnungen nicht stimmt?

"stepper.move(200) und dahinter stepper.run()"
Kann es sein das dort "steppers.moveTo(200)" stehen sollte?

Müßte das nicht so aussehen?

void loop()
{
stepper.moveTo(500);
while (stepper.currentPosition() != 300) // Full speed up to 300
stepper.run();
stepper.runToNewPosition(0); // Cause an overshoot then back to 0
}

Du kommst hier auch mit nichts rüber, wie wäre es denn mal mit dem Sketch
und ein Foto/Schaltplan von der Verdrahtung?
Und vermeide bitte das Wort "Hemmung" in Verbindung mit einer M8-Gewindestange.
Gruß und Spaß
Andreas

Die 'Verdrahtung' der Kamera ist simpel geklärt und hatte ich denke ich auch im Eingangspost geschrieben. Es muss nur ein Pin zum Auslösen auf High geschaltet werden. Über ein Reed-Relais wird dann die Kamera ausgelöst. Man muss da kein Signal programmieren o.ä..

Der Ablauf sollte auch wie am Anfang beschrieben folgender sein:
Fahren, Kamera auslösen und Warten, Fahren usw.

Die Zeit, bei der der Kamera Pin auf HIGH ist, möchte ich später mit einem Encoder einstellen, da sich immer verschiedene Belichtungszeiten ergeben und ich auch mal mehr Zeit zwischen den Fotos brauche.

Ich bin bisher mit diesen Befehlen ganz gut klar gekommen. MoveTo bewegt den Stepper zu einer neuen (absoluten) Zielposition, Während move den Stepper eine bestimmte Schrittzahl weiterdreht.

Mit diesem Code kann ich den Motor eine Umdrehung mit Beschleunigung und Abbremsen drehen. Zwischendurch steht der Motor eine Sekunde.

#include <AccelStepper.h>

#define stepPin 3 //deklariert StepPin des DRV8825
#define dirPin  2 //deklariert dirPin  des DRV8825
long steps = 200; // 1600 Schritte pro durchlauf, später mit Encoder ausgelesen
int microstep = 8; //DRV8825 im 1/8-Schritt Modus

// Define a stepper and the pins it will use
AccelStepper stepper(1, stepPin, dirPin); //erstellt Accelstepper-Objekt mit namen 'stepper'

void setup(){  
  stepper.setMaxSpeed(2000); //maximale geschwindigkeit 
  stepper.setAcceleration(1000); //Beschleunigung
}

void loop(){    
  stepper.move(steps*microstep); //Schritte, die gefahren werden berechnen
  stepper.runToPosition(); //Schritte fahren
  delay(1000);
}

Theoretisch reicht dieser Code und wird jetzt um die Endschalter, Richtungsangaben und Encoder erweitert. Oder was meint Ihr?

P.S.: Sind denn Bilder gewünscht? Was wollt Ihr genau sehen? Kann auch ein Video machen.

Hallo,
in Deinem letzten Post lief es ja noch nicht…

"Ich weiß nur nicht richtig, wie der Motor mit Accelstepper richtig angesteuert wird. stepper.move(200) und dahinter stepper.run() reicht nicht aus, dass der Motor 200 Schritte macht."

Wenn es jetzt läuft braucht es keine Bilder/Sketch mehr. Du kannst es also
Stück für Stück erweitern.
Gruß und Spaß dabei
Andreas

Fototobi94:
Komisch: Wenn ich den StepPin und den DirPin tausche, macht der Motor genau das Selbe.

Das sehe ich als Hinweis auf irgendeinen Fehler.

Ich habe meinen unbelasteten Schrittmotor (NEMA-17 200 steps/rev, 12V 350mA) an DRV8825 und UNO angeschlossen. Wenn ich da DIR und STEP vertausche, dreht sich da nichts. Außerdem macht er eine Umdrehung bei 200 Impulsen. Das Signal sieht so aus:
Accelstepper.png
Oben STEP (20µs HIGH), unten DIR konstant auf HIGH.

Ich habe es heute endlich mal wieder an den Arduino geschafft. Ich versuche jetzt, einen Encoder auszulesen um die Anzahl der Schritte vorzugeben. Das Encoder Basic tutorial habe ich verstanden und es funktioniert auch ganz super (außer, dass der Arduino bei einem Encoderschritt immer 4 hochzählt).

Wenn ich den Code in mein Programm übertrage funktioniert das ganz schlecht. Ich kann den Encoder drehen wie verrückt, aber ich komme maximal auf 8. Der Motor bewegt sich dementsprechend.

Was muss ich ändern?

#include <AccelStepper.h>
#include <Encoder.h>

#define stepPin 3 //deklariert StepPin des DRV8825
#define dirPin  2 //deklariert dirPin  des DRV8825
#define EncoderPinA 6 //deklariert Encoder Pin A
#define EncoderPinB 7 //deklariert Encoder Pin B

int microstep = 8; //DRV8825 im 1/8-Schritt Modus

long altePosition = 0;

// Definiert Stepper und die benutzten Pins
AccelStepper stepper(1, stepPin, dirPin); //erstellt Accelstepper-Objekt mit namen 'stepper'

//Definiert Encoder und die benutzen Pins
Encoder Schritte(EncoderPinA, EncoderPinB);

void setup(){
  stepper.setMaxSpeed(800*microstep); //maximale geschwindigkeit 
  stepper.setAcceleration(300*microstep); //Beschleunigung
  Serial.begin(9600);
}

void loop(){    
  long neuePosition = Schritte.read();
  if (neuePosition != altePosition){
    altePosition = neuePosition;
  }
  
  stepper.move(neuePosition*microstep); //Schritte, die gefahren werden berechnen
  stepper.runToPosition(); //Schritte fahren
  Serial.println(neuePosition);
}

Über das Thema Gabellichtschranke habe ich mich mit meinem Berufsschullehrer unterhalten. Er sagt, dass auch Umgebungslicht die Lichtschranke schon beeinflussen kann. Aber wenn ich das Signal über einen analogen Eingang auslese und einen minimalen Wert einstelle, müsste das Problem doch behoben sein, oder?

Zum Encoder kann ich nichts sagen, da müßte man alle beteiligten Bibliotheken abklopfen, welche Timer, Interrupts etc. die verwenden.

Lichtschranken kann man mit Pulsen ansteuern, die unterscheiden sich deutlich von Umgebungslicht. So wird das bei IR-Fernbedienung gemacht.

DrDiettrich:
Zum Encoder kann ich nichts sagen, da müßte man alle beteiligten Bibliotheken abklopfen, welche Timer, Interrupts etc. die verwenden.

Lichtschranken kann man mit Pulsen ansteuern, die unterscheiden sich deutlich von Umgebungslicht. So wird das bei IR-Fernbedienung gemacht.

Macht es Sinn, im Loop nur die Variablen auszulesen und die Motorsteuerung in einem weiteren Loop (Void Motor) laufen zu lassen? Dann läuft es doch gretrennt voneinander und die Variablen können jederzeit ausgelesen werden. Während der Motor läuft, hält der Sketch nämlich an, glaube ich.

Für die Gabellichtschranke bräuchte ich dann auch für die IR-LED einen Pin, den ich vielleicht 4x pro Sekunde HIGH und LOW schalte und dann dieses Signal abfrage?

Hallo,

„Während der Motor läuft, hält der Sketch nämlich an, glaube ich.“

Vielleicht hilft es Dir ein wenig weiter…

void setup()
{
Serial.println(„Start Loop“);

Dein Code

Serial.println(„Ende Loop“);
}

Wenn Du jetzt etwas in Deinem Sketch machst, kannst Du sehen wo es- wann, zu Störungen
kommt.
Gruß und Spaß
Andreas

@Fototobi94: Ich habe heute einen Kameraslider in Aktion gesehen, war aber nur ein mit Hand bewegter.

Fototobi94:
Macht es Sinn, im Loop nur die Variablen auszulesen und die Motorsteuerung in einem weiteren Loop (Void Motor) laufen zu lassen? Dann läuft es doch gretrennt voneinander und die Variablen können jederzeit ausgelesen werden. Während der Motor läuft, hält der Sketch nämlich an, glaube ich.

Da der Arduino kein Parallelprozessing kann, geht das so nicht. Er würde entweder die Sensor-Loop oder die Motor-Loop ausführen. Du kannst aber beides zusammen packen. Du programmierst verschiedene Intervalle ein. Er bewegt den Motor alle 2sec.. Die Tasten fragt er 10x in der Sekunde ab. Den Endschalter kontrolliert er vor jedem Schritt. Du solltest dir dazu das Beispiel BlinkwithoutDelay anschauen und zum Verständnis um eine zweite Led mit anderem Blinkrythmus ohne Verwendung von Delay erweitern.

Hallo,

was Tobi machen sollte ist ...

a) Ablaufplan erstellen
b) millis anwenden können

Bsp. #21 Kurvenlicht fürs Auto - Lichter ein und ausdimmen - Deutsch - Arduino Forum
die 3 Funktionen in der loop werden permanent abgeackert.

Wenn das Programm jederzeit auf neue Eingaben reagieren kann, dann ist das quasi parallele Abarbeitung.

Oder es läuft wieder auf einen Zustandsautomaten hinaus. Läuft auch permanent durch. Dafür liefert dir sicherlich agmue seine Bsp. und Link.

Ohne klaren Ablaufplan dauerts länger ...

agmue:
@Fototobi94: Ich habe heute einen Kameraslider in Aktion gesehen, war aber nur ein mit Hand bewegter.

Es gibt ja fertige Kameraslider zu kaufen, die kosten aber um die 1000€ -> Hier z.B.

Ich bin Ab Samstag im Urlaub, werde mir aber Lektüre mitnehmen und mir Blinken ohne delay anschauen. Das Grundprinzip hatte ich schon verstanden, aber ich weiß noch nicht richtig, wie ich es auf meinen Code übertrage.

Anstatt also per delay() zu warten, läuft der Sketch weiter und wenn die Differenz zwischen millis() und einer Variable x gleich (zum Beispiel) 10000 ist (für 10 Sekunden) dann schaltet der Kamerapin HIGH und eine halbe Sekunde später wieder LOW. Wie mache ich das, dass sich der Motor in der Zeit nicht bewegt?

Den Ablauf schreibe ich hier nochmal strukturiert:

  • Encoder 1: Schritte Auslesen

  • Encoder 2: Zeitintervall auslesen (gerne auch zwei Variablen mit einem Encoder)

  • Startknopf (rastend): Steuerung starten (Kann auch ohne Arduino eingebaut werden, oder nicht?)

  • SMS (Shoot - Move - Shoot) Modus

  • Kamera auslösen und Zeitintervall abwarten

  • Motor Bewegen

  • Kamera auslösen usw.

  • Endschalter Links (Gabellichtschranke)

  • Endschalter Rechts (Gabellichtschranke)

Die Schritte und Zeitintervalle sollten auch während des Betriebs eingestellt werden können und auf einem Display angezeigt werden. Das Display schalte ich höchstens manuell aus um Strom zu sparen.

Ich hoffe, dass das verständlich ist. Sonst fragt mich einfach, ich versuche es dann genauer zu erklären.

Fototobi94:
Anstatt also per delay() zu warten, läuft der Sketch weiter und wenn die Differenz zwischen millis() und einer Variable x gleich (zum Beispiel) 10000 ist (für 10 Sekunden) dann schaltet der Kamerapin HIGH und eine halbe Sekunde später wieder LOW. Wie mache ich das, dass sich der Motor in der Zeit nicht bewegt?

In dem du vorher den Motor stoppst? Dann auslöst? Und nachher wieder in Gang setzt?

Du benutzt doch einen Schrittmotor, der sich nicht bewegt ohne, dass du ihn aktiv ansteuerst.

Doc_Arduino:
Oder es läuft wieder auf einen Zustandsautomaten hinaus. Läuft auch permanent durch. Dafür liefert dir sicherlich agmue seine Bsp. und Link.

Das hatte ich schon mal gemacht, fand aber nicht so den Anklang (Stand 24.4.2016):

#include <AccelStepper.h>

#define TASTERpin  2
#define STEPpin  8
#define DIRpin   9
#define AusloeserPin 13
AccelStepper Xaxis(1, STEPpin, DIRpin);
const unsigned long ruhe = 1000, aufnahme = 100, pause = 500;
unsigned long aktMillis, fotoMillis;
long pos;
enum {WARTEN, BEWEGUNG, BERUHIGUNG, AUFNAHME, PAUSE};
const byte maxZ = 5;
byte zaehler, zustand = WARTEN;

void setup() {
  Serial.begin(9600);
  Serial.println("Anfang");
  pinMode(TASTERpin, INPUT_PULLUP);
  pinMode(AusloeserPin, OUTPUT);
  Xaxis.setMaxSpeed(500);
  Xaxis.setAcceleration(500);
}

void loop() {
  aktMillis = millis();
  switch (zustand) {
    case WARTEN:
      if (digitalRead(TASTERpin)) {
        pos = analogRead(A0);
        Serial.print("pos: ");
        Serial.println(pos);
        Xaxis.move(pos);
        zustand = BEWEGUNG;
      }
      break;
    case BEWEGUNG:
      if (Xaxis.distanceToGo() == 0) {
        fotoMillis = aktMillis;
        zustand = BERUHIGUNG;
      }
      break;
    case BERUHIGUNG:
      if (aktMillis - fotoMillis >= ruhe) {
        digitalWrite(AusloeserPin, HIGH);
        fotoMillis = aktMillis;
        zustand = AUFNAHME;
      }
      break;
    case AUFNAHME:
      if (aktMillis - fotoMillis >= aufnahme) {
        digitalWrite(AusloeserPin, LOW);
        fotoMillis = aktMillis;
        zustand = PAUSE;
      }
      break;
    case PAUSE:
      if (aktMillis - fotoMillis >= pause) {
        zaehler++;
        zaehler = zaehler % maxZ;
        if (!zaehler) {
          Serial.println("Fertig, warten auf neuen Zyklus.");
          zustand = WARTEN;
        } else {
          Xaxis.move(pos);
          zustand = BEWEGUNG;
        }
      }
      break;
  }
  Xaxis.run();
}

Hallo,

für die Steuerung brauchst du Variablen für die Zustände. Sprich, du baust dir einen Zustandsautomaten. :wink:
Der Code von agmue sieht doch gut aus. Haste dir den wenigstens mal angesehen? Wäre Schade drum wenn nicht.
In Ruhe durch ackern bist du weist was er macht. Ausdrucken, Notizen reinmalen etc. ...

Bei Deinem Encoder müßte man erstmal schauen was er für Signale liefert um damit sinnvoll arbeiten zu können.
Hast du überhaupt einen Encoder dran? Wenn ich den Thread überblicke hast du doch gar keinen?

Wünsche erstmal angenehmen Urlaub.