Go Down

Topic: Hilfe bei der Servo Steuerung (Read 2091 times) previous topic - next topic

Lept0pp

Jan 08, 2013, 12:54 am Last Edit: Jan 08, 2013, 12:57 am by Lept0pp Reason: 1
he ihr. ich habe berreits meinen code fertig.
ich möchte 2 servos gleichzeitig ansteuern mit einer sprachsteuerung.
funktioniert alles auch super, nur dass die servos nacheinander reagieren. ich weis der fehler liegt darran das in meinem action part die befehle so aufgeführt sind dass sie nacheinander abgearbeitet werden, aber ich weis nicht wie ich sie zeitgleich ausführen kann. kann mir da jmd helfen ? bitte^^  =(

hier mal mein code ab action:

void action()
{
   switch (group)
   {
   case GROUP_0:
     switch (idx)
     {
     case G0_JARVIS:
       // write your action code here
       group = GROUP_1;
       // group = GROUP_X;
       break;
     }
     break;
   case GROUP_1:
     switch (idx)
     {
     case G1_HELM_AUF:
     
       for(pos = 90; pos < 180; pos += 1)
       {                                  
         myservo.write(pos);            
         delay(40);  
       }        
       for(pos2 = 10; pos2 < 100; pos2 += 1)
       {
         myservo2.write(pos2);
         delay(40);
       }
       
       group = GROUP_0;
       // group = GROUP_X;
       break;
     case G1_HELM_ZU:
       // write your action code here
       for(pos = 180; pos>=90; pos-=1)    
       {                                
         myservo.write(pos);              
         delay(40);            
       }
       for(pos2 = 100; pos2>=10; pos2-=1)
       {
         myservo2.write(pos2);
         delay(40);
       }
       
       
       group = GROUP_0;
       // group = GROUP_X;
       break;
     }
     break;
   }
}

sui

Naja, zeitgleich geht nicht, aber Du kannst die Servos abwechselnd je um 1° bewegen.

Code: [Select]

for (int i=0; i<90; i++) {   // Drehung um 90°
myservo.write(pos+90);  // 1.Servo von 90°-180°
myservo2.write(pos+10);  // 2.Servo von 10°-100°
delay(80);
}

mde110

Dein Programm ist momentan so wie Blink aufgebaut.
Du müsstest dein Programm grundsätzlich ändern, um den von dir gewünschten Effekt zu erhalten.

Die for Schleifen müssen mit den Delays raus.
Dann müsstest du die Position der Servos mit Hilfe der Funktion millis() errechnen.
Ziel ist es dein Programm wie das Beispiel aufzubauen: BlinkWithoutDelay

Lept0pp

denke ich versuch erstmal suis version aus^^
danke schonmal. mal sehen obs klappt.
aber wo ist bei deinem vorschlag die stelle wo se sich abwechselnd um 1° bewegen?

uwefed

Hier:
Code: [Select]
myservo.write(pos+90);  // 1.Servo von 90°-180°
myservo2.write(pos+10);  // 2.Servo von 10°-100°

Lept0pp

ok ich bin jetzt wieder zurrück zu meinem code gegangen. irgendwie konnte ich den helm nicht mehr schließen lassen mit dem vorgeschlagenem code. danke trotzdem

Lept0pp

ich weis es ist umständlich und braucht viel speicher, aber ich habe es jetzt so gelöst, dass ich einfach die befehle wiederhole und die servos abwechseln um 1 ° bewegen lasse.
bei dem vorschlag von euch schnellen die servos auf die grad zahl (ich brauche aber eine langsame gleichmäßige bewegung).
am geschicktesten wäre es, wenn es ginge das so zu schreiben:
Es wird eine ausgangspossition angegeben, dann wird +1! dazu addiert und die neue position ausgelesen.
dannach das gleiche für den 2. servo und im anschluss das ganze wieder von anfang an wiederholen (schleife eben).
am ende dann wenn eine bestimmte gradzahl erreicht ist, wird die schleife beendet.
ne schleife ist leicht ich weis, aber ich scheiter heute echt an allem -.-

mde110

Ich habe mich bezüglich deiner Aufgabenstellung wohl geirrt. Ich habe angenommen, du möchtest zwei unterschiedliche Bewegungen kombinieren.

Poste doch mal deinen Sketch, indem die Servos gleich auf die Endposition fahren. Da lässt sich sicher was finden.

qualidat

#8
Jan 09, 2013, 08:57 am Last Edit: Jan 09, 2013, 08:59 am by qualidat Reason: 1
Wenn du ein par Euro mehr in die Hand nimmst und gleich mit digitalen Servos arbeitest, erlangst du in deinem Programm erheblich mehr Freiheiten und das Timing entspannt sich drastisch. Digitalen Servos genügen bereits 10..20 Pulse um zu "verstehen", welche Position sie anfahren sollen. Desweiteren speichern sie diese Zielposition und wenn für eine Weile gar keine Pulse mehr kommen, halten Sie diese trotzdem und ruckeln nicht!

Du kannst also die Pulsausgabe ganz entspannt in eine Funkton packen und nahezu beliebig "selten" aufrufen ... (Servonummer und Stellwert als Parameter)
Dann werden deine Servos trotdem noch nacheinander angesteuert, aber z.B. 10 ms Unterschied sind ohne Messmittel bestimmt nicht wahrnehmbar.

Lept0pp

#9
Jan 09, 2013, 12:59 pm Last Edit: Jan 09, 2013, 01:01 pm by Lept0pp Reason: 1
also zur entwirrung:
ich habe in einem helm 2 servos seitlich die die klappe des helmes bei dem kommando "helm auf" öffnen sollen.
dazu muss der eine im und der andere gegen den uhrzeigersinn drehen.
icb rauche 90 ° und habe 2 digitale servos.

hier mal mein ganzer code:
wie mann sieht habe ich sehr viel aus den beispielen einfach übernommen
Code: [Select]
#if defined(ARDUINO) && ARDUINO >= 100
 #include "Arduino.h"
 #include "SoftwareSerial.h"
 SoftwareSerial port(12,13);
#else // Arduino 0022 - use modified NewSoftSerial
 #include "WProgram.h"
 #include "NewSoftSerial.h"
 NewSoftSerial port(12,13);
#endif

#include <Servo.h>  // Eingefügter Servo
Servo myservo2;
#include <Servo.h>  // Eingefügter Servo
Servo myservo;
#include "EasyVR.h"
EasyVR easyvr(port);

int pos = 0;    // variable to store the servo position
int pos2 = 0;
//Groups and Commands
enum Groups
{
 GROUP_0  = 0,
 GROUP_1  = 1,
};

enum Group0
{
 G0_JARVIS = 0,
};

enum Group1
{
 G1_HELM_AUF = 0,
 G1_HELM_ZU = 1,
};


EasyVRBridge bridge;

int8_t group, idx;

void setup()
{
 // bridge mode?
 if (bridge.check())
 {
   cli();
   bridge.loop(0, 1, 12, 13);
 }
 // run normally
 Serial.begin(9600);
 port.begin(9600);

 if (!easyvr.detect())
 {
   Serial.println("EasyVR not detected!");
   for (;;);
 }

 easyvr.setPinOutput(EasyVR::IO1, LOW);
 Serial.println("EasyVR detected!");
 easyvr.setTimeout(5);
 easyvr.setLanguage(3);

 group = EasyVR::TRIGGER; //<-- start group (customize)
 myservo2.attach(7);
 myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}
void action();

void loop()
{
 easyvr.setPinOutput(EasyVR::IO1, HIGH); // LED on (listening)

 Serial.print("Say a command in Group ");
 Serial.println(group);
 easyvr.recognizeCommand(group);

 do
 {
   // can do some processing while waiting for a spoken command
 }
 while (!easyvr.hasFinished());
 
 easyvr.setPinOutput(EasyVR::IO1, LOW); // LED off

 idx = easyvr.getWord();
 if (idx >= 0)
 {
   // built-in trigger (ROBOT)
   // group = GROUP_X; <-- jump to another group X
   return;
 }
 idx = easyvr.getCommand();
 if (idx >= 0)
 {
   // print debug message
   uint8_t train = 0;
   char name[32];
   Serial.print("Command: ");
   Serial.print(idx);
   if (easyvr.dumpCommand(group, idx, name, train))
   {
     Serial.print(" = ");
     Serial.println(name);
   }
   else
     Serial.println();
   easyvr.playSound(0, EasyVR::VOL_FULL);
   // perform some action
   action();
 }
 else // errors or timeout
 {
   if (easyvr.isTimeout())
     Serial.println("Timed out, try again...");
   int16_t err = easyvr.getError();
   if (err >= 0)
   {
     Serial.print("Error ");
     Serial.println(err, HEX);
   }
 }
}

void action()
{
   switch (group)
   {
   case GROUP_0:
     switch (idx)
     {
     case G0_JARVIS:
       // write your action code here
       group = GROUP_1;
       // group = GROUP_X; <-- or jump to another group X for composite commands
       break;
     }
     break;
   case GROUP_1:
     switch (idx)
     {
     case G1_HELM_AUF:
       // write your action code here
       for(pos = 90; 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(40);  
       }        
       for(pos2 = 10; pos2 < 100; pos2 += 1)
       {
         myservo2.write(pos2);
         delay(40);
       }
       
       group = GROUP_0;
       // group = GROUP_X; <-- or jump to another group X for composite commands
       break;
     case G1_HELM_ZU:
       // write your action code here
       for(pos = 180; pos>=90; pos-=1)     // goes from 180 degrees to 0 degrees
       {                                
         myservo.write(pos);              // tell servo to go to position in variable 'pos'
         delay(40);             // waits 15ms for the servo to reach the position
       }
       for(pos2 = 100; pos2>=10; pos2-=1)
       {
         myservo2.write(pos2);
         delay(40);
       }
       
       
       group = GROUP_0;
       // group = GROUP_X; <-- or jump to another group X for composite commands
       break;
     }
     break;
   }
}


diverse kommentare auf deutsch und englisch und verschobene, hab ich einfach drinnen gelassen, war mir zu doof die alle rauszusuchen^^

Lept0pp


Wenn du ein par Euro mehr in die Hand nimmst und gleich mit digitalen Servos arbeitest, erlangst du in deinem Programm erheblich mehr Freiheiten und das Timing entspannt sich drastisch. Digitalen Servos genügen bereits 10..20 Pulse um zu "verstehen", welche Position sie anfahren sollen. Desweiteren speichern sie diese Zielposition und wenn für eine Weile gar keine Pulse mehr kommen, halten Sie diese trotzdem und ruckeln nicht!

Du kannst also die Pulsausgabe ganz entspannt in eine Funkton packen und nahezu beliebig "selten" aufrufen ... (Servonummer und Stellwert als Parameter)
Dann werden deine Servos trotdem noch nacheinander angesteuert, aber z.B. 10 ms Unterschied sind ohne Messmittel bestimmt nicht wahrnehmbar.


oh momment mal, kann es desshalb sein dass sie ab und zu mal nen kleinen ruckler von sich geben?
dachte des sei einfach ein impuls der vom board kommt damit mann sieht das die servos den befehl bekommen.
so ein ruckeln hab ich immer dann, wenn das board irgendwas tut: also befehl erhalten, befehl fehlerhaft ausgesprochen usw.

Lept0pp

also ich habe mir etz mal ordendliche servos zugelegt, sogar welche die sowol analog als auch digital sind also ist es egal ;)

