Skocz do zawartości
Komentator

Kurs Arduino - #5 - PWM, serwomechanizmy, biblioteki

Pomocna odpowiedź

22 godziny temu, Slowik napisał:

serwo wychyla się o jakieś 90 stopni po czym wraca do pozycji początkowej

Po zaniku sygnału sterującego takie zjawiska mogą się dziać. Można temu próbować zaradzić odcinając najpierw zasilanie serwa.

Fajnie, że robisz zadania i umieszczasz komentarze w kodach 🙂 Powodzenia z kolejnymi zadaniami!

Udostępnij ten post


Link to post
Share on other sites

Witam wszystkich,

Jaka jest poprawna odpowiedź na 5.1?  Zawsze można skorzystać z modulo, ale upraszcza to jedynie zapis 😞

 

Udostępnij ten post


Link to post
Share on other sites

@BlackWraith67 witam na forum 🙂

Tak można w ten sposób, możesz też przekręcić 8 bitową zmienną. Próbuj 🙂 To zadanie, żeby spróbować własnych sił.

Udostępnij ten post


Link to post
Share on other sites

Cześć,

Podłączyłem wszystko jak jest na schemacie, a mimo wszystko serwo się  nie porusza. Czy są jakieś prostsze sposoby zeby sprawdzić co jest nie tak niz przepinanie kabli :)?

IMG_20200712_193715.jpg

IMG_20200712_193709.jpg

Udostępnij ten post


Link to post
Share on other sites

@SzejN witam na forum 🙂 A jak na chwilę odepniesz z wtyczki serwka zasilanie i przytkniesz je do pinu 5V Arduino to coś się dzieje? Serwo na chwilę się poruszy czy coś?

Udostępnij ten post


Link to post
Share on other sites

Zadanie 5.1 Zmienna byte obsługuje wartości od 0 do 255. Jeśli zmienimy typ zmiennej wypelnienie z int na byte to możemy usunąć instrukcję warunkową if, ponieważ wypełnienie będzie się automatycznie zerowało po osiągnięciu maksymalnej wartości dozwolonej, czyli 255. 

Zadanie 5.2

#define Dioda 3  //przypisanie nazwy Dioda do elementu podpiętego pod pin 3

int wypelnienie = 0;
int zmiana = 5;

void setup() {

  Serial.begin(9600);    //rozpoczęcie komunikacji przez UART
  pinMode(Dioda, OUTPUT); //ustawienie pinu 3 jako OUTPUT
}

void loop() {
  analogWrite(Dioda, wypelnienie);   //nadpisanie w aktualnym stanie wartosci wypelnienia do Diody

while (wypelnienie != 255) {
  analogWrite(Dioda, wypelnienie);  //ROZŚWIETLANIE
  wypelnienie += zmiana;            //zmiana aktualnego poziomu wypelnienia poprzez zwiekszenie o zadany próg
  Serial.print(wypelnienie); Serial.print("\n"); 

  delay(50);
}

while (wypelnienie != 0) {
  analogWrite(Dioda, wypelnienie);  //PRZYCIEMNIANIE
  wypelnienie -= zmiana;            //zmiana aktualnego poziomu wypelnienia poprzez zmniejszenie o zadany próg
  Serial.print(wypelnienie); Serial.print("\n"); 

  delay(50);
}

Serial.print(wypelnienie); Serial.print("\n");  //wyświetlenie aktualnej wartości wypełnienia w UART
  delay(100);
}

 

Zadanie 5.3 

#include <Servo.h> //biblioteka odpowiedzialna za serwomechanizmy

Servo serwomechanizm;
int pozycja = 0;
int zmiana = 6;
int opoznienie = 200;

void setup()
{ 
  Serial.begin(9600);
  serwomechanizm.attach(9);
}

void loop()
{
  if (pozycja < 100) {
    serwomechanizm.write(pozycja); 
  } else {
    pozycja = 0;
  }

  pozycja = pozycja + zmiana;
  delay(opoznienie); 
  opoznienie = opoznienie + 25; 

  Serial.print("Aktualne opoznienie: "); Serial.print(opoznienie); 
}

Zadanie 5.4

#include <Servo.h> //biblioteka odpowiedzialna za serwomechanizmy

Servo serwomechanizm;
String stringKat;
int gotowyKat;

void setup()
{
  Serial.begin(9600);   //rozpoczecie komunikacji przez UART
  serwomechanizm.attach(9);   //przypisanie serwomechanizmu do pinu 9
  Serial.print("Gdzie chcesz przesunąć śmigło (podaj liczbę z zakresu 0-180): \n");
}

