Skocz do zawartości

Problem z drganiem serw


cinek93

Pomocna odpowiedź

Witam, mam mały problem z drganiem serw, ten wątek był często powtarzany na wielu forach, ale na żadnym nie było odpowiedzi, która by coś wyjaśniała. Programuję quadropoda (Arduino Mega), czyli robota ze czterema nogami (12serw). Jak na razie skupiłem się na samym podnoszeniu, program wygląda tak:

#include <Servo.h> 

 Servo servo1;
 Servo servo2;
 Servo servo3;
 Servo servo4;
 Servo servo5;
 Servo servo6;
 Servo servo7;
 Servo servo8;
 Servo servo9;
 Servo servo10;
 Servo servo11;
 Servo servo12;

 int v1;
 int v2;
 int v3;
 int v4;

 void setup() 
{ 
   Serial.begin(9600);
   pinMode(5, INPUT);
   servo1.attach(52);
   servo2.attach(50);
   servo3.attach(48);
   servo4.attach(44);
   servo5.attach(42);
   servo6.attach(40);
   servo7.attach(36);
   servo8.attach(34);
   servo9.attach(32);
   servo10.attach(26);
   servo11.attach(28);
   servo12.attach(24);
} 
   void up()
   {
   servo1.write(90);
   servo4.write(90);
   servo7.write(90);
   servo10.write(90);

   servo2.write(v1);
   servo5.write(v2);
   servo8.write(v2);
   servo11.write(v1);

   servo3.write(v3);
   servo6.write(v4);
   servo9.write(v4);
   servo12.write(v3);

   }

 void loop() 
{ 
 int x = pulseIn(5, LOW);
 v1 = map(x, 18900, 17700, 30, 90);   // skala wartości (x, max PWM; min PWM, min pozycja serwa; max pozycja serwa)
 v2 = map(x, 18900, 17700, 150, 90);
 v3 = map(x, 18900, 17700, 55, 90);
 v4 = map(x, 18900, 17700, 125, 90); 
   up();
   delay(15);    
} 

Wszystko ładnie śmiga tylko serwa minimalnie drgają. Musi być to związane z niestabilnym sygnałem PWM odbieranym z odbiornika RC, który ten odbiera sygnał z aparatury. Wartości PWM (1, 2, 3, 4 kanał) przy nieruchomych drążkach wyglądają tak:

Wartości zmieniają się tylko w ostatnich 2cyfrach. I teraz zadam właściwe pytanie: czy jest jakiś sposób aby program brał pod uwagę pierwsze 3cyfry, a pozostałe 2 by ignorował? To chyba naprawiłoby problem z drganiem serw, bo wartości PWM byłyby jednakowe.

__________

Komentarz dodany przez: Nawyk

Używaj, proszę, znaczników 'code'

Link do komentarza
Share on other sites

A te serwa testujesz juz w zmontowanym robocie, czy tak luzem? Bo często serwa drgają bez obciążenia, ale pod obciążeniem jest ok. Ja testowałem parę serw i praktycznie za każdym razem serwo drgało, gdy nic nie było na nim zamocowane (w sensie sam orczyk), jednak w finalnym projekcie drgania ustały.

A co do ignorowania 2 ostatnich cyfr, to jak najbardziej możesz tak zrobić - to przecież prosta operacja matematyczna.

Link do komentarza
Share on other sites

Serwa są już zamontowane, bez obciążenia jest tak samo, tutaj raczej nie chodzi o problem mechaniczny, serwo wariuje kiedy otrzymuje niestały sygnał, wcześniej ustawiłem tak, że serwa poruszały się kiedy sygnał PWM przekroczył pewną wartość np:

int x = pulseIn(5, LOW); 
if (x > 17000)
{
servo2.write(30);
servo5.write(150);
servo8.write(150);
servo11.write(30);
}

W sumie było ok i bez żadnych drgań, ale to mnie za bardzo ograniczało, więc wolałem zaprogramować to tak, że wraz ze wzrostem wartości PWM proporcjonalnie zmienia się pozycja serwa.

Mówisz że to prosta operacja matematyczna, tylko że ja się z tym bawię od niedawna i nie wszystko jest dla mnie takie oczywiste, może jakaś podpowiedź?😋

Link do komentarza
Share on other sites