ich habe nur noch immer ein probleme mitm einem code. die billigen servos haben mit folgendem code funktioniert:
Code: [Select]
#if defined(ARDUINO) && ARDUINO >= 100
  #include "Arduino.h"
  #include "SoftwareSerial.h"
  SoftwareSerial port(12,13);
#else // Arduino 0022 - use modified NewSoftSerial
  #include "WProgram.h"
  #include "NewSoftSerial.h"
  NewSoftSerial port(12,13);
#endif

#include <Servo.h>  // Eingefügter Servo
Servo myservo2;
#include <Servo.h>  // Eingefügter Servo
Servo myservo;
#include "EasyVR.h"
EasyVR easyvr(port);

int pos = 0;    // variable to store the servo position
int pos2 = 60;
//Groups and Commands
enum Groups
{
  GROUP_0  = 0,
  GROUP_1  = 1,
};

enum Group0
{
  G0_JARVIS = 0,
};

enum Group1
{
  G1_HELM_AUF = 0,
  G1_HELM_ZU = 1,
};


EasyVRBridge bridge;

int8_t group, idx;

void setup()
{
  // bridge mode?
  if (bridge.check())
  {
    cli();
    bridge.loop(0, 1, 12, 13);
  }
  // run normally
  Serial.begin(9600);
  port.begin(9600);

  if (!easyvr.detect())
  {
    Serial.println("EasyVR not detected!");
    for (;;);
  }

  easyvr.setPinOutput(EasyVR::IO1, LOW);
  Serial.println("EasyVR detected!");
  easyvr.setTimeout(5);
  easyvr.setLanguage(3);

  group = EasyVR::TRIGGER; //<-- start group (customize)
  myservo2.attach(7);
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}
void action();

