Skocz do zawartości

Kurs Arduino - #5 - PWM, serwomechanizmy, biblioteki


Komentator

Pomocna odpowiedź

Przed chwilą, solowkidamian napisał:

i tu moje pytanie jakie napięcie jest między pinem VIN a GND?

Napięcie na VIN jest równe napięciu zasilacza, więc jak zasilasz z baterii 9V, to powinno być ~9V (ale może mieć dość spore wahania w zależności od baterii)

  • Lubię! 1
Link do komentarza
Share on other sites

Witam udało mi sie zrobić zadania 5.3, 5.4 oraz 5.5

Zad 5.3

#include <Servo.h>

Servo serwomechanizm;
int pozycja = 0;
int zmiana = 6;
int czas = 150;

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

void loop() {
  for (int i = 0; i <= 1500; i = i + 50){
    
  if (pozycja < 180) {
    serwomechanizm.write(pozycja);
  } else {
    pozycja = 0;
  }  
  pozycja = pozycja + zmiana;
  
  Serial.println( i);
  
  delay(czas + i);
  
  if (i >= 1500){
    i = 0;
   }
  }
}

5.4

#include <Servo.h>

Servo serwomech;
int odebraneDaneINT = 0;
String odebraneDane = "";
bool stan = true;
int pozycja = 0;

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

void loop() {
  
if(stan == true) {
  Serial.println("Podaj liczbe z zakresu od 0 do 180");
  stan = false;
  }
  
 if(Serial.available() > 0) {
    odebraneDane = Serial.readStringUntil('\n');
    odebraneDaneINT = odebraneDane.toInt();
    Serial.println(odebraneDaneINT);
    
 if (odebraneDaneINT >= 0 && odebraneDaneINT <= 180 ) {
  Serial.println("git");
  odebraneDaneINT;
  serwomech.write(odebraneDaneINT);
  }
 else if(odebraneDaneINT < 0 or odebraneDaneINT > 180) {
  Serial.println("Podano blednom liczbe");
  }  
    }
  delay(1000); 
 }

 

 

5.5

#include <Servo.h>

Servo servo;
int odczyt = 0;

void setup() {
  servo.attach(9);
}

void loop() {
odczyt = analogRead(A1);
odczyt = map(odczyt, 0, 1021, 0, 180);
servo.write(odczyt);
}

będę wdzięczny za komentarze i uwagi

Edytowano przez solowkidamian
Link do komentarza
Share on other sites

@solowkidamian ogólnie ok, ale np:

 odebraneDaneINT;