Mówisz że to prosta operacja matematyczna, tylko że ja się z tym bawię od niedawna i nie wszystko jest dla mnie takie oczywiste, może jakaś podpowiedź?😋

No np tak:

 x /= 100;

czyli dzielenie całkowite przez 100, dzięki czemu pozbędziesz się ostatnich 2 cyfr. Pamiętaj tylko by w map() sobie zakresy pozmieniać odpowiednio.

Ogólnie lepszym rozwiązaniem byłoby przesunięcie bitowe (np podzielenie przez 64 albo 128), bo to tylko jeden cykl procesora, a dzielenie całkowite to już bardziej skomplikowana operacja i trwa o wiele dłużej, więc zamiast "/=" możesz użyć ">>" (tutaj masz wyjaśnione-> http://arduino.cc/en/Reference/Bitshift ).

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Zastosowałem metodę x /= 100, w sumie trochę pomogło, przy nieruchomych drążkach wartości są stałe jednak nie zawsze, są momenty kiedy wartość sygnału rośnie i maleje o 1, co powoduje drgania serw. Poza tym skala wartości zmalała, teraz zakres wynosi od 189 do 177, przez co serwa zamiast płynnie przechodzić z pozycji na pozycję, to "skaczą". Chyba muszę znaleźć jakąś lepszą metodę odczytywania sygnału RC, może jest jakiś filtr, który stabilizuje odbierany sygnał. Czy ktoś już miał z czymś podobnym do czynienia i mógłby jakoś pomóc?😉

Link do komentarza
Share on other sites

Musi być to związane z niestabilnym sygnałem PWM odbieranym z odbiornika RC, który ten odbiera sygnał z aparatury.

Używasz PPMa czy ja to się tam zwie ?

Na drgania serv, ma często także wpływ zasilnie, konkretnie jego sztywność. Ogólnie problem z którym modelarze walczą chyba od zalania dziejów.

Link do komentarza
Share on other sites

Musi być to związane z niestabilnym sygnałem PWM odbieranym z odbiornika RC, który ten odbiera sygnał z aparatury.

Używasz PPMa czy ja to się tam zwie ?

Na drgania serv, ma często także wpływ zasilnie, konkretnie jego sztywność. Ogólnie problem z którym modelarze walczą chyba od zalania dziejów.

Tak to jest PPM, tylko odbiornik używa pinów PWM. Jestem pewny, że to nie przez zasilanie.

[ Dodano: 15-06-2012, 20:37 ]

Udało się!!!😃 Znalazłem program, który konwertuje sygnał PPM na PWM (ten ostatni kod), naniosłem drobne poprawki i teraz śmiga jak ta lala:

#include <Servo.h> 

 Servo servo1;
 Servo servo2;
 Servo servo3;
 Servo servo4;
 Servo servo5;
 Servo servo6;
 Servo servo7;
 Servo servo8;
 Servo servo9;
 Servo servo10;
 Servo servo11;
 Servo servo12;

 volatile int RXSG[4];
 int RXCH[4]; 
 int RXOK[4];
 int PWMSG[4];

 int v1;
 int v2;
 int v3;
 int v4;

 void setup() 
{ 
   Serial.begin(57600); 

   RXCH[1] = 33;
   RXCH[2] = 35;
   RXCH[3] = 37;
   RXCH[4] = 39;

   servo1.attach(52);
   servo2.attach(50);
   servo3.attach(48);
   servo4.attach(44);
   servo5.attach(42);
   servo6.attach(40);
   servo7.attach(36);
   servo8.attach(34);
   servo9.attach(32);
   servo10.attach(26);
   servo11.attach(28);
   servo12.attach(24);
} 

   void PPMtoPWM()
   {
   RXSG[3] = pulseIn(RXCH[3], LOW, 20000);
     if (RXSG[3] == 0)     
       {
         RXSG[3] = RXOK[3];
       } 
     else 
       {
     RXOK[3] = RXSG[3];
       }    
   PWMSG[3] = map(RXSG[3], 17700, 19000, 0, 511);
   constrain (PWMSG[3], 0, 511);	
   }

   void up()
   {
   servo1.write(90);
   servo4.write(90);
   servo7.write(90);
   servo10.write(90);

   servo2.write(v1);
   servo5.write(v2);
   servo8.write(v2);
   servo11.write(v1);

   servo3.write(v3);
   servo6.write(v4);
   servo9.write(v4);
   servo12.write(v3);

   }

 void loop() 
{ 
 PPMtoPWM();
 v1 = map(PWMSG[3], 0, 511, 30, 120); 
 v2 = map(PWMSG[3], 0, 511, 150, 60);
 v3 = map(PWMSG[3], 0, 511, 55, 120);
 v4 = map(PWMSG[3], 0, 511, 125, 60); 
   up();
   delay(15);  

} 

Jakby ktoś miał kiedyś problem z odczytywaniem sygnału z odbiornika RC, tutaj dam gotowe programy.

Odczytywanie sygnału PPM:

void setup()
{
Serial.begin(9600);
// 33,35,37,39 to Digital Piny
// nie polecam Pinów PWM, bo sygnał jest wtedy mniej stabilny
pinMode(33, INPUT);  // kanał 1
pinMode(35, INPUT);  // kanał 2
pinMode(37, INPUT);  // kanał 3
pinMode(39, INPUT);  // kanał 4
}
void loop()
{
 {
   //HIGH można zmienić na LOW, wtedy wartości PPM, będą inne
   int v1 = pulseIn(33, HIGH);
   int v2 = pulseIn(35, HIGH);
   int v3 = pulseIn(37, HIGH);
   int v4 = pulseIn(39, HIGH);

   Serial.print(v1);
   Serial.print("     ");
   Serial.print(v2);
   Serial.print("     ");
   Serial.print(v3);
   Serial.print("     ");
   Serial.print(v4);
 }
   Serial.println("");
}

Jeśli znamy wartości PPM max i min, to możemy przekonwertować go na PWM i odczytywać ten sygnał:

//Reads PPM signals from 4 channels of an RC reciever, translates the values to
//PWM and prints the values to serial port.
//Works with Spectrum DX7 (haven't tested anything else) -> moja apka Hitec Laser 4 również ładnie śmiga;)

//Create variables for 4 channels -> jeśli ilość kanałów jest inna niż "4", zmień tą wartość
int RXCH[4]; 
volatile int RXSG[4];
int RXOK[4];
int PWMSG[4];

void setup() {

 //Start communication to serial port
 Serial.begin(115200);  

 //Assign PPM input pins. The receiver output pins are conected as below to non-PWM Digital connectors
 // <- RXCH[numer kanału] = odpowiedni Digital Pin do którego jest podpięty poszczególny kanał odbiornika RC, (nie PWM Pin!)

 RXCH[1] = 33;
 RXCH[2] = 35;
 RXCH[3] = 37;
 RXCH[4] = 39;

 for (int i = 1; i < 5; i++)
 {
   pinMode(RXCH[i], INPUT);
 }

}

void loop() {

// Read RX values
 for (int i = 1; i < 5; i++)                //for each of the 4 channels: 
 {					     // <- jeśli odbiornik ma 3 kanały, zmień wartość "5" na "4", jeśli 5 kanałów to z "5" na "6" etc.
 RXSG[i] = pulseIn(RXCH[i], LOW, 20000);   //read the receiver signal, 
                                            // <- LOW można zmienić na HIGH, wtedy zmienią się wartości PPM
 if (RXSG[i] == 0)     //if the signal is good then use it
   {
     RXSG[i] = RXOK[i];
   } 
 else     //else use the previous signal
   {
     RXOK[i] = RXSG[i];
   }                                        
 PWMSG[i] = map(RXSG[i], 17700, 19000, 0, 511);	//substitute the high values to a value between 0 and 511 
                                               // <- można zmienić zakres wartości PPM: PWMSG[i] = map(RXSG[i], min PPM, max PPM, 0, 511);	
 constrain (PWMSG[i], 0, 511);			//make sure that the value stays within the disired boundries

// Print RX values

 Serial.print(PWMSG[i]);
 Serial.print("     ");
 delay(5);  
}
Serial.println();
} 

Co prawda drgań serw nie wyeliminowałem w 100%, teraz pozycja zmienia się minimalnie o +-1 stopień, ale to nic w porównaniu z tym co było wcześniej;) Jeszcze popracuję nad tym, aby całkowicie je usunąć.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.