void loop()
{
  easyvr.setPinOutput(EasyVR::IO1, HIGH); // LED on (listening)

  Serial.print("Say a command in Group ");
  Serial.println(group);
  easyvr.recognizeCommand(group);

  do
  {
    // can do some processing while waiting for a spoken command
  }
  while (!easyvr.hasFinished());
 
  easyvr.setPinOutput(EasyVR::IO1, LOW); // LED off

  idx = easyvr.getWord();
  if (idx >= 0)
  {
    // built-in trigger (ROBOT)
    // group = GROUP_X; <-- jump to another group X
    return;
  }
  idx = easyvr.getCommand();
  if (idx >= 0)
  {
    // print debug message
    uint8_t train = 0;
    char name[32];
    Serial.print("Command: ");
    Serial.print(idx);
    if (easyvr.dumpCommand(group, idx, name, train))
    {
      Serial.print(" = ");
      Serial.println(name);
    }
    else
      Serial.println();
    easyvr.playSound(0, EasyVR::VOL_FULL);
    // perform some action
    action();
  }
  else // errors or timeout
  {
    if (easyvr.isTimeout())
      Serial.println("Timed out, try again...");
    int16_t err = easyvr.getError();
    if (err >= 0)
    {
      Serial.print("Error ");
      Serial.println(err, HEX);
    }
  }
}

