Skocz do zawartości

Kurs Arduino - #5 - PWM, serwomechanizmy, biblioteki


Pomocna odpowiedź

Witam,

To jest mój pierwszy post tutaj, więc proszę o wyrozumiałość 🙂

Otóż przy wykonywaniu części PWM natknąłem się na taką jedną rzecz, która nie daje mi spokoju, przy modyfikacji zadania 5.1, a ściślej do skrócenia kodu do następującego fragmentu:

#define diodaPIN 3

int wypelnienie = 0;
int zmiana = 5;

void setup() {
pinMode(diodaPIN, OUTPUT);//Konfiguracja pinu jako wyjścia 
}

void loop() {
analogWrite(diodaPIN, wypelnienie); //Generujemy sygnał o zadanym wypełnieniu

wypelnienie=wypelnienie+zmiana;

delay(50); //Małe opóźnienie, aby efekt był widoczny
}

Program nadal działa, nie rozumiem dlaczego, skoro wartość wypełnienia jest powiększana cały czas o 5, i nie ma warunku gdzie powracamy do początku. Dioda zachowuje się identycznie jak przy oryginalnym programie.

RAV511, zerknij do informacji o zmiennych. Każda ma pewną swoją pojemność maksymalną. Po jej przekroczeniu zmienna przyjmuje swoją najmniejszą możliwą wartość. Wyświetl sobie przez UART wartość zmiennej "wypełnienie", to lepiej zaobserwujesz to zjawisko.

  • 3 tygodnie później...

Witam

Trochę odgrzewam temat jednak mój 10 letni syn dostał zestaw Arduino Uno na mikołaja więc korzystając z tego poradnika obaj próbujemy się nauczyć jego obsługi i programowania. Doszliśmy właśnie do "Serwomechanizm w praktyce" do którego nam brakuje stabilizator LM7805 oraz diod filtrujących. Stabilizator to nie problem jednak nie bardzo wiem jakie mają mieć parametry te diody. Bardzo bym prosił o info bo nawet próbowałem sprawdzić jakie Państwo sprzedajecie razem w zestawach startowych jednak takowych w nich nie zauważyłem.

Lofi_Toys, jeśli w zestawie brakowało jakiś elementów to proszę zgłosić się do dystrybutora - Botlandu, na pewno doślą odpowiednie podzespoły 🙂

PS zapewne chodzi o kondensatory filtrujące, a nie diody 🙂

Problem w tym że mój syn dostał zestaw z innej firmy. Jednak przeglądając spis zawartości zestawów Botlandu także nie zauważyłem takowych kondensatorów które są użyte w ćwiczeniu.

Ktoś tu pytał na pierwszej stronie czy mają to być kondensatory 100nF tylko nie jestem elektronikiem i nie jestem pewien czy to ma być 100 nanoFarad ?

Wszystko bajka zarowno ta jak i poprzednie lekcje(do reszty jeszcze mi daleko 😃) Jesli chodzi o PWM to nie moglem zlokalizowac w tej czesci kusry informacji jak zmieniac czestotliwosc, z tego co wyczytalem w internecie funkcja analogWrite() ustala wartosc czestotliwosci na 490Hz a istnieje moze inna funkncja badz przelicznik dzieki ktoremy bedzie mozna ja wprowadzic?(pytam bo troche przerobilem powyzszy program i zrobilem pwma tegulowanego potencjometrem) Jeli ktos ma czas to prosze o wsparcie 🙂

Problem w tym, że analogWrite() jest dość ściśle powiązane z innymi mechanizmami czasowymi w Arduino i zmiana jej podstawy czasu rozwali kilka innych rzeczy. Natomiast w bardzo prosty sposób możesz generować prawie dowolne częstotliwości i wypełnienia PWM bezpośrednio za pomocą timerów sprzętowych. System Arduino zawłaszcza sobie timer 0, ale zostaje Ci jeszcze nr 1 i 2 - i to tylko w procesorze ATmega328 (UNO itp). Wszystkie płytki MEGA oparte na większych procesorach mają tych timerów jeszcze więcej. Jesteś co prawda wtedy uwiązany tylko do pewnych konkretnych pinów (zwróć na to uwagę w opisie), ale zwykle nie jest to problem.

Biblioteka obsługująca np. timer 1 ma dużo ciekawych funkcji, w szczególności pwm(pin, duty, period). Poczytaj tu:

http://playground.arduino.cc/Code/Timer1

  • Lubię! 1

Albo byly mega łatwe albo juz coś pojmuję 🙂

5.4

#include <Servo.h>

Servo ser1;
int pozycja = 0;
int zmienna = 5;
int czas = 10;
String dane = "";
int dane_int = 0;
int s1 = 0;

void setup() {
 ser1.attach(3);
 Serial.begin(9600);

}

