Servo / verschiedene Positionen mit kurzem Halt

Hallo miteinander.
Könnte mir bitte jemand helfen, den Code von einem Servo so zu ändern, damit er an verschiedenen Position hält .
Es dreht sich hier um einen 150Kg/12V Servo . Die Drehzahl würde bereits passen.

/* Sweep
 by BARRAGAN <http://barraganstudio.com>
 This example code is in the public domain.

 modified 8 Nov 2013
 by Scott Fitzgerald
 https://www.arduino.cc/en/Tutorial/LibraryExamples/Sweep
*/

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // Startposition

void setup() {
  myservo.attach(8);  // Steckplatz am Board
}

void loop() {
  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(30);                       // waits 15 ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(25);                       // waits 15 ms for the servo to reach the position
     }

     delay (100000);
}

Vielen Dank im voraus

Hallo kruemelchen_70

Hier kommt ein Tipp zum Schlaulesen:

dazu müsstest du zunächst den Ablauf exakt beschreiben. Ca in dieser Form:

Langsam Bewegen nach xx Grad
Warten yy ms
Langsam Bewegen nach zz Grad
Warten ...

Vielen Dank schon mal fürs Antworten .

  • Startposition 0
  • langsam auf 100°, warten 2sek,
  • langsam auf 60°, warten 2sek,
  • langsam auf 180°, warten 2sek,
  • zurück auf 0°

Die Grad Zahl , kann ich ja noch ändern.

VG

void loop() {
  for (pos = 0; pos <= 100; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15 ms for the servo to reach the position
  }
 delay(2000);  
  for (pos = 100; pos >= 60; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15 ms for the servo to reach the position
     }
  delay(2000);  
  for (pos = 60; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15 ms for the servo to reach the position
  }
  delay(2000);  
  myservo.write(0);  
}

hier zunächste eine blockierende Variante:

/* 
 Slow Servo - Blocking and with delay
 https://forum.arduino.cc/t/servo-verschiedene-positionen-mit-kurzem-halt/1281682/4

 for a better variant see my homepage:
 https://werner.rothschopf.net/microcontroller/202207_millis_slow_servo.htm

 2024-07-15 by noiasca

 to be deleted 2024-10
*/

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

// move the servo to a specified target
void move(int target, int wait = 30) {
  static int current = 0;  // you must remember the old position, hence the static keyword
  while (target != current) {
    if (target < current) {
      current--;
      myservo.write(current);
    }
    else if (target > current) {
      current++;
      myservo.write(current);
    }
    delay(wait); // dirty blocking delay
  }
}

void setup() {
  myservo.attach(8);  // Steckplatz am Board
  //Startposition 0
  move (0, 0);        // position, waittime
}

void loop() {
  //langsam auf 100°, warten 2sek,
  move(100); 
  delay(2000);
  //langsam auf 60°, warten 2sek,
  move(60); 
  delay (2000);
  //langsam auf 180°, warten 2sek,
  move (180); 
  delay(2000);
  //zurück auf 0°
  move (0, 0);
}

nicht blockierend würde ich es nach diesem Muster aufbauen:
https://werner.rothschopf.net/microcontroller/202207_millis_slow_servo.htm

Vielen vielen Dank für die Hilfe :pray: .... da ist schon was dabei was funktioniert.
Der Simulator ist ja geil. Sowas hab ich noch nie gesehen . Echt toll

Jetzt wenn das noch klappt, dass der Servo so schön langsam fährt, wenn ein PIR bewegung erkennt, dann hätte ich mein Ziel erreicht. :grinning:

Schön langsam macht @wwerner mit seinem
delay(15);
15 ms pro Grad Servowinkel.

