2 Servos per Zufall bewegen + via RC Signal schaltbar machen

Hi Leute

da ich bezüglich meines Tiger-Projektes noch eine andere Möglichkeit testen wollen würde, hätte ich an die Programmier-Spezialisten bzw. Cracks am Arduino eine Bitte:
Evtl kann mir den Code jemand um einen Servosignal-Eingang erweitern. Z.b. an Pin 9.? :slight_smile:

Ich habe bereits diesen fertigen Code hier.
Er bewegt 2 Servos per Zufall mit Random-Werten hin und her.
Die Geschwindigkeit lässt sich auch variabel einstellen.

Ich würde das ganze jetzt gerne noch via RC-Signal schaltbar gestalten.
Dazu hätte ich gerne einstellbar in welchem Bereich von 1000 µs to 2000 µs die Schaltung auf “AN” geht.

Leider übersteigt das meine doch sehr geringen Progmmierkenntnisse im Bereich “Arduino bzw. C”

Anbei mein bisheriger Code:

Verwendet habe ich einen Pro Mini 5V 16Hz
Vor dem Arduino befindet sich noch ein kleiner Spannungswandler der mir die Spannung vom 2s LIPO auf genau 5V regelt.

Endausschläge und Geschwindigkeit für das jeweilige Servo sind einstellbar.
Die Servoposition an die das Servo geschickt wird, wird per Zufall via Random-Wert generiert.

Video wie das ganze dann aussieht:

Man benötigt folgende Library sowie unten stehenden Code
Library:
VarSpeedServo.h

kann man hier downloaden:
https://github.com/netlabtoolkit/VarSpeedServo

Code:

#include <VarSpeedServo.h>

#define SERVO_P1 10 // Servo connected to PIN 10
#define SERVO_P2 11 // Servo connected to PIN 11
#define WAIT_I 1000 // wait after init in ms


#define POS_L 20 // left endstop
#define POS_R 160 // right endstop
#define POS_O 20 // oben endstop
#define POS_U 160 // unten endstop

#define WAIT_EN 350 // wait time at endstop in ms
#define WAIT_IN 500 // wait time at each angular increment in ms


VarSpeedServo servo1; // create servo object to control a servo
VarSpeedServo servo2; // Zusatzservo für oben unten


void setup()
{
servo1.attach(SERVO_P1); // attaches the servo on pin 10 to the servo object
servo1.write(POS_L); // tell servo to go to init position

servo2.attach(SERVO_P2); // attaches the servo on pin 11 to the servo object
servo2.write(POS_O); // tell servo to go to init position

delay(WAIT_I); // wait a little bit
}


void loop()
{
int posX = 0; // variable to store the servo position
int posY = 0; // variable to store the servo position
int gotoX = (int) random(POS_L, POS_R);
int gotoY = (int) random(POS_O, POS_U);


servo1.write(gotoX,40); // tell servo to go to position in variable 'pos'
servo2.write(gotoY,10); // tell servo to go to position in variable 'pos'

delay(WAIT_IN); // waits for the servo to reach the position
}

Wäre sehr dankbar, wenn mir ein Profi da evtl kurz helfen könnte. :slight_smile:

Vielen Dank

Gruß
Manuel

FireFoxDeluxe: Ich würde das ganze jetzt gerne noch via RC-Signal schaltbar gestalten. Dazu hätte ich gerne einstellbar in welchem Bereich von 1000 µs to 2000 µs die Schaltung auf "AN" geht.

Ich habe Dir mal einen Interrupt-Handler für ein Servosignal an Pin-2 für einen Atmega328 geschrieben.

Code ungetestet:

#include "VarSpeedServo.h"

#define SERVO_INPUTPIN 2  // Eingang Pin-2 bei Atmega328
#define SERVO_INPUTINT 0  // Interrupt 0 gehört zu Pin-2 (Atmega328)
#define SERVO_P1 10 // Servo connected to PIN 10
#define SERVO_P2 11 // Servo connected to PIN 11
#define WAIT_I 1000 // wait after init in ms


#define POS_L 20 // left endstop
#define POS_R 160 // right endstop
#define POS_O 20 // oben endstop
#define POS_U 160 // unten endstop

#define WAIT_EN 350 // wait time at endstop in ms
#define WAIT_IN 500 // wait time at each angular increment in ms


VarSpeedServo servo1; // create servo object to control a servo
VarSpeedServo servo2; // Zusatzservo für oben unten

volatile boolean activeMode=false;

void rxHandler()
{
  byte rxState = digitalRead(SERVO_INPUTPIN); // current pin state
  static unsigned long lastRuntime;
  long now=micros();
  unsigned long timeDiff=now-lastRuntime;
  lastRuntime=now;
  if (rxState==LOW) // pin is now LOW, has been HIGH before
  { // so timeDiff contains the duration of a HIGH signal
     if (timeDiff>=1600) activeMode=true;
     else activeMode=false;
  }
}



void setup()
{
servo1.attach(SERVO_P1); // attaches the servo on pin 10 to the servo object
servo1.write(POS_L); // tell servo to go to init position

servo2.attach(SERVO_P2); // attaches the servo on pin 11 to the servo object
servo2.write(POS_O); // tell servo to go to init position
attachInterrupt(SERVO_INPUTINT, rxHandler, CHANGE);

delay(WAIT_I); // wait a little bit
}


void loop()
{
  if (!activeMode) return;
int posX = 0; // variable to store the servo position
int posY = 0; // variable to store the servo position
int gotoX = (int) random(POS_L, POS_R);
int gotoY = (int) random(POS_O, POS_U);


servo1.write(gotoX,40); // tell servo to go to position in variable 'pos'
servo2.write(gotoY,10); // tell servo to go to position in variable 'pos'

delay(WAIT_IN); // waits for the servo to reach the position
}

Wenn am Eingang Servoimpulse mit einer Dauer über 1600 µs festgestellt werden, sollte der "activeMode" gesetzt werden. Ansonsten wird er abgeschaltet.

Bei Abschalten des "activeMode" macht die loop-Funktion dann gar nichts mehr und wird umgehend mit "return" verlassen, d.h. die Servos bleiben dann auf der zuletzt angesteuerten Position stehen. Falls die Servos in dem Fall in eine Mittelstellung gebracht werden sollen, müßte man das noch ergänzen.

Ich hoffe, es funktioniert so, aber ich kann es hier nicht testen.