Anfängerfrage Zeitverzögerungen Servosteuerung

Hallo zusammen,

ich hätte kurz eine kleine Frage zu meinem aktuellen Versuch ein Modellbauservo in der Geschwindigkeit
und Position einstellen zu können.
Ich habe mir hierzu einen kleinen Sketch gebastelt. Leider funktioniert das noch nicht richtig.
Der Servo fährt zwar auf seine Endpositionen, aber leider nicht in den von mit gewünschten Einzelschritten mit 200ms Verzögerung.
Meine Überlegung war die einzelnen Funktionen nur einmal alle 200ms durchlaufen zu lassen. Der “Hilfsmerker” HM1 soll dafür sorgen, das die Funktion nur alle 200ms durchlaufen wird wenn er wieder auf 1 gesetzt wird. Innerhalb der Funktion wird der HM1 auf 0 gesetzt.
Jetzt fährt der Servo aber ungeachtet der Zeit auf seine Position. Ich habe das Gefühl das die 1ms reichen um den Wert der “pos” auf 160 hochzuzählen.
Wird der Wert “pos” nicht nur 1x bei jedem Zyklus hochgezählt?
Dann sollte doch schon HM1 auf 0 sein.
Oder habe ich hier einen gravierenden Gedankenfehler?

// SERVOTEST

unsigned long time = millis() % 200; // Alle 200ms soll angewählte Funktion durchlaufen werden

if  (time >= 200){
   HM1 = 1;                              // Hilfsmerker Freigabe Servodurchlauf wenn 200ms abgelaufen
}
else {
}

if  ((digitalRead(0) == HIGH) && (HM1 = 1) && (pos <= 160)){  //Servodurchlauf wenn Schalter High, Hilfsmerker 1 und Position kleiner als 160
   pos += 1;                                                 //Aktuelle position um ein Grad erhöhen
   SERVO2.write(pos);                                    //Servo ansteuern
   HM1 = 0;                                                  //Hilfsmerker 0 um zu verhindern das Schritt erneut durchgeführt wird.
}
else {
} 

if  ((digitalRead(0) == LOW) && (HM1 = 1) && (pos >= 0)){   //Servodurchlauf wenn Schalter LOW, Hilfsmerker 1 und Position größer als 0
   pos -= 1;                                               //Aktuelle position um ein Grad verringern
   SERVO2.write(pos);                                  //Servo ansteuern
   HM1 = 0;                                                //Hilfsmerker 0 um zu verhindern das Schritt erneut durchgeführt wird.
}
else {
}

crazyvolle:
Oder habe ich hier einen gravierenden Gedankenfehler?
...

Du hast auf jeden Fall einen ziemlich „querfeldein“-formatierten Code. Wenn es bei mir um Fehlersuche geht, sehe ich zuerst, dass der Sketch einheitlich und übersichtlich formatiert ist. Mich würde nicht wundern, wenn Du den Fehler findest, wenn Du Deinen Sketch aufhübschst.

Gruß

Gregor

Hi

Deine Annahme ist falsch:

unsigned long time = millis() % 200; // Alle 200ms soll angewählte Funktion durchlaufen werden

if  (time >= 200){

time kann nur Werte von 0...199 annehmen - Du ermittelst den Rest der Division durch 200 - und Der kann nur kleiner als 200 sein, sonst könntest Du ja '1x mehr' teilen.

MfG

PS: STRG+T in der IDE rückt den Code anschaulich ein.
Massenauftreten von Leerzeilen muß man aber händisch entfernen - Die sind aber ja auch händisch da rein gekommen ;).

Hallo zusammen,

ok, den Code habe ich jetzt mal formatiert.
Das Byte setze ich jetzt bei 0ms auf 1. Funzt aber immer noch nicht richtig.

  // SERVOTEST

  unsigned long time = millis() % 200;  // Alle 200ms soll Funktion durchlaufen werden

  if  (time == 0) {
    HM1 = 1;                            // Hilfsbyte Freigabe Servodurchlauf wenn 200ms abgelaufen
  }
  else {
  }

  if  ((digitalRead(0) == HIGH) && (HM1 = 1) && (pos <= 160)) { //Servodurchlauf wenn Schalter High, Hilfsmerker 1 und Position kleiner als 160
    HM1 = 0;                                                    //Hilfsbyte 0 um erneten Schritt auszuführen.
    pos += 1;                                                   //Aktuelle Position um ein Grad erhöhen
    SERVO2.write(pos);                                          //Servo ansteuern
  }
  else {
  }

  if  ((digitalRead(0) == LOW) && (HM1 = 1) && (pos >= 0)) {    //Servodurchlauf wenn Schalter LOW, Hilfsmerker 1 und Position größer als 0
    HM1 = 0;                                                    //Hilfsbyte 0 um erneten Schritt auszuführen.
    pos -= 1;                                                   //Aktuelle Position um ein Grad verringern
    SERVO2.write(pos);                                          //Servo ansteuern
  }
  else {
  }

