Taktzeiten ohne delay realisieren

Hallo zusammen,

ich möchte in der folgenden Funktion erreichen, dass die Anzahl steps (Übergabeparameter 1) ausgeführt werden und die Zeit zwischen den Steps "takt" entspricht.... Hierbei würde ich gerne ohne delay() arbeiten und bin bei meiner Recherche auf folgendes Ergebnis gekommen:

void vorschrittHPV(long steps, long takt){
  unsigned long millisVorher = 0;
  long stepsZaehler = 0;
  if(steps > stepsZaehler){
    if(millis() > millisVorher + takt){
      digitalWrite(DIR_PIN_HPV, LOW); //Gegen den Uhrzeigersinn (UZS)
      digitalWrite(STEP_PIN_HPV, HIGH);
      digitalWrite(STEP_PIN_HPV, LOW);
      digitalWrite(DIR_PIN_HPV, HIGH);
      stepsZaehler++;
      millisVorher = millis();
    }
  }
}

... allerdings funktioniert es nicht und ich verstehe nicht wieso.
Wäre cool wenn sich hier jemand findet der ein besseres Verständnis davon hat.

Beste Grüße
Jost

achja immer das gleiche

  1. den ganzen Sketch posten.
    am schnellsten geht das mit
  • in der IDE rechtsklick mit der Maus
  • Für Forum kopieren auswählen
  • zum posting wechseln
  • Strg-V drücken

Damit Berechnungen mit millis() auch dann funktionieren wenn millis() vom Maximalwert auf 0 springt (rollover)
muss man die If-bedingung so programmieren

if (  millis() - millisVorher >= takt) {
  millisVorher = millis();
  // ....
}

Wenn du gleich den ganzen Sketch gepostet hättest könnte ich jetzt selber nachsehen was für Zahlenwerte du für "takt" verwendest.
Das ist eine mögliche Fehlerquelle.

Noch eine Fehlerquelle könnte sein wo unter welchen Bedingungen rufst du die function vorschrittHPV auf

usw.

vermutlich liegt es daran dass du die Variable millisVorher in der function definierst aber ohne den Zusatz static und das du dann millisVorher auch noch auf null setzt

