Skocz do zawartości

Kurs Arduino - #5 - PWM, serwomechanizmy, biblioteki


Pomocna odpowiedź

fire45, tak spokojnie można mieć podpięte oba źródła. Arduino ma wewnętrznie połączone masy USB oraz złącza zasilania.

Czy serwo Tower Pro Micro 9g SG90 powinno tak delikatnie "wibrować" w oczekiwaniu

na zmianę np. oświetlenia fotorezystora przy jednym z zadań kursu?

fire45, tak, serwa te są stosunkowo tanie przez co nie są zbyt precyzyjne. Jeśli drgania są małe, to nie trzeba się nimi przejmować.

Cześć! Dopiero co kupiłem zestaw i powoli sobie próbuję

(po pierwsze, wielki szacunek za kurs, jest świetnie, więc brnę dalej 😃 )

Na pewno już były dobre rozwiązania, ale podpinam też swoje

5.4

#include <Servo.h> //Biblioteka odpowiedzialna za serwa

Servo serwomechanizm;  //Tworzymy obiekt, dzięki któremu możemy odwołać się do serwa 
String wpis = "";//wpisana pozycja
int intwpis = 0;//wpisana pozycja w int
boolean start = true;//podejście po wpisaniu liczby z 0-180 bądź nie
void setup() 
{ 
 Serial.begin(9600);
 serwomechanizm.attach(9);  //Serwomechanizm podłączony do pinu 9

} 

void loop() 
{  
 while (start == true)//kiedy podano liczbe 0-180
 {
   Serial.println("Podaj pozycje, do ktorej serwomechanizm ma sie obrocic (wpisujac liczbe)");
   //po otwarciu programu podaj prośbę o podanie pozycji
   while(Serial.available() == 0)//poczekaj na wpisanie pozycji
   {}
   if(Serial.available() > 0)//jeśli pozycja zostanie wpisana
   {
      wpis = Serial.readStringUntil('\n');//odczytaj pozycje
      intwpis = wpis.toInt();//zamien na typ int
      Serial.println("Wybrana pozycja:");//pokazuje wybraną pozycje
      Serial.println(intwpis);

       if((intwpis >= 0) && (intwpis <= 180))//jeśli należy do 0-180
       {
         serwomechanizm.write(intwpis);//wykonaj przesuniecie na dana pozycje
         start = true;//podano prawidlową pozycję
       }
       else//kiedy podano złą pozycję
       {
         Serial.println("Musisz podac liczbe z przedzialu 0 - 180. Sprobuj ponownie!");
         start = false;//podano złą pozycję
       }
     }
   }
 while (start == false)//po podaniu złej pozycji
 { 
   while(Serial.available() == 0)//poczekaj na wpisanie pozycji
   {}
   if(Serial.available() > 0)//jeśli pozycja zostanie wpisana
   {
     wpis = Serial.readStringUntil('\n');//odczytaj pozycje
     intwpis = wpis.toInt();//zamien na typ int
     Serial.println("Wybrana pozycja:");
     Serial.println(intwpis);
     if((intwpis >= 0) && (intwpis <= 180))
     {
       serwomechanizm.write(intwpis);//wykonaj przesuniecie na dana pozycje
       start = true;
     }
     else
     {
       Serial.println("Musisz podac liczbe z przedzialu 0 - 180. Sprobuj ponownie!");
       start = false;  
     }
   }
 }
}

pewnie można jakoś prościej, ale działa

5.5

#include <Servo.h>//biblioteka
Servo serwomechanizm;//obiekt - serwo
#define potencjometr A5
int odczytPotencjometru;
int odczytPrzeskalowany;
void setup() {
 serwomechanizm.attach(9);
}

void loop() {
 odczytPotencjometru = analogRead(A5); //odczytujemy wartość napięcia
 odczytPrzeskalowany = map(odczytPotencjometru, 0, 1023, 0, 180);
 //przeskalowujemy odczytaną wartość na liczby 0-180 ~ pozycję serwo
 serwomechanizm.write(odczytPrzeskalowany); //ustawiamy serwo w wybranej pozycji
 delay(100); //małe opóźnienie
}