Hallo,

also ich wollte Euch kurz informieren das es jetzt so wie gewünscht funktioniert.
Hier mal meine Lösung.
Vermutlich gibt es noch eine einfachere Lösung. Aber ich bin mit meinem Entwurf erst einmal zufrieden.
Ich habe auch gleich ein paar Variablen mit reingepackt. Die Zeit zwischen zwei Schritten soll einstellbar sein. Auch soll die End/Anfangsposition vom Servo variabel sein.

  // SERVO 1

  unsigned long timeSv1 = millis() % (VSv1);  // Zeitangabe um Servo zwischen zwei Schritten zu bewegen. VSv1 ist variabel
  if  (timeSv1 <= 1) {
    HM1 = 1;                            // Freigabe für Durchlauf der Funktion. Byte wird mit 1 beschrieben.
  }
  else {
    HM1 = 0;                            // Sperren der Servofunktion für den Rest der eingestellten Laufzeit
  }
  if  ((digitalRead(0) == HIGH) && (HM1 == 1) && (posSv1 <= PosSv1AS)) { //Servodurchlauf wenn Schalter High, Hilfsbyte 1 und Position kleiner als aus variablen Position
    posSv1 += 1;                                                   //Aktuelle Position um ein Grad erhöhen
    SERVO2.write(posSv1);                                          //Position an Servo schreiben
    delay(2);                                                      //Verzögerung
  }
  else {
  }
  if  ((digitalRead(0) == LOW) && (HM1 == 1) && (posSv1 >= PosSv1GS)) {    //Servodurchlauf wenn Schalter High, Hilfsbyte 1 und Position kleiner als aus variablen Position
    posSv1 -= 1;                                                   //Aktuelle Position um ein Grad verringern
    SERVO2.write(posSv1);                                          //Position an Servo schreiben
    delay(2);                                                      //Verzögerung
  }
  else {
  }

Dein Code ist suboptimal, da er delay in Schleifen benutzt.

Wenn du es einfach haben willst, nimm die passende Lib.

Variabel Servo Speed

Hallo,

ich habe jetzt noch einmal ein wenig experimentiert.
Jetzt funktioniert es auch ohne delay.
Ich merke mir im Byte HM1 nun das der Nulldurchgang in timeSv1 stattgefunden hat.
Dann wird in das Byte HM11 eine 1 geschrieben wenn timeSV1 >=1 ist.
Als Startbedingung für die Schleife werden dann beide abgefragt.
Ist eigentlich eine Flankenauswertung. Zumindest habe ich mir das so gedacht :wink:

  // SERVO 1 ANSTEUERUNG

  unsigned long timeSv1 = millis() % (200);  // Zeitangabe um Servo zwischen zwei Schritten zu bewegen.
  if  (timeSv1 == 0) {
    HM1 = 1;                            // Freigabe für Durchlauf der Funktion. Byte wird mit 1 beschrieben.
  }
  else {                            // Sperren der Servofunktion für den Rest der eingestellten Laufzeit
  }
  if  ((HM1 == 1) && (timeSv1 >= 1)) {
    HM11 = 1;                            // Freigabe für Durchlauf der Funktion. Byte wird mit 1 beschrieben.
  }
  else {                            // Sperren der Servofunktion für den Rest der eingestellten Laufzeit
  }

  if  ((digitalRead(0) == HIGH) && (HM11 == 1) && (posSv1 <= 160)) { //Servodurchlauf wenn Schalter High, Hilfsbyte 1 und Position kleiner als aus variablen Position
    posSv1 += 1;                                                   //Aktuelle Position um ein Grad erhöhen
    SERVO1.write(posSv1);                                          //Position an Servo schreiben
    HM1 = 0;
    HM11 = 0;
  }
  else {
  }
  if  ((digitalRead(0) == LOW) && (HM11 == 1) && (posSv1 >= 20)) {    //Servodurchlauf wenn Schalter High, Hilfsbyte 1 und Position kleiner als aus variablen Position
    posSv1 -= 1;                                                   //Aktuelle Position um ein Grad verringern
    SERVO1.write(posSv1);                                          //Position an Servo schreiben
    HM1 = 0;
    HM11 = 0;
  }
  else {
  }

Gruß Volle