void action()
{
    switch (group)
    {
    case GROUP_0:
      switch (idx)
      {
      case G0_JARVIS:
        // write your action code here
        group = GROUP_1;
        // group = GROUP_X; <-- or jump to another group X for composite commands
        break;
      }
      break;
    case GROUP_1:
      switch (idx)
      {
      case G1_HELM_AUF:
        // write your action code here
        {
          myservo.write(pos+60);  // 1.Servo von 90°-180°
          myservo2.write(pos2-60);  // 2.Servo von 10°-100°
         
        }
       
        // HELM ZU !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       
        group = GROUP_0;
        // group = GROUP_X; <-- or jump to another group X for composite commands
        break;
      case G1_HELM_ZU:
        // write your action code here
          myservo.write(pos);  // 1.Servo von 90°-180°
          myservo2.write(pos2);  // 2.Servo von 10°-100°
       
        group = GROUP_0;
        // group = GROUP_X; <-- or jump to another group X for composite commands
        break;
      }
      break;
    }
}


die neuen zicken da aber rumm, funktionieren allerdings mit dem alten code:
hier nur der action berreich:
Code: [Select]
case G1_HELM_AUF:
        // write your action code here
        for(pos = 90; 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(40); 
        }       
        for(pos2 = 10; pos2 < 100; pos2 += 1)
        {
          myservo2.write(pos2);
          delay(40);
        }
       
        group = GROUP_0;
        // group = GROUP_X; <-- or jump to another group X for composite commands
        break;
      case G1_HELM_ZU:
        // write your action code here
        for(pos = 180; pos>=90; pos-=1)     // goes from 180 degrees to 0 degrees
        {                               
          myservo.write(pos);              // tell servo to go to position in variable 'pos'
          delay(40);             // waits 15ms for the servo to reach the position
        }
        for(pos2 = 100; pos2>=10; pos2-=1)
        {
          myservo2.write(pos2);
          delay(40);
        }
       


beid dem letzten code wird ja leider jeder servo einzelt angesteuert und sie bewegen sich nacheinander.
ich brauche es ja aber dass beide gleichzeitig drehen (was mit dem ersten code nicht funktioniert.

Lept0pp

ich dneke ich sollte es einfach sein lassen. in einer woche muss ich fertig sein und nichts funktioniert, selbst nach mehrfachem nachlesen in allen möglichen anleitungen

mkl0815

wie wäre es einfach statt mit:
Code: [Select]

for(pos = 90; 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(40); 
        }       
        for(pos2 = 10; pos2 < 100; pos2 += 1)
        {
          myservo2.write(pos2);
          delay(40);
        }

mit
Code: [Select]

for(pos = 90; 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'
          myservo2.write((pos - 80));
          delay(40); 
        }       

dann zählt die pos von 90 bis 180 und der zweite server bekommt die werte mit jeweils -80 serviert, zählt also von 10 bis 100.
Mario.

Lept0pp

danke, werd ich gleich mal ausprobieren, denke die neuen servos kann ich eh vergessen.
die verändern ständig ihre posi von alleine

Go Up