void loop() {
 if ( s1 == 0) {
   Serial.print(" Podaj cyfre od 0 do 180 ");
   s1 = 1;
 }

 if (Serial.available() > 0) {
   dane = Serial.readStringUntil('\n');
   dane_int = dane.toInt();
   if (dane_int < 0)
   { Serial.print ("Niewlasciwe DANE !!!");
     dane_int = 0;
     delay(1000);
   } else {
     if (dane_int > 180) {
       Serial.print ("Niewlasciwe DANE !!!");
       dane_int = 0;
       delay(1000);
     }
   }
   ser1.write(dane_int);
   delay(3000);
   s1 = 0;
   dane_int = 0;
   ser1.write(dane_int);
   delay(1000);
 }
}

5.5

#include <Servo.h>                    // Biblioteka Serwo

Servo ser1; 
int dane = 0;

void setup() {
 ser1.attach(3);                     // przypisanie ser1 do 3 Pinu
}
void loop() {
 dane = analogRead(A0);              //odczyt danych z portu analogowego A0
 dane = map(dane, 0, 1023, 0, 180);  //zamiana ich na wartosci od 0 do 180
 ser1.write(dane);                   //przypisanie ich do serwa
}

RossiQ, jeśli chodzi o program do zadania 5.4, to zabrakło komentarzy 😉

Poprawiłbym też kilka rzeczy w zapisie, zamiast takiego formatowania:

  if (dane_int < 0) 
   { Serial.print ("Niewlasciwe DANE !!!"); 
     dane_int = 0; 
     delay(1000); 
   }

Lepiej byłoby zrobić tak:

    if (dane_int < 0) {
     Serial.print ("Niewlasciwe DANE !!!"); 
     dane_int = 0; 
     delay(1000); 
   }

Inaczej podczas edycji/kopiowania programu można łatwo "wstrzyknąć" sobie coś między if'a, a blok kodu, który ma być wykonywany po spełnieniu warunku.

Po drugie, zamiast:

    } else { 
     if (dane_int > 180) { 
       Serial.print ("Niewlasciwe DANE !!!"); 
       dane_int = 0; 
       delay(1000); 
     } 
   } 

Można zrobić od razu:

    } else if (dane_int > 180) { 
       Serial.print ("Niewlasciwe DANE !!!"); 
       dane_int = 0; 
       delay(1000); 
   } 

W dalszej części kursu pokazane są informacje na temat łączenia warunków, więc wtedy oba warunki będziesz mógł zmieścić w jednym if'ie.

W przypadku zadania 5.5 wszystko wygląda dobrze. Ewentualnie można przyczepić się do nazwy zmiennej "dane", bo nie mówi ona zbyt wiele o przechowywanej informacji. Jednak wszystkie mojego uwagi to tylko kosmetyka, ogólnie poszło Ci dobrze 🙂 Powodzenia w dalszej nauce!

  • 2 tygodnie później...

Czesc!

To moj pierwszy post na forum. Ostatnio zaczalem kurs Arduino, oto moj kod do zadania 5.4. Co moznaby jeszcze poprawic?

#include <Servo.h> //biblioteka odpowiedzialna za serwa
Servo serwo; //tworzymy obiekt odwolujacy sie do serwa
String pozycja; // pozycja wpisana przez uzytkownika
int pozycjaInt = 0; //przerobiona na zmienna int

void setup() {
 serwo.attach(9); //Serwo podlaczone do pinu 9
 Serial.begin(9600);
 serwo.write(180);
 delay(300);
 Serial.println("Aby ustawic serwo prosze podac liczbe z zakresu od 0 do 180");
}

void loop() {
 while (!Serial) delay(10); //czekamy na otwarcie monitora
 while (Serial.available() == 0); //czekamy na podanie liczby
 pozycja = Serial.readStringUntil('/n');
 pozycjaInt = pozycja.toInt(); //Zamiana string na int
 obrot(); //funkcja obracajaca serwem

}

funkcja obrot()

void obrot()
{
if (pozycjaInt >= 0 && pozycjaInt <= 180)
{
   serwo.write(pozycjaInt);
 delay(200);
 Serial.println("Serwo w pozycji: ");
 Serial.println(pozycjaInt);
}
else
{
 Serial.println("Podano niewlasciwa wartosc. Prosze podac wartosc z zakresu 0-180");
}
}

Zielak_, witam na forum 🙂

Jeśli chcesz czekać na start transmisji (while (!Serial) delay(10);), to wystarczy zrobić to raz, czyli w funkcji setup, nie trzeba powtarzać tego w każdym obiegu pętli loop. W przypadku funkcji obrot() polecałbym poprawić formatowanie - głównie wcięcia nawiasów, bo w tej chwili się zlewają. Poza tym wygląda dobrze 🙂

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