void vorschrittHPV(long steps, long takt){
  static unsigned long millisVorher;  // ohne auf NULL setzen!!!

Wie soll denn die Variable millisVorher einen Wert ungleich null haben wenn du sie jedesmal auf null setzt???

vgs

Hallo Jost95
Sowas gibt es fertig von der Stange.
https://funduino.de/nr-15-schrittmotor
Ich wünsche einen geschmeidigen Tag und viel Spass beim Programmieren in C++.

Hi zusammen,

erstmal vielen Dank für eure schnelle Antwort. Leider habe ich das gewünschte Ergebnis immer noch nicht erreicht.

Ich dachte es wäre so erstmal einfacher, da mein gesamter Code dann doch etwas komplexer ist. Dann werde ich jetzt trotzdem mal fürs Verständnis mein Projekt erläutern:
Der Plan ist, eine Sonnennachführung mit dazugehörigen Solartracker aufzubauen. Bei meinem jetzigen Problem fokussiert es sich aber ausschließlich auf den PV-tracker, welcher die Gradzahlen in einer bestimmten Zeit abfahren soll. Die Aktuierung erfolgt über NEMA17-Motoren (Treiber: TMC2209), welche die horizontalen und vertikalen Achsen mit der jeweiligen Übersetzung bewegen.
Bei den Funktionen findet ihr dann den bekannten Code, der die Schritte abfahren soll. Aufgerufen werden diese in der Funktion "stepsPV" (Abfahren der Sonnenstände) und "Ausgangspunkt" (Zum Ausgangspunkt fahren).

//Einbinden der Bibliotheken
#include <Arduino.h> //Für alle Arduino-sketches erforderlich
#include <TMCStepper.h> //Bibliothek für alle TMC-Stepper (Auch 2209)

// Pin-Belegung für den ersten Stepper-driver
#define DIR_PIN_VPV A1  // Richtungssignal
#define STEP_PIN_VPV A0  // Schrittsignal
#define EN_PIN_VPV 38   // Aktivierte Motorausgänge (GND = An, VIO = Aus)

// Pin-Belegung für den zweiten Stepper-driver
#define DIR_PIN_HPV A3  // Richtungssignal
#define STEP_PIN_HPV A2  // Schrittsignal
#define EN_PIN_HPV 40   // Aktivierte Motorausgänge (GND = An, VIO = Aus)

//Dauer, in der das Experiment abfahren soll
long eineMin = 60000;
long dreiMin = eineMin*3; //3 Minuten
long fuenfMin = eineMin*5; //5 Minuten
long zehnMin = eineMin*10; //10 Minuten


//Initialisieren der Ausgangspositionen
float sommerVPVAusgang = -60.00;     //VPV = Vertikale PV
float sommerHPVAusgang = -130.85;    //HPV = Horizontale PV
float sommerVSAAusgang = 0.00;       //VSA = Vertikaler Schwenkarm (Sonne)
float sommerHSAAusgang = -130.85;    //HSA = Horizontaler Schwenkarm (Sonne)

float winterVPVAusgang = -60.00;     //Beginn um 08:30 Uhr
float winterHPVAusgang = -52.81;
float winterVSAAusgang = 0.00;
float winterHSAAusgang = -52.81;

//Initialisieren der abzufahrenden Gradzahlen
float gzSommerVerti [] = {1.54, 1.73, 1.87, 1.97, 2.04, 2.10, 2.15, 2.19, 2.23, 2.27, 2.29, 2.31, 2.33, 
                        2.34, 2.34, 2.34, 2.34, 2.32, 2.30, 2.26, 2.22, 2.17, 2.11, 2.02, 1.92, 1.79, 
                        1.66, 1.49, 1.29, 1.06, 0.81, 0.54, 0.24, -0.05, -0.36, -0.64, -0.91, -1.15, 
                        -1.37, -1.55, -1.71, -1.85, -1.96, -2.05, -2.13, -2.19, -2.24, -2.28, -2.31, 
                        -2.32, -2.34, -2.35, -2.34, -2.34, -2.32, -2.30, -2.29, -2.25, -2.22, -2.17, 
                        -2.14, -2.07, -2.02, -1.93, -1.83, -1.67, -1.51};
float gzSommerHori [] = {2.93, 2.89, 2.84, 2.80, 2.78, 2.75, 2.73, 2.73, 2.72, 2.72, 2.74, 2.77, 2.80,
                        2.84, 2.91, 2.98, 3.08, 3.18, 3.32, 3.47, 3.64, 3.86, 4.09, 4.36, 4.67, 5.02, 
                        5.38, 5.77, 6.17, 6.56, 6.90, 7.16, 7.33, 7.36, 7.28, 7.07, 6.78, 6.41, 6.03, 
                        5.62, 5.24, 4.88, 4.56, 4.25, 4.00, 3.78, 3.57, 3.41, 3.26, 3.14, 3.04, 2.95, 
                        2.89, 2.83, 2.78, 2.76, 2.73, 2.72, 2.72, 2.73, 2.74, 2.76, 2.78, 2.82, 2.86, 
                        2.90, 2.94};

float gzWinterVerti [] = {1.55, 1.59, 1.60, 1.54, 1.46, 1.36, 1.27, 1.15, 1.04, 0.91, 0.78, 0.65, 0.51, 
                        0.37, 0.23, 0.08, -0.06, -0.21, -0.35, -0.49, -0.63, -0.77, -0.90, -1.01, 
                        -1.14, -1.25, -1.36, -1.44, -1.53, -1.59, -1.60, -1.55};
float gzWinterHori [] = {2.91, 2.96, 3.01, 3.06, 3.12, 3.18, 3.23, 3.29, 3.34, 3.39, 3.44, 3.47, 3.52, 
                        3.53, 3.56, 3.56, 3.57, 3.55, 3.54, 3.52, 3.48, 3.44, 3.40, 3.35, 3.29, 3.24, 
                        3.19, 3.12, 3.08, 3.01, 2.97, 2.91};

int anzWerteSommer = sizeof(gzSommerVerti)/sizeof(float); //Anzahl der Gradzahlen im Sommer
int anzWerteWinter = sizeof(gzWinterVerti)/sizeof(float); //Anzahl der Gradzahlen im Sommer

//Initialisieren der Uebersetzungen 
float uebersetzungVPV = 3.17;
float uebersetzungHPV = 13.83;
float uebersetzungVSA = 1.00;
float uebersetzungHSA = 1.00;


void setup() {
  //Driver-Pins als Outputs deklarieren
  pinMode(DIR_PIN_VPV, OUTPUT);
  pinMode(STEP_PIN_VPV, OUTPUT);
  pinMode(EN_PIN_VPV, OUTPUT);

  pinMode(DIR_PIN_HPV, OUTPUT);
  pinMode(STEP_PIN_HPV, OUTPUT);
  pinMode(EN_PIN_HPV, OUTPUT);

  //Enable-Pins auf LOW setzen
  digitalWrite(EN_PIN_VPV, LOW);
  digitalWrite(EN_PIN_HPV, LOW);

  //Seriellen Monitor starten
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:

  if(Serial.available()){
    int eingabe = Serial.read();

    if(eingabe == 's'){
      Ausgangspunkt(sommerVPVAusgang, sommerHPVAusgang, uebersetzungVPV, uebersetzungHPV);
    }
    if(eingabe == 'w'){
      Ausgangspunkt(winterVPVAusgang, winterHPVAusgang, uebersetzungVPV, uebersetzungHPV);
    }
    if(eingabe == 'S'){
      stepsPV(gzSommerVerti, gzSommerHori, uebersetzungVPV, uebersetzungHPV, anzWerteSommer, dreiMin);
    }
    if(eingabe == 'W'){
      stepsPV(gzWinterVerti, gzWinterHori, uebersetzungVPV, uebersetzungHPV, anzWerteWinter, dreiMin);
    }
    if(eingabe == 't'){
      vorschrittVPV(1000, 1); //Test für Funktion
    }
  }
}

/*In diesem Abschnitt werden Funktionen, 
die mehrfach ausgeführt werden müssen, 
der Einfachheit halber hinterlegt*/

void rueckschrittHPV(long steps, long takt){
  static unsigned long millisVorher;
  long stepsZaehler = 0;
  if(steps*(-1) > stepsZaehler){
    if(millis() - millisVorher >= takt){
      millisVorher = millis();
      digitalWrite(DIR_PIN_HPV, HIGH); //UZS
      digitalWrite(STEP_PIN_HPV, HIGH);
      digitalWrite(STEP_PIN_HPV, LOW);
      stepsZaehler++;
    }
  }
}

void vorschrittHPV(long steps, long takt){
  static unsigned long millisVorher;
  long stepsZaehler = 0;
  if(steps > stepsZaehler){
    if(millis() - millisVorher >= takt){
      millisVorher = millis();
      digitalWrite(DIR_PIN_HPV, LOW); //Gegen den Uhrzeigersinn (UZS)
      digitalWrite(STEP_PIN_HPV, HIGH);
      digitalWrite(STEP_PIN_HPV, LOW);
      digitalWrite(DIR_PIN_HPV, HIGH);
      stepsZaehler++;
    }
  }
}

void rueckschrittVPV(long steps, long takt){
  static unsigned long millisVorher;
  long stepsZaehler = 0;
  if(steps*(-1) > stepsZaehler){
    if(millis() - millisVorher >= takt){
      millisVorher = millis();
      digitalWrite(DIR_PIN_VPV, HIGH); //UZS
      digitalWrite(STEP_PIN_VPV, HIGH);
      digitalWrite(STEP_PIN_VPV, LOW);
      stepsZaehler++;
    }
  }
}

void vorschrittVPV(long steps, long takt){
  static unsigned long millisVorher;
  long stepsZaehler = 0;
  if(steps > stepsZaehler){
    if(millis() - millisVorher >= takt){
      millisVorher = millis();
      digitalWrite(DIR_PIN_VPV, LOW); //Gegen den Uhrzeigersinn (UZS)
      digitalWrite(STEP_PIN_VPV, HIGH);
      digitalWrite(STEP_PIN_VPV, LOW);
      digitalWrite(DIR_PIN_VPV, HIGH);
      stepsZaehler++;
    }
  }
}
//Testfunktion zum rumprobieren
/*void vorschrittVPV(long steps, long takt){
  static unsigned long timer;
  long stepsZaehler = 0;
  for(int i = 0; i < steps; i++){
    if(millis() > timer + takt){
      digitalWrite(DIR_PIN_VPV, LOW); 
      digitalWrite(STEP_PIN_VPV, HIGH);
      digitalWrite(STEP_PIN_VPV, LOW);
      digitalWrite(DIR_PIN_VPV, HIGH);
      //stepsZaehler++;
      timer = millis();
    }
  }
}*/


//Allgemeinfültige Funktion zum Positionieren der Drehachse

void stepsPV(float axisVPV[], float axisHPV[], float ueberVPV, float ueberHPV, int anzWerte, long dauer){
 long viertelstundenTakt = (dauer/anzWerte-1);
  for(int i=0; i<anzWerte; i++){

      long stepsVPV = (axisVPV[i]/(2.8125*0.01))*ueberVPV;
      long stepsHPV = (axisHPV[i]/(2.8125*0.01))*ueberHPV;

      //Abfrage, ob Gradzahl positiv oder negativ ist und anschließend entsprechender Schritt...
      //...für VPV...
      if(axisVPV[i] < 0){
        rueckschrittVPV(stepsVPV, viertelstundenTakt/stepsVPV);
     }
      else if(axisVPV[i] >= 0){
        vorschrittVPV(stepsVPV, viertelstundenTakt/stepsVPV);
      }
      //...für HPV...
      if(axisHPV[i] < 0){
        rueckschrittHPV(stepsHPV, viertelstundenTakt/stepsHPV);
      }
      else if(axisHPV[i] >= 0){
        vorschrittHPV(stepsHPV, viertelstundenTakt/stepsHPV);
      }
      
  }
}

//Positionieren zu den Ausgangspunkten
void Ausgangspunkt(float VPV, float HPV, float uebersVPV, float uebersHPV){
  long stepsVPV = (VPV/(2.8125*0.01))*uebersVPV;
  long stepsHPV = (HPV/(2.8125*0.01))*uebersHPV;

  if(VPV < 0 && HPV < 0){
    rueckschrittHPV(stepsHPV, 1);
    rueckschrittVPV(stepsVPV, 1);
  }
  else if (VPV >= 0 && HPV < 0){
    rueckschrittHPV(stepsHPV, 1);
    vorschrittVPV(stepsVPV, 1);
  }
  else if (VPV < 0 && HPV >= 0){
    vorschrittHPV(stepsHPV, 1);
    rueckschrittVPV(stepsVPV, 1);
  }
  else if (VPV >= 0 && HPV >= 0){
    vorschrittHPV(stepsHPV, 1);
    vorschrittVPV(stepsVPV, 1);
  }
}

Ich hoffe der Code ist so verständlich und das ihr mir weiterhelfen könnt. :nerd_face:

Beste Grüße
Jost

Damit sich die Funktion die Werte merkt, eventuell so:

  static unsigned long millisVorher = 0;
  static long stepsZaehler = 0;

Einfaches Beispiel:

const byte ledPin1 = 13;
const byte ledPin2 = 12;

void setup() {
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
}

void loop() {
  aufgabe1();
  aufgabe2();
}

void aufgabe1()
{
  uint32_t jetzt = millis();
  static uint32_t vorhin;
  const uint32_t intervall = 111;
  if (jetzt - vorhin >= intervall)
  {
    vorhin = jetzt;
    digitalWrite(ledPin1, !digitalRead(ledPin1));
  }
}

void aufgabe2()
{
  uint32_t jetzt = millis();
  static uint32_t vorhin;
  const uint32_t intervall = 300;
  if (jetzt - vorhin >= intervall)
  {
    vorhin = jetzt;
    digitalWrite(ledPin2, !digitalRead(ledPin2));
  }
}

Hi @agmue ,

leider hat das nichts gebracht...

Wenn du variablen in einer function definierst dann sind sie nur innerhalb dieser function bekannt und außerhalb unbekannt.

ohne den Zusatz "static" wird die Variable bei jedem function-Aufruf neu erstellt und beim Verlassen der function
weggeworfen / aus dem Speicher gelöscht / für immer eliminiert

Wenn man eine Variable tatsächlich nur innerhalb einer function braucht dann definiert man sie in dieser function.

Wenn man den Variablenwert beim nächsten function-aufruf benötigt dann deklariert man sie mit static. Das static verhindert das Wegwerfen.

Wenn man eine Variable in mehreren functions braucht dann definiert man sie global. Das heißt außerhalb aller functions

Deine Variable

stepsZaehler 

wird beim nächsten Aufruf auch wieder benötigt also muss die auch static definiert werden.
Wenn du diese Variable auch noch in anderen functions benutzt dann muss sie global werden

So und nun fange mal das eigene Nachdenken an und gehe deinen ganzen code durch um die Variablen mit diesem neuen Wissen entsprechend anzupassen.

vgs

Alles klar,

da ich meine Variable in mehreren Functions benötige, deklariere ich "stepsZaehler" global. (Auch wenn ich nicht verstehe was schlecht daran wäre wenn ich es jedes Mal neu in der Function mit dem Wert 0 deklariere).
Um einen Fehler im zweiten if-Befehl auszuschließen habe ich das Ganze auch noch ausgeklammert

void vorschrittVPV(long steps, long takt){
  static unsigned long millisVorher = 0;
  //long stepsZaehler = 0;
  if(steps > stepsZaehler){
    //if(millisJetzt - millisVorher >= takt){
      millisVorher = millis();
      digitalWrite(DIR_PIN_VPV, LOW); //Gegen den Uhrzeigersinn (UZS)
      digitalWrite(STEP_PIN_VPV, HIGH);
      digitalWrite(STEP_PIN_VPV, LOW);
      digitalWrite(DIR_PIN_VPV, HIGH);
      stepsZaehler++;
    //}
  }
}

... jedoch rührt sich mein Motor trotzdem nicht und ich verstehe einfach nicht wieso.
Habt ihr das durchblickt?

Beste Grüße

Dein Code aus Post 4 erschließt sich verständlicherweise nicht ganz einfach in ein paar Minuten :wink:

Jedoch - auch wenn es Dir vielleicht schwerfällt - Du musst Dich entscheiden, ob Du ein blockierendes oder ein nicht-blockierendes Programm haben willst. So, wie der Code jetzt aufgebaut ist, ist er zwangsläufig blockierend. Und damit verbaust Du Dir eine Reihe von Möglichkeiten. Das Stichwort zur Lösung lautet "State Machine", das klingt schlimmer, als es ist ...

Das liegt natürlich bei Dir. Hilfe findest Du dafür hier sicher auch.

Dein aktueller Code rennt wahrscheinlich viel zu schnell durch die for-Schleife in dem folgenden Auszug. Aufgehalten werden könnte er nur in den hinter den if's aufgerufenen Funktionen. Die blockieren aber auch nicht (s.u.). Soweit jedenfalls nach schnellem Durchschauen (kann mich natürlich auch täuschen, Testen ist angesagt siehe unten):

void stepsPV(float axisVPV[], float axisHPV[], float ueberVPV, float ueberHPV, int anzWerte, long dauer){
 long viertelstundenTakt = (dauer/anzWerte-1);
  for(int i=0; i<anzWerte; i++){

      long stepsVPV = (axisVPV[i]/(2.8125*0.01))*ueberVPV;
      long stepsHPV = (axisHPV[i]/(2.8125*0.01))*ueberHPV;

      //Abfrage, ob Gradzahl positiv oder negativ ist und anschließend entsprechender Schritt...
      //...für VPV...
      if(axisVPV[i] < 0){
        rueckschrittVPV(stepsVPV, viertelstundenTakt/stepsVPV);
     }
      else if(axisVPV[i] >= 0){
        vorschrittVPV(stepsVPV, viertelstundenTakt/stepsVPV);
      }
      //...für HPV...
      if(axisHPV[i] < 0){
        rueckschrittHPV(stepsHPV, viertelstundenTakt/stepsHPV);
      }
      else if(axisHPV[i] >= 0){
        vorschrittHPV(stepsHPV, viertelstundenTakt/stepsHPV);
      }
      
  }
}

Zu Testen würde ich mal ein Serial.println("i = "+String(i)); an den Anfang der for-Schleife einsetzen.

Und ggf. weitere println dort, wo in angemessenem "takt" weitere Aktivitäten erfolgen sollen...

void vorschrittVPV(long steps, long takt){
  static unsigned long millisVorher;
  long stepsZaehler = 0;
  if(steps > stepsZaehler){
    if(millis() - millisVorher >= takt){
      millisVorher = millis();
      digitalWrite(DIR_PIN_VPV, LOW); //Gegen den Uhrzeigersinn (UZS)
      digitalWrite(STEP_PIN_VPV, HIGH);
      digitalWrite(STEP_PIN_VPV, LOW);
      digitalWrite(DIR_PIN_VPV, HIGH);
      stepsZaehler++;
    }
  }
}

Wenn der Monitor ins Schwitzen kommt ... dann stimmt was nicht mit dem Timing. Und wenn die Variable stepsZaehler global oder statisch deklariert ist, musst Du sicherstellen, dass sie zum richtigen Zeitpunkt wieder rückgesetzt wird! Sonst hat sie immer den letzten zugewiesenen Wert ...

Aber siehe oben :wink:

1 Like

Wofür soll das String-Geraffel gut sein?

Serial.print("i = ");
Serial.println(i);

und Dein RAM wird es Dir danken.

Gruß Tommy

Nicht Thread relevant

Wenn's gebraucht wird ... :wink: Bei mir bricht eben ab und zu Pascal durch :innocent:

Und dann meintest Du vermutlich sogar

Serial.print(F("i = "));
Serial.println(i);

Nur im Sinne von (trifft damit für uns beide zu):

image

Ändert aber m.E. nichts daran, dass die Struktur des Sketches erheblich verändert werden muss, um nicht-blockierend zu arbeiten ...

Das habe ich nicht bestritten und ja, das F-Macro wäre eine weitere Optimierungsmöglichkeit.

Gruß Tommy

1 Like

Klugscheißer?
Anwesend!

#include <Streaming.h>


Serial << F("i = ") << i  << endl;
1 Like
Nicht Thread relevant

Ich wollte schon drauf wetten :wink:
Mehr zu wissen, kann, muss aber nicht immer glücklich machen :innocent:

Aufgrund fehlender Möglichkeiten hier vollkommen ungetestet und nur eine Idee.

Ich kann den nicht kompilieren und habe das nur trocken getackert...
Unkommentiert und ohne irgendeinen Anspruch.

[EDIT] Es gibt in Zeile166 eine Änderung, da ich da aus einer anderen Version was übersehen habe - Danke @ec2021 für den Hinweis[/]

//Einbinden der Bibliotheken
#include <Arduino.h> //Für alle Arduino-sketches erforderlich
#include <TMCStepper.h> //Bibliothek für alle TMC-Stepper (Auch 2209)

// Pin-Belegung für den ersten Stepper-driver
#define DIR_PIN_VPV A1  // Richtungssignal
#define STEP_PIN_VPV A0  // Schrittsignal
#define EN_PIN_VPV 38   // Aktivierte Motorausgänge (GND = An, VIO = Aus)

// Pin-Belegung für den zweiten Stepper-driver
#define DIR_PIN_HPV A3  // Richtungssignal
#define STEP_PIN_HPV A2  // Schrittsignal
#define EN_PIN_HPV 40   // Aktivierte Motorausgänge (GND = An, VIO = Aus)

//Dauer, in der das Experiment abfahren soll
long eineMin = 60000;
long dreiMin = eineMin*3; //3 Minuten
long fuenfMin = eineMin*5; //5 Minuten
long zehnMin = eineMin*10; //10 Minuten


//Initialisieren der Ausgangspositionen
float sommerVPVAusgang = -60.00;     //VPV = Vertikale PV
float sommerHPVAusgang = -130.85;    //HPV = Horizontale PV
float sommerVSAAusgang = 0.00;       //VSA = Vertikaler Schwenkarm (Sonne)
float sommerHSAAusgang = -130.85;    //HSA = Horizontaler Schwenkarm (Sonne)

float winterVPVAusgang = -60.00;     //Beginn um 08:30 Uhr
float winterHPVAusgang = -52.81;
float winterVSAAusgang = 0.00;
float winterHSAAusgang = -52.81;

//Initialisieren der abzufahrenden Gradzahlen
float gzSommerVerti [] = {1.54, 1.73, 1.87, 1.97, 2.04, 2.10, 2.15, 2.19, 2.23, 2.27, 2.29, 2.31, 2.33, 
                        2.34, 2.34, 2.34, 2.34, 2.32, 2.30, 2.26, 2.22, 2.17, 2.11, 2.02, 1.92, 1.79, 
                        1.66, 1.49, 1.29, 1.06, 0.81, 0.54, 0.24, -0.05, -0.36, -0.64, -0.91, -1.15, 
                        -1.37, -1.55, -1.71, -1.85, -1.96, -2.05, -2.13, -2.19, -2.24, -2.28, -2.31, 
                        -2.32, -2.34, -2.35, -2.34, -2.34, -2.32, -2.30, -2.29, -2.25, -2.22, -2.17, 
                        -2.14, -2.07, -2.02, -1.93, -1.83, -1.67, -1.51};
float gzSommerHori [] = {2.93, 2.89, 2.84, 2.80, 2.78, 2.75, 2.73, 2.73, 2.72, 2.72, 2.74, 2.77, 2.80,
                        2.84, 2.91, 2.98, 3.08, 3.18, 3.32, 3.47, 3.64, 3.86, 4.09, 4.36, 4.67, 5.02, 
                        5.38, 5.77, 6.17, 6.56, 6.90, 7.16, 7.33, 7.36, 7.28, 7.07, 6.78, 6.41, 6.03, 
                        5.62, 5.24, 4.88, 4.56, 4.25, 4.00, 3.78, 3.57, 3.41, 3.26, 3.14, 3.04, 2.95, 
                        2.89, 2.83, 2.78, 2.76, 2.73, 2.72, 2.72, 2.73, 2.74, 2.76, 2.78, 2.82, 2.86, 
                        2.90, 2.94};

float gzWinterVerti [] = {1.55, 1.59, 1.60, 1.54, 1.46, 1.36, 1.27, 1.15, 1.04, 0.91, 0.78, 0.65, 0.51, 
                        0.37, 0.23, 0.08, -0.06, -0.21, -0.35, -0.49, -0.63, -0.77, -0.90, -1.01, 
                        -1.14, -1.25, -1.36, -1.44, -1.53, -1.59, -1.60, -1.55};
float gzWinterHori [] = {2.91, 2.96, 3.01, 3.06, 3.12, 3.18, 3.23, 3.29, 3.34, 3.39, 3.44, 3.47, 3.52, 
                        3.53, 3.56, 3.56, 3.57, 3.55, 3.54, 3.52, 3.48, 3.44, 3.40, 3.35, 3.29, 3.24, 
                        3.19, 3.12, 3.08, 3.01, 2.97, 2.91};

int anzWerteSommer = sizeof(gzSommerVerti)/sizeof(float); //Anzahl der Gradzahlen im Sommer
int anzWerteWinter = sizeof(gzWinterVerti)/sizeof(float); //Anzahl der Gradzahlen im Sommer

//Initialisieren der Uebersetzungen 
float uebersetzungVPV = 3.17;
float uebersetzungHPV = 13.83;
float uebersetzungVSA = 1.00;
float uebersetzungHSA = 1.00;


void setup() {
  //Driver-Pins als Outputs deklarieren
  pinMode(DIR_PIN_VPV, OUTPUT);
  pinMode(STEP_PIN_VPV, OUTPUT);
  pinMode(EN_PIN_VPV, OUTPUT);

  pinMode(DIR_PIN_HPV, OUTPUT);
  pinMode(STEP_PIN_HPV, OUTPUT);
  pinMode(EN_PIN_HPV, OUTPUT);

  //Enable-Pins auf LOW setzen
  digitalWrite(EN_PIN_VPV, LOW);
  digitalWrite(EN_PIN_HPV, LOW);

  //Seriellen Monitor starten
  Serial.begin(9600);
  Serial.println(F("Start... "));
}

void loop() {
  // put your main code here, to run repeatedly:

  if(Serial.available()){
    int eingabe = Serial.read();

    if(eingabe == 's'){
      Ausgangspunkt(sommerVPVAusgang, sommerHPVAusgang, uebersetzungVPV, uebersetzungHPV);
    }
    if(eingabe == 'w'){
      Ausgangspunkt(winterVPVAusgang, winterHPVAusgang, uebersetzungVPV, uebersetzungHPV);
    }
    if(eingabe == 'S'){
      stepsPV(gzSommerVerti, gzSommerHori, uebersetzungVPV, uebersetzungHPV, anzWerteSommer, dreiMin);
    }
    if(eingabe == 'W'){
      stepsPV(gzWinterVerti, gzWinterHori, uebersetzungVPV, uebersetzungHPV, anzWerteWinter, dreiMin);
    }
    if(eingabe == 't'){
      vorschrittVPV(1000, 1); //Test für Funktion
    }
  }
vorschrittHPV();
}

/*In diesem Abschnitt werden Funktionen, 
die mehrfach ausgeführt werden müssen, 
der Einfachheit halber hinterlegt*/

void rueckschrittHPV(long steps, long takt){
  static unsigned long millisVorher;
  long stepsZaehler = 0;
  if(steps*(-1) > stepsZaehler){
    if(millis() - millisVorher >= takt){
      millisVorher = millis();
      digitalWrite(DIR_PIN_HPV, HIGH); //UZS
      digitalWrite(STEP_PIN_HPV, HIGH);
      digitalWrite(STEP_PIN_HPV, LOW);
      stepsZaehler++;
    }
  }
}

bool vorschrittHPV()
{
  return vorschrittHPV(0,0);
}
bool vorschrittHPV(long steps, long takt)
{
  static bool myStatus = false;
  static long mySteps = 0;
  static long myTakt = 0;
  static unsigned long lastmillis = 0;
  if (myStatus == false)
  {
    mySteps = steps;
    myTakt = takt;
    myStatus = true;
    lastmillis = 0;
    Serial.print(F("Daten übernommen: ")); Serial.print(mySteps); Serial.print(" "); Serial.println(myTakt);
  }
  if (mySteps > 0)
  {
    if (millis() - lastmillis > myTakt)
    {
      digitalWrite(DIR_PIN_HPV, LOW); //Gegen den Uhrzeigersinn (UZS)
      digitalWrite(STEP_PIN_HPV, HIGH);
      digitalWrite(STEP_PIN_HPV, LOW);
      digitalWrite(DIR_PIN_HPV, HIGH);
      mySteps--;
      lastmillis = millis();
    }
  }
  if (mySteps <= 0) myStatus = false;
  return myStatus;
}

void rueckschrittVPV(long steps, long takt){
  static unsigned long millisVorher;
  long stepsZaehler = 0;
  if(steps*(-1) > stepsZaehler){
    if(millis() - millisVorher >= takt){
      millisVorher = millis();
      digitalWrite(DIR_PIN_VPV, HIGH); //UZS
      digitalWrite(STEP_PIN_VPV, HIGH);
      digitalWrite(STEP_PIN_VPV, LOW);
      stepsZaehler++;
    }
  }
}

void vorschrittVPV(long steps, long takt){
  static unsigned long millisVorher;
  long stepsZaehler = 0;
  if(steps > stepsZaehler){
    if(millis() - millisVorher >= takt){
      millisVorher = millis();
      digitalWrite(DIR_PIN_VPV, LOW); //Gegen den Uhrzeigersinn (UZS)
      digitalWrite(STEP_PIN_VPV, HIGH);
      digitalWrite(STEP_PIN_VPV, LOW);
      digitalWrite(DIR_PIN_VPV, HIGH);
      stepsZaehler++;
    }
  }
}
//Testfunktion zum rumprobieren
/*void vorschrittVPV(long steps, long takt){
  static unsigned long timer;
  long stepsZaehler = 0;
  for(int i = 0; i < steps; i++){
    if(millis() > timer + takt){
      digitalWrite(DIR_PIN_VPV, LOW); 
      digitalWrite(STEP_PIN_VPV, HIGH);
      digitalWrite(STEP_PIN_VPV, LOW);
      digitalWrite(DIR_PIN_VPV, HIGH);
      //stepsZaehler++;
      timer = millis();
    }
  }
}*/


//Allgemeinfültige Funktion zum Positionieren der Drehachse

void stepsPV(float axisVPV[], float axisHPV[], float ueberVPV, float ueberHPV, int anzWerte, long dauer){
 long viertelstundenTakt = (dauer/anzWerte-1);
  for(int i=0; i<anzWerte; i++){

      long stepsVPV = (axisVPV[i]/(2.8125*0.01))*ueberVPV;
      long stepsHPV = (axisHPV[i]/(2.8125*0.01))*ueberHPV;

      //Abfrage, ob Gradzahl positiv oder negativ ist und anschließend entsprechender Schritt...
      //...für VPV...
      if(axisVPV[i] < 0){
        rueckschrittVPV(stepsVPV, viertelstundenTakt/stepsVPV);
     }
      else if(axisVPV[i] >= 0){
        vorschrittVPV(stepsVPV, viertelstundenTakt/stepsVPV);
      }
      //...für HPV...
      if(axisHPV[i] < 0){
        rueckschrittHPV(stepsHPV, viertelstundenTakt/stepsHPV);
      }
      else if(axisHPV[i] >= 0){
        vorschrittHPV(stepsHPV, viertelstundenTakt/stepsHPV);
      }
      
  }
}

//Positionieren zu den Ausgangspunkten
void Ausgangspunkt(float VPV, float HPV, float uebersVPV, float uebersHPV){
  long stepsVPV = (VPV/(2.8125*0.01))*uebersVPV;
  long stepsHPV = (HPV/(2.8125*0.01))*uebersHPV;

  if(VPV < 0 && HPV < 0){
    rueckschrittHPV(stepsHPV, 1);
    rueckschrittVPV(stepsVPV, 1);
  }
  else if (VPV >= 0 && HPV < 0){
    rueckschrittHPV(stepsHPV, 1);
    vorschrittVPV(stepsVPV, 1);
  }
  else if (VPV < 0 && HPV >= 0){
    vorschrittHPV(stepsHPV, 1);
    rueckschrittVPV(stepsVPV, 1);
  }
  else if (VPV >= 0 && HPV >= 0){
    vorschrittHPV(stepsHPV, 1);
    vorschrittVPV(stepsVPV, 1);
  }
}

Für die Rückgabe in Zeile 126 gibt es derzeit keinen Sinn, aber mit einer solchen Rückgabe kannst Du prüfen, ob Dein Step bereits abgelaufen ist.

Ich betrachte es als Vorteil. Mit dem Rest kann ich leben.

Gruß Tommy

Nicht Thread relevant

„Das Wissen macht uns weder besser, noch glücklicher.“ — Heinrich Von Kleist

Quelle: Zitate von Heinrich Von Kleist (40 Zitate) | Zitate berühmter Personen

Der ist aber auch schon lange tot ... :wink:

Hallo Jost,

also wenn dein Motor keinen Mucks macht.
musst du jetzt erst einmal ein paar grundlegende Fragen beantworten

Womöglich suchen wir uns hier im code die Augen wund und dabei hast du einen hardwarefehler.

Hast du den Schrittmotor mit einem Testcode der nichts weiter als
"Schrittmotor lauf mal 200 Schritte" macht am laufen gehabt? Ja oder nein?

Poste mal eine verbale Beschreibung wie dein Code im Prinzip funktionieren soll

vgs

Steht doch im ersten Post.
In #4 sein Code.

Der Thread ist eh kaputt...
@ec2021:
(Mein Lieblingszitat seit Monaten...)
„In diesem Fall ziehen Sie eine Maske schnell zu sich heran und platzieren diese fest auf Mund und Nase. Danach helfen Sie Kindern und hilfsbedürftigen Personen.“ - Batman zu Robin
Quelle
:slight_smile: :slight_smile: :slight_smile:

Moin @my_xy_projekt:

Du hast (höchste Anerkennung für VHIT ohne Compilieren!) nur ein fehlendes Gleichheitszeichen in der Zeile

 if (mySteps != 0) myStatus true; else myStatus = false;     // vor "true"

Kleiner Support für Dich; pack das vorne in den Sketch, dann kannst Du ihn bei Dir compilieren und hochladen (die Pins habe ich mal willkürlich zugewiesen). Es lässt sich auch ohne die Stepper-Lib übersetzen. Da kann man auch mal drüber nachdenken ... Sind dort nur die paar Pin Definitionen hinterlegt?

//Einbinden der Bibliotheken
#include <Arduino.h> //Für alle Arduino-sketches erforderlich
#define TEST

#ifdef TEST
// Pin-Belegung für den ersten Stepper-driver
#define DIR_PIN_VPV 8  // Richtungssignal
#define STEP_PIN_VPV 9  // Schrittsignal
#define EN_PIN_VPV  10   // Aktivierte Motorausgänge (GND = An, VIO = Aus)

// Pin-Belegung für den zweiten Stepper-driver
#define DIR_PIN_HPV  11  // Richtungssignal
#define STEP_PIN_HPV 12  // Schrittsignal
#define EN_PIN_HPV   13   // Aktivierte Motorausgänge (GND = An, VIO = Aus)

#else 

#include <TMCStepper.h> //Bibliothek für alle TMC-Stepper (Auch 2209)
// Pin-Belegung für den ersten Stepper-driver
#define DIR_PIN_VPV A1  // Richtungssignal
#define STEP_PIN_VPV A0  // Schrittsignal
#define EN_PIN_VPV 38   // Aktivierte Motorausgänge (GND = An, VIO = Aus)

// Pin-Belegung für den zweiten Stepper-driver
#define DIR_PIN_HPV A3  // Richtungssignal
#define STEP_PIN_HPV A2  // Schrittsignal
#define EN_PIN_HPV 40   // Aktivierte Motorausgänge (GND = An, VIO = Aus)

#endif