Bei @noiasca hat die Funktion move eine Voreinsteillung von 30 msec/ Grad.
Das kann man in der Funktionsdefinition
void move(int target, int wait = 30) {
anpassen, oder bei jedem move-Aufruf individuell einstellen. Z.B. so

move(100,50); // langsam hin
delay(1000);     // 1 sec Warten
move(0,10);    // etwas flotter zurück

Hallo,

jetzt bist Du eigentlich an dem Punkt angekommen wo Du dich, wenn Du magst, mit dem Thema Ablaufsteuerung , Schrittketten, Statemashine und nicht blockierender Ablauf beschäftigen solltest. Vermutlich willst Du ja mit dem PIR einen ganzen Zyklus starten. Kann aber ja auch sein das Du nur Teile davon ablaufen lassen willst. Eventuell kommt Dir als nächstes der Gedanke auch noch was anderes gleichzeitig machen zu wollen, und sei es nur das Du während der Wartezeit einen zweiten Eingang abfragen möchtest um z.B sofort zurück zu fahren.

Es geht dabei zunächst darum die vorhandenen delay() durch ein Konstrukt mit millis() zu ersetzten. Wenn Du ein bisschen suchst wirst Du reichlich Beispiele finden. Such mal hier im Forum nach dem Nachtwächter, wenn Du das verstanden hast und anwenden kannst ist der Rest ein Klacks.

Für das langsame Bewegen könntest Du statt der Servo.h die MobaTools verwenden. Die können das ohne dass Du im Sketch was dafür tun musst ( Ausser 1x angeben wie schnell es gehen soll :wink: )
Für die Pause zwischen den Bewegungen kannst Du dann millis() verwenden um den Code nicht zu blockieren.

Hier eine nicht blockierende Variante mit MobaTools:

/*
  Servo langsam zu verschiedenen Positionen fahren
  Nicht blockierende Variante mit MobaTools
*/

#include <MobaTools.h>

MoToServo myServo;  // create servo object to control a servo
MoToTimer pauseZeit; // Timer fuer die Pausen

byte positions[] = { 100, 60, 180, 20 }; // Tabelle der anzufahrenden Positionen
constexpr byte posZahl = sizeof(positions); // Positionen müssen als byte deklariert werden))
constexpr int warteZeit = 2000;
byte posIx = 0;
bool pauseAktiv = false;
void setup() {
  Serial.begin(115200);
  myServo.attach(8);  // Steckplatz am Board
  myServo.setSpeedTime ( 2000 ); // 2 Sec werden von 0 auf 180 benötiogt
  //Startposition 0
  myServo.write(0);        // erste Position
}

void loop() {
  if ( myServo.moving() == 0 ) {
    // Nur wenn das Servo steht, passiert was
    if ( not pauseAktiv ) {
      // Servo hat Zielpunkt erreicht, aber Pausezeit läuft noch nicht
      pauseZeit.setTime( warteZeit ); //Timer starten
      pauseAktiv = true;
      Serial.println( "Timer starten");
    }
    if ( pauseZeit.expired() ) {
      // Die Pausezeit ist abgelaufen, Servo auf nächsten Punkt bewegen
      myServo.write( positions[posIx]);
      Serial.print("Gehe zu Pos "); Serial.println (positions[posIx] );
      if ( ++posIx >= posZahl ) {
        // Ende der Positionstabelle erreicht, wieder auf 0
        posIx = 0;
      }
      pauseAktiv = false;
    }
  }
}

Das Array mit den anzufahrenden Positionen kannst Du gegebenenfalls auch erweitern ( oder kürzen ).
Die seriellen Ausgaben sind nur zur Visualisierung was passiert - die kannst Du auch löschen/auskommentieren.

...wo ich morgen in den Urlaub fliege ... stimmt :grinning:

Es ist bestimmt ein interessantes Thema. Nur bin ich beruflich und auch privat ganz gut eingespannt, dass ich nicht mal zum fernsehen komme.
Ich würde auch , wenn es angeboten würde , einen Arduino-Anfängerkurs besuchen . Nur durch das lesen komm ich nicht weiter. Zu viel Fachchinesisch. Ich bin der Mensch , Learning by doing.

Ich hab mich rießig über den Arduino Code gefreut. Danke hierfür an alle :pray: :pray: :pray:

Somit bin ich meinem kleinen Halloween Projekt einen Stück weitergekommen :grinning:

Seid mir bitte nicht böse, wenn ich mich demnächst nicht melde.

Viele Grüße