Nie wiem co tu miało być.

  for (int i = 0; i <= 1500; i = i + 50){

1500 jest bardzo magiczną liczbą, może nazwij to jakoś:

#define TIME_INTERVAL 1500
#define TIME_SPEED 50
  for (int i = 0; i <= TIME_INTERVAL; i = i + TIME_SPEED){

 

  • Lubię! 1
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

Witam, po przerobieniu lekcji z tego działu czułem niedosyt. Postanowiłem więc rozwiązać dodatkowe zadanie które sobie wymyśliłem takie z "*" 🙂

Zadanie domowe 5.6*

Napisz program taki jak w zadaniu 5.4 (ustawianie pozycji serwomechanizmu za pomocą komunikacji przez UART). Jednak bez wykorzystania biblioteki

#include <Servo.h>

Po uświadomieniu sobie że zapis:

Cytat

Wypełnienie generowanego sygnału powinno mieścić się w granicach 5-10%. Wartości te zostaną przekształcone na dwie skrajne pozycje serwa (maksymalnie w lewo oraz maksymalnie w prawo).

Tyczy się przedziału od początku skali do jej końca +/- 5-10% wartości krańcowych a nie od 5% do 10% przedziału.przedzialy.thumb.png.440098e44b1ce90a50810cf592b7ff65.png

Udało mi się napisać działający skrypt:

#define servoPin 9

int pozycja = 0;
String inputValue = "";

int servoMin = 44;
int servoMax = 254;

void setup() {
  pinMode(servoPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  while(Serial.available() > 0){
    inputValue = Serial.readStringUntil('\n');
    pozycja = inputValue.toInt();
    if(pozycja < 0 || pozycja > 180){
      Serial.println("Wrong value.");
    } else {
      setServo(pozycja);
    }
  }
}

void setServo(int value){
  value = map(value, 0, 180, servoMin, servoMax);
  analogWrite(servoPin, value);
}

Wartości "servoMin" oraz "servoMax" ustaliłem metodą prób i błędów ręcznie próbując wszystkie wartości po kolei. Serwomechanizm do puki nie podałem wartości z zakresu nie odpowiadał wcale tj. będąc na pozycji 180 po otrzymaniu wartości 43 nie przechodził na pozycję 0 tylko pozostawał w spoczynku, dopiero po podaniu poprawnej wartości 44 zmieniał pozycje na 0. 

Tutaj dochodzimy do nurtującego mnie pytania. Skoro wartości skrajne wąchają się między 5-10% a komunikacja z serwomechanizmem jest tylko jedno strona jak jesteśmy w stanie określić przedziały?

  • Lubię! 1
Link do komentarza
Share on other sites

@MaciejG witam na forum! Fajnie widzieć, że ktoś próbuje "wycisnąć" z zadań jeszcze więcej 🙂

Dnia 3.09.2022 o 19:12, MaciejG napisał:

Skoro wartości skrajne wąchają się między 5-10% a komunikacja z serwomechanizmem jest tylko jedno strona jak jesteśmy w stanie określić przedziały?

Nie jesteśmy. To znaczy, w tego typu serwach (jak sam zauważyłeś) nie ma żadnego sprzężenia zwrotnego, więc możemy określić to jedynie eksperymentując z danym egzemplarzem serwa w praktyce. Istnieją takiej bardziej zaawansowane napędy ze sprzężeniem zwrotnym, ale są znacznie droższe i zdecydowanie mniej popularne.

Link do komentarza
Share on other sites

Tak jak Treker mówił.

Jeżeli komuś nie działa servo poprawnie, to jak zmieniłem baterię na nową to zaczęło działać dobrze i śmiga jak helikopter. Poprzednia miała +-7.99V. I to nie wystarczało na poprawne działanie serwomechanizmu. 

Link do komentarza
Share on other sites

17 godzin temu, ethanak napisał:

Wywal baterie i kup jakiś zasilacz za 15 zeta - te baterie są dobre do zasilania ledy i to z duuuuuużym rezystorem 🙂

Dzięki, tak też zrobiłem. Pozdrawiam.

PS. Zadania 5.4 i 5.5 zrobione i działają poprawnie.  

Edytowano przez RakietowyKim
Dodany ps
  • Lubię! 1
Link do komentarza
Share on other sites

Po wczorajszych perypetiach dzisiejsze lekcje przyszły łatwiej. 🙂

Zad. 5.1
 

#define LED 3

byte wypelnienie = 0; //Zmienna wypelnienie
int zmiana = 5; //Zmienna do zmiany wypelnienia

void setup() {
  pinMode(LED, OUTPUT); //Konfiguracja pinu jako wyjscie
}

void loop() {
  analogWrite(LED, wypelnienie); //Generowanie sygnalu o zadanym wypelnieniu
  wypelnienie = wypelnienie + zmiana; //Zwieksz wypelnienie o wartosc zmiennej zmiana
 
delay(50); //<ale opoznienie dla uwidocznienia efektu

}

 

Zad. 5.2
 

#define LED 3

int wypelnienie = 0; //Zmienna wypelnienie
int zmiana = 5; //Zmienna do zmiany wypelnienia

void setup() {
  pinMode(LED, OUTPUT); //Konfiguracja pinu jako wyjscie
}

void loop() {
  analogWrite(LED, wypelnienie); //Generowanie sygnalu o zadanym wypelnieniu

 if (wypelnienie < 255) { //Jezeli wypelnienie jest mniejsze od 100%
 wypelnienie = wypelnienie + zmiana; //Zwieksz wypelnienie o wartosc zmiennej zmiana
 }

 if (wypelnienie >= 255) { //Jezeli wypelnienie jest rowne lub wieksze od 100%
  while(wypelnienie > 0) { //Jezeli wypelnienie jest wieksze od 0
    wypelnienie = wypelnienie - zmiana; //Zmniejsz wypelnienie o wartosc zmiennej zmiana
    analogWrite(LED, wypelnienie); //Konfiguracja pinu jako wyjscie
    delay(5); //Opoznienie dla uwidocznienia
  }
 }

delay(5); //<ale opoznienie dla uwidocznienia efektu

}

 

Zad. 5.3
 

#include <Servo.h>//Zalaczenie biblioteki odpowiedzialnej za serwomechanizmy

Servo serwo; //Tworzenie obiektu dzieki ktoremu odwolamy sie do serwa
int pozycja = 0; //Zmienna dla aktualnej pozycji serwa 0-180
int zmiana = 6; //Zemienna z interwalem zmiany serwa
int opoznienie = 200; //Wstepne opoznienie pomiedzy pozycjami serwomechanizmu

void setup() {
  serwo.attach(9); //Serwomechanizm podlaczony do pinu 9
}

void loop() {
  if (pozycja < 180) { //Jesli pozycja miesci sie w zakresie do 180
    delay(opoznienie); //Opoznienie przed wykonaniem ruchu
    serwo.write(pozycja); //Wykonaj ruch
  } else {
    pozycja = 0; //Jesli pozycja nie miesci sie w zakresie to wroc na poczatek
    opoznienie = 0;
  }

  pozycja = pozycja + zmiana; //Zwiekszenie aktualnej pozycji serwa o interwal zmiennej zmiana
  opoznienie = opoznienie + 50; //Zwiekszanie opoznienia przy kazdej zmianie pozycji
}

 

Zad. 5.4
 

#include <Servo.h> //Dolaczenie biblioteki odpowiedzialnej za serwa

Servo serwo; //Tworzeniu obiektu do odwolan do serwa
String pozycja = ""; //Zadana pozycja wprowadzona przez UART
int ruch = 0; //Zmienna przekonwertowana z pozycji

void setup() {
  serwo.attach(9); //Podlaczenie serwa do pinu 9
  Serial.begin(9600); //Uruchomienie komunikacji UART
  serwo.write(90); //Ustawienie serwa w pozycji 90
}

void loop() {
  Serial.println("Witaj!");
  Serial.println("Podaj oczekiwaną pozycję (0-180)");
  while(Serial.available() == 0) {} //Czekaj na dane z portu
  pozycja = Serial.readStringUntil('\n'); //Odzczyt danych z portu
  ruch = pozycja.toInt(); //Konwersja danych z portu do zmiennej int

  if (ruch >= 0 && ruch <= 180) { //Warunek wykonywany jezeli podano liczbe z zakresu 0-180
    delay(100);
    Serial.print("Gotowe, ustawiona pozycja to: ");
    Serial.println(ruch);
    serwo.write(ruch);
  } else {
    Serial.println("Podałeś złą wartość!");
    Serial.println("Spróbuj ponownie");
    delay(200);
  }
}

 

Zad. 5.5
 

#include <Servo.h> //Dolaczenie biblioteki odpowiedzialnej za serwa

Servo serwo; //Tworzeniu obiektu do odwolan do serwa
int potek = 0; //Zmienna do ktorej bedzie przypisana wartosc z potencjometru

void setup() {
  serwo.attach(9); //Podlaczenie serwa do pinu 9
}

void loop() {
  potek = analogRead(A5); //Odczyt danych z potencjometru
  potek = map(potek, 10, 1013, 5, 175); //Konwersja wartosci potencjometru na wartosci serwa
  serwo.write(potek); //Ustawienie serwa wzgledem potencjometru
  
}

 

P.S.
Zauważyłem, że serwo ma czasami "padaczkę", która po chwili (krótkiej lub krótszej) ustępuje.
Nie tylko w skrajnych pozycjach, bo przy zadaniu z potencjometrem przy szybszym obrocie "padaczka" włączała się w aktualnej pozycji i ustępowała po jakimś czasie w pozycji zadanej. 😉
Rozumiem, że to prawdopodobnie objaw niskiej ceny i generalnie aktualnie mi to nie przeszkadza, ale po zakończeniu kursów chcę m.in. to serwo zatrudnić do robota z kursów i mnie to trochę martwi. 😉

Link do komentarza
Share on other sites

2 godziny temu, ethanak napisał:

No to ma prawo się dziwnie zachowywać. Zerknij parę postów wyżej co pisałem do @RakietowyKim

 

1 godzinę temu, farmaceuta napisał:

Oj ta nieszczęsna baterią 9v to marne źródło zasilania...na chwilkę coś sprawdzić ujdzie, ale na dłuższą metę to ni hu hu😉

 

Jako, że posiadam zestaw do drugiej części kursu i ogarnąłem, że tam jest zasilacz, to go wygrzebałem, podłączyłem i objawy dalej występują. 😂

  • Lubię! 1
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!

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

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.