void loop()
{
  if (Serial.available() > 0) {

    stringKat = Serial.readStringUntil('\n'); //czytamy podaną wartość
    gotowyKat = stringKat.toInt();
    if ((gotowyKat >= 0) && (gotowyKat <= 180)) {
      serwomechanizm.write(gotowyKat);
      Serial.print("\nUstawiłeś serwomechanizm w pozycji: " + stringKat);
    } else {
      Serial.print("Wartość nie prawidłowa, podaj wartość z prawidłowego przedziału, 0-180!\n");
    }
  }

  delay(200);
}

Zadanie 5.5

#include <Servo.h> //biblioteka odpowiedzialna za serwomechanizmy

Servo serwomechanizm;
int katPotencjometr;
int Kat;

void setup()
{
  Serial.begin(9600);   //rozpoczecie komunikacji przez UART
  serwomechanizm.attach(9);   //przypisanie serwomechanizmu do pinu 9
  Serial.print("Przekręć potencjometr i obserwuj zachowanie serwomechanizmu!"); 

}

void loop()
{
  katPotencjometr = analogRead(A5);
  Kat = map(katPotencjometr, 0, 1023, 0, 180);  //zmapowanie wartości napięcia na możliwe wartości kąta dla serwa

  serwomechanizm.write(Kat);
  delay(200);
}

 

Czekam na uwagi, możliwe ulepszenia i każdą możliwą krytykę.

W ten sposób uczę się najlepiej.

 

SUPER KURS! Aktualnie jestem w trakcie studiów i ten kurs jest idealnym uzupełnieniem zdobywanej wiedzy o praktyczne podejście. Dzięki za czas włożony w jego przygotowanie 😄 

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites
(edytowany)
19 godzin temu, samemilerzeczy napisał:

automatycznie zerowało po osiągnięciu maksymalnej wartości dozwolonej, czyli 255. 

Sprytnie, bardzo dobry pomysł 🙂 w wątku z przywitaniem pisałeś, że masz doświadczenie w programowaniu. Napiszę tyle: widać 🙂 Ładnie piszesz kody, starannie i poprawnie. Myślę, że kurs to dla Ciebie jakiś banał, ale fajnie że wrzucać odpowiedzi, na pewno dla innych będzie to dobra pomoc.

Ewentualnie przyczepię się magicznych liczb typu tajemnicze 9 przewijające się w kodach... 🔮

Edytowano przez Gieneq

Udostępnij ten post


Link to post
Share on other sites

@Gieneq 

Miło usłyszeć komplement. Dodaje to skrzydeł, a one są bardzo potrzebne gdy się codziennie ciężko pracuje. 

Ale kurs mimo wszystko nadal jest wymagający i stanowi przyjemne wyzwanie co sprawia też, że jest dużo ciekawszy. Zauważam też, jak wielu rzeczy nie mówią nam na Politechnice Gdańskiej więc się cieszę, że mogę sobie te braki w ten sposób  zakleić 😄 

A ta liczba 9 to tak została z zadania przykładowego z serwomechanizmem. Czasami z braku czasu zamiast pisać zadanie od nowa wykorzystuje co mogę z poprzedniego i tak się przewinęła ta 9 przez wszystkie zadania z tej części 😅😅😅

  • Lubię! 2

Udostępnij ten post


Link to post
Share on other sites

Może mi ktoś wytłumaczyć jedną rzecz? W tej części kodu z zadania 5.2:

void loop() {
  analogWrite(light, wypelnienie);

  if (wypelnienie < 255) {
    wypelnienie += zmiana;
  } else if (wypelnienie == 255) {
      while (wypelnienie > 0) {
        wypelnienie -= zmiana;
        analogWrite(light, wypelnienie);
        delay(50);
      }
  }

po while trzeba użyć jeszcze raz analogWrite (bez niego, LED zamiast stopniowo się wyłączać, wyłącza się natychmiast). Nie bardzo rozumiem w jaki sposób to działa.

Udostępnij ten post


Link to post
Share on other sites

Działa bardzo prosto.

Dopóki wypełnienie jest większe od zera, zmniejsz wypełnienie, wyślij wartość do układu sterującego diodą i odczekaj 50 milisekund.

To co proponujesz to: 

Dopóki wypełnienie jest większe od zera, zmniejsz wypełnienie, pozostaw układ sterujący diodą w poprzednim stanie (czyli zajarana ile fabryka dała), i odczekaj 50 milisekund.

Widzisz różnicę?

  • Pomogłeś! 1

Udostępnij ten post


Link to post
Share on other sites

@ethanak Jak tak to rozpisałeś to faktycznie ma sens. Wydawało mi się, że skoro na początku pętli już wysyłamy ten sygnał, to drugi raz nie ma potrzeby. Z tego co zrozumiałem to po prostu jeżeli nie wyślemy "poprawionego" sygnału to on zostawia to tak jak było?

Udostępnij ten post


Link to post
Share on other sites

Zauważ, że masz tu dwie pętle: jedną realizowaną przez wbudowany mechanizm loop, drugą tworzoną przez while. A zmiana wartości jakiejś tam zmiennej to wewnętrzna sprawa programu, jeśli chcesz, aby jakiś mechanizm to uwzględnił musisz podać mu nową wartość po każdej zmianie. 

Dlatego jestem przeciwny stosowaniu while/for/do przez początkujących (i w przykładach dla początkujących).

  • Pomogłeś! 1

Udostępnij ten post


Link to post
Share on other sites
15 godzin temu, ethanak napisał:

Dlatego jestem przeciwny stosowaniu while/for/do przez początkujących (i w przykładach dla początkujących).

@ethanak faktycznie pętle te (podobnie jak opóźnienia) bywają nagminnie stosowane nie tam gdzie trzeba, ale z drugiej strony kiedyś początkujący musi się nauczyć z czym to się je, czasem też musi się sparzyć i zastanowić nad ich sensem, może odkryje koło na nowo i będzie mieć powiedzmy życiową lekcję 🙂 

Podobnie jak opóźnienia, gdyby nie one to przykład blink, który jest bardzo dobrym testem środowiska/płytki zanim ruszy się dalej byłby bardziej skomplikowany, a z czasem niektórzy zauważają, że opóźnienia w programie wcale nie są niezbędne i da się to zrobić inaczej.

Udostępnij ten post


Link to post
Share on other sites

@Gieneq Ja nie twierdzę, że pętle czy opóźnienia to źródło wszelkiego zła. Po prostu na samym początku, kiedy delikwent jeszcze nie bardzo wie o co w tym całym programowaniu chodzi powinien uczyć się od rzeczy najprostszych. Tak jak dziecko na początku w przedszkolu poznaje literki, potem uczy się pisać, a dopiero potem poznaje tajniki gramatyki i w końcu zostaje wybitnym pisarzem. Gdybyś od początku chciał wprowadzić np. odmianę przez przypadki - raczej nic by z tego nie wyszło. I tu - zanim się człowiek nie nauczy jak działają warunki w instrukcjach warunkowych, jak się tworzy bloki - nie ma co szaleć z pętlami (które wymagają uprzedniego poznania obu tych rzeczy). Bo inaczej człowiek owszem sparzy się, ale nie będzie miał bladego pojęcia co go tak naprawdę sparzyło 😞

Akurat opóźnienia to przeciwieństwo pętli. Tak jak dziecko najpierw ma zeszyt w dwie linie, a potem dopiero się okazuje że te dodatkowe linijki nie są już potrzebne - tak samo tu: najpierw poznaje się opóźnienia, a potem pokazuje się że bez nich też można (tyle że trzeba wiedzieć coś więcej). Nie wspomnę już o goto (o którym to na szczęście w kursie w ogóle nie wspomniano) - jeśli stosować tę instrukcję prawidłowo, program nie traci na czytelności, nie ma jakichś dziwnych efektów ubocznych a przy okazji jest krótszy niż gdyby na siłę pozbyć się goto nawet tam, gdzie jest to naturalne.

Udostępnij ten post


Link to post
Share on other sites

No tak zgadzam się, że warto uczyć się na początku czegoś prostego, choć co jest proste to już kwestia dyskusyjna, bo to zależy do czego ten jeżyk będzie używany. Ale to też specyfika uczenia się programowania - abstrakcja i dopasowanie narzędzi do poziomu abstrakcji, który ma reprezentować rzeczywiste działanie, przy czym dochodzą do tego dobre i złe drogi, obie prowadzą do celu, ale niekoniecznie po linii najmniejszego oporu 🙂 Pocieszam się faktem, że przeglądając forum czasem trafiają się dość zdolni kursanci, którzy dobrze sobie radzą 🙂 

Udostępnij ten post


Link to post
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!

Anonim
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...