a tak poza tym to jeszcze pytanko:

na obrazkach widziałem, że ze stabilizatorem zazwyczaj były podpinane dwa kondensatory bezbiegunowe

w swoim zestawie dostałem tylko jeden taki (ten pomarańczowy mały okrągły) i drugi biegunowy; podłączyłem je i działa, tylko nie wiem czy "lepiej" by było dwa takie same czy jak to zmienia sytuację?

(zielony jestem w elektronice praktycznej jakby co 😉

na obrazkach widziałem, że ze stabilizatorem zazwyczaj były podpinane dwa kondensatory bezbiegunowe

w swoim zestawie dostałem tylko jeden taki (ten pomarańczowy mały okrągły) i drugi biegunowy; podłączyłem je i działa, tylko nie wiem czy "lepiej" by było dwa takie same czy jak to zmienia sytuację?

Kondensator biegunowy (elektrolityczny) również dobrze się tutaj sprawdza. Oczywiście pod warunkiem, że podłączysz go odpowiednio. W wolnej chwili poczytaj kurs elektroniki, wtedy będziesz lepiej obeznany z tym tematem. Bez podstaw możesz przypadkiem uszkodzić Arduino: Kurs elektroniki – #1 – napięcie, prąd, opór, zasilanie 😉

wiem wiem, uważałem na to, gdzie ma minus i plus, tylko nie wiedziałem czy to znacząco coś zmienia, ale chyba nie

Czytałem już trochę, ale jeszcze na pewno będę zaglądał 😉 dzięki

Na wstępie witam wszystkich oraz składam podziękowania na ręce autora za przygotowanie super kursu. Od około tygodnia pilnie korzystam z kursu i do tej pory na forum byłem tylko obserwatorem ponieważ wszystko działało. Tym razem napotkałem problem którego nie mogę sam rozwiązać:

Moje serwo drży w pozycji w zakresie 0-10, im wartość bliższa 0 tym mocniej drży, przy wartości 0 prawie podskakuje.

5.5:

#include <Servo.h> //Biblioteka odpowiedzialna za serwa

Servo serwo;  // wprowadzam obiekt serwo
int poz = 0; // pozycja serwa
int zmiana = 0; // wprowadzam zmienną z informacją o zmianie pozycji

void setup() 
{ 
 serwo.attach(9);  // deklaruję serwo na 9 pinie
 Serial.begin(9600);
} 

void loop() 
{  

 zmiana = analogRead(A1);  // odczytuję wartość z potencjometru podłączonego do pinu A1
 Serial.println(zmiana);  //  dodatkowa informacja dla mnie aby znac pozycje serwa do rozwiązani problemu z drżeniem
 zmiana = map(zmiana, 0, 1023, 0, 180);  // skaluję odczyt z potencjomtru


 serwo.write(zmiana);  // steruje serwinechanizmem

}

Przy zadaniu 5.4 takie samy objawy.

Aby rozwikłać problem próbowałem:

zasilanie z baterii 9V jak również zasilacz 12V 2A

elektrolity przy stabilizatorze 100uF (akurat takie miałem)

takie samy objawy na klonie Arduino duo jak również na oryginalnym Arduino Duemilanove.

Dopisałem dodatkową linijkę w wyświetlaniem wartości zmiennej do której podstawiam przeskalowaną wartość odczytaną z potencjometru. Przy odłączonym zasilaniu serwa wszystko stabilnie się wyświetla (np 0 dla maksymalnie skręconego potencjometru), po podłączeniu zasilania wyniki zaczynają wariować w zakresie 0-23. Wygląda jak by serwo w skrajnym położeniu zakłócało pomiar sygnału analogowego, przy wartości 180 żadne zakłócenia nie występują.

__________

Komentarz dodany przez: Treker

Poprawiłem tagi z na . Pamiętaj proszę na przyszłość 🙂

endras, akurat tutaj bym się nie przejmował tym problemem, tylko odpowiednio przeskalował wartości, aby uniknąć działania w tych skrajnych warunkach. Zarówno serwomechanizm jak i potencjometr w skrajnych wartościach może być trochę nieprzewidywalny.

Tutaj wina jest zapewne po stronie serwomechanizmu. Jeśli użyłeś taniego serwa, to sterownik w jego wnętrzu pewnie nie jest zbyt idealny i może sobie nie radzić ze zbyt krótkimi lub zbyt długimi impulsami. Stąd pewne ogłupienie/drgania.

Dzięki za odpowiedź. Przeskalowałem w zakresie 11-180 i jest ok, po za tym że ograniczyłem o 1/18 zakres ruchu serva (ale w sumie czego wymagać od serva za 7zł).

Bardziej mnie zastanawia w jaki sposób serwo wpływa na odczyt z potencjometru? Bo jednak po odłączeniu zasilania serva, wartość odczytywana z potencjometru jest stabilna.

endras, sprawdź miernikiem co dzieje się z napięciem, gdy masz podłączony serwomechanizm. Może źródło jest zbyt słabe i napięcie wyraźnie spada?

Źródło to zasilacz 2A więc raczej odpada, ale kupiłem dziś kilka różnych serw do zabawy (w tym między innymi dokładnie takie samo SG90) i w żadnym z nich nic takiego się nie dzieje. Po prostu miałem pecha z tym pierwszym a że dociekliwy jestem szukałem przyczyny. Teraz już będę spał spokojnie i mogę przejść do kolejnej części kursu 😉 Dzięki za pomoc.

Cześć, chciałem rozwiązać zadanie 5.2 z wykorzystaniem zmiennej bool, wydaje mi się, że ona do tego typu rzeczy służy. Jednak nie bardzo wiem jak z niej korzystać.

Napisałem program tak jak mi się wydaje, że można z bool'a korzystać ale niestety nie działa poprawnie, dioda powoli rozświetla się do maksimum ale nie chce ściemnieć.

#define diodaPIN 3

byte wypelnienie = 0;
int zmiana = 1;
bool kierunek = false;

void setup() {
 pinMode(diodaPIN, OUTPUT);

}

void loop() {
 if (wypelnienie == 255){
   kierunek = true;
 }
 if (wypelnienie == 0){
   kierunek = false;
 }
 if (kierunek == false){
   wypelnienie = wypelnienie + zmiana;
 }
 if (kierunek == true){
   wypelnienie = wypelnienie - zmiana;
 }
 analogWrite(diodaPIN, wypelnienie);
 delay(50);
}

Od razu przepraszam za brak komentarzy ale wszystko jest chyba oczywiste.

hawaya, wykorzystaj UART do pomocy. Wyświetlaj sobie przy każdym obiegu pętli wartość zmiennej kierunek oraz wypelnienie. Zobacz, co się dzieje, gdy dioda będzie świeciła już maksymalnie jasno. Daj znać, jakie wnioski z tego wyciągnąłeś 🙂

Treker, nie wiem co o tym myśleć. Zrobiłem tak jak kazałeś. Poza dopisaniem trzech linijek do UARTa nie zmieniłem w kodzie absolutnie nic a nagle zaczęło działać tak jak chciałem ...

Jedyne co zaobserwowałem to, że dioda świeci się maksymalnie przy wypełnieniu równym ok. 120 (mam rezystor 220 Ohm) więc może po prostu nie zauważyłem kiedy dioda ciemniała bo większość czasu świeciła się maksymalnie. Wydaje mi się to jednak bardzo mało prawdopodobne bo bardzo uważnie jej się wczoraj przyglądałem.

Tak czy siak teraz już steruję serwem i jest super 🙂 dzięki za odpowiedź.

  • Lubię! 1

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...