Skocz do zawartości

Kurs Arduino - #6 - kontynuacja UART, serwomechanizmy


Komentator

Pomocna odpowiedź

bziakot, na ten moment nie planuję takiego tekstu 🙁

nie szkodzi 🙂 i tak poradnik super, jakieś podstawy wyrobiłem na tym poradniku, więc może jakoś sam ogarnę jakiś przykład z neta, bo to gotowce w programie coś nie współpracują

Link do komentarza
Share on other sites

Witajcie,
Mam 2 problemy.

1. Zrobiłem zadanie 5.4 wszystko działa ale... na pewnych ustawieniach serwa (losowe np. 150, 170 , 50 ) serwo po zatrzymaniu wibruje. Co może być przyczyną? Stabilizator 5V, kondensatory na wejściu i wyjściu 220uf.

Próbowałem zmianę kondensatorów na:

100uf - nic nie dało.

1000uf - serwo w ogóle nie reagowało na polecenia z konsoli.

2. Wymyśliłem sobie że dorobię sobie diodę zieloną która będzie świecić w momencie gdy serwo nie pracuje (czeka na wartość). Dioda podłączona pod pin 10 świeci. Ale serwo dostaje świra, po wprowadzeniu wartości niższej (np serwo stoi na 150 i chcemy aby się przesunęło na 100) wykonuje dziwne ruchy i dopiero rusza na wlaściwą pozycję.

Załączam kodzik przy którym serwo dostaje głupawki.

#include <Servo.h> // biblioteka serwa
Servo servo; // obiekt serwa
int pozycja;
int pozycjaWyjsciowa = 90;
String odebraneDane;
boolean pauza=false;


void setup() {
servo.attach(9);
servo.write(pozycjaWyjsciowa);
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
Serial.begin(9600);
}

void loop() 
 {
   if (pauza==false){
     Serial.println("Podaj kat wychylenia od 0-180");
     pauza=true;
   }
      if(Serial.available() > 0){
           odebraneDane = Serial.readStringUntil('\n');
           pozycja = odebraneDane.toInt();
        if (pozycja <=180 && pozycja >= 0) 
           {servo.write(pozycja);//wykonaj ruch
           Serial.println(pozycja);
           delay(100);}
        else
           {Serial.println("Pozycja poza zakresem!");}
            }
 }
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

Rayu85, przyczyn może być kilka. Jednak głównie szukałbym ich w samym serwomechaniźmie. Napędy używane w kursie są bardzo popularnymi i dość tanimi silnikami, więc mają również swoje wady. Drgania oznaczają, że serwomechanizm próbuje cały czas ustawić się w danej pozycji, a coś mu na to nie pozwala - stąd wpada w takie wibracje. Możliwe, że w danej pozycji coś złego dzieje się w przekładni lub potencjometrze, który jest wewnątrz.

Jeśli drgania faktycznie występują tylko na jednej pozycji to najprościej można programowo po prostu omijać tę wartość 🙂 Możesz też reklamować napęd do sprzedawcy. Tak, czy inaczej drgania w serwomechanizmach są czymś normalnym i często spotkasz się z takimi zjawiskami - w większości przypadków będzie to zupełnie normalne. Szczególnie przy krańcach zakresu, w którym porusza się oś serwa.

Link do komentarza
Share on other sites

Dzięki za odpowiedz:) Drgania występują tak jak pisałem przy losowych ustawieniach np. raz na pozycji 50 serwo drga a za 2 gim razem na tej pozycji jest spokojne. Możliwe że to faktycznie wynika z taniego seraw:) Narazie nie przeszkadza mi to ale mnie zaciekawiło 🙂 zobaczymy jak się sprawdzi w innych konstrukcjach 🙂

Link do komentarza
Share on other sites

Witam, próbowałem zrobić wskaźnik poziomu światła w następujący sposób.


#include <Servo.h>
int odczytanaWartosc = 0; 
Servo myservo; 

void setup() 
{ 
 myservo.attach(11); 
Serial.begin(9600);
} 

void loop() 
{  

int  odczytanaWartosc = analogRead(A5);
 odczytanaWartosc = map(odczytanaWartosc, 0, 70, 0, 180);
 myservo.write(odczytanaWartosc);
 Serial.println(odczytanaWartosc);
 delay(200); 

 }    


Nie chciałem kopiować słowo w słowo kodu źródłowego dlatego napisalem cos sam na podstawie podobnego kodu ( serwo + potencjometr ). Ogólnie prgram działa tylko czasem wariuje. Sprawdziłem, że jeśli przyłoże latarke z telefonu do fotorezystora to w terminalu pokazuje sie maxymalna wartość 225, przy założeniu, że

odczytanaWartosc = map(odczytanaWartosc, 0, 103, 0, 180);

a jesli zmienie

odczytanaWartosc = map(odczytanaWartosc, 0, 50, 0, 180);

wartosc w terminalu wynosi nawet 450.

Nie wiem czym to jest spowodowane i nie wiem jak to skalibrowac w odpowiedni sposób. Pozdrawiam

Link do komentarza
Share on other sites

spwr, dlaczego w kodzie masz za każdym razem inne wartości podawane jako argument funkcji 70, 103, 50? Skąd je bierzesz? Jeśli ustawić zakres wartości wejściowych 0-50, a faktycznie z ADC jest tam odczytywana wielkość np. 255, to wychodzi za zakres kilka razy. Nie jest to poprawne podejście i tutaj doszukiwałbym się problemów.

Link do komentarza
Share on other sites

Mam inne wartości, bo eksperymentowałem. I nie moge znaleźć tego złotego środka. Myslalem ze jak dam ( 0 , 50 , 0 , 180) to najwyzsza wartosc w terminalu bedzie rowna 50 co bedzie odpowiadalo maksymalnemu wychyleniu serwa czyli 180. Analogicznie gdy tam 70 i 103. To jaka wartośc powinienem ustawić zmiast 50 ? Skad mam ją wziąć ?

Link do komentarza
Share on other sites

spwr, nie wiem czy rozumiesz dobrze działanie parametrów funkcji map. Te zakresy, które podałeś - przykładowo [...] 0 , 50 , 0 , 180 [...], oznaczają, że Ty "gwarantujesz", że wartość wejściowa jest z zakresu 0-50, a Arduino ma ją przeskalować do 0-180. Całość realizowana jest wzorem (z dokumentacji): (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min.

Więc jeśli przyjmiemy powyższe zakresy, to mamy: (x - 0) * (180 - 0) / (50 - 0) + 0, teraz jak za X podstawisz sobie wspomniane 255 z ADC, to wychodzi: 255*180 / 50, co daje 918 - więc nie możesz dziwić się, że funkcja zwraca błędne wartości. Ona zwraca poprawny wynik, to Ty nie trzymasz się założeń i podajesz na jej wejście złe dane. Twój zakres wejściowy powinien być ustawiony na 0-255. Możesz go zmieniać, ale nie "na ślepo" - trzeba zmierzyć jaką wartość pokazuje ADC przy maksymalnym oświetleniu/zaciemnieniu fotorezystora i takie wartości można tutaj podstawić.

Link do komentarza
Share on other sites

Wstawiłem kondensatory elektrolityczne 220uF i działa bardzo dobrze 🙂 Czujnik na dłuższym przewodzie, położony przy oknie reaguje na np. zachmurzenie 😉 Miernik wyskalowałem tak:

pozycja = map(odczytCzujnika, 0, 900, 35, 120)

Pozdrawiam

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

Mam pytanie do zadania 6.1

Wszystko działa poprawnie, tutaj mam kod:

int button = 1;

void setup() {
 Serial.begin(9600); 
 pinMode(8,INPUT_PULLUP);
}

void loop() {

int fr1 = analogRead(A5);
int fr2 = analogRead(A0);

 if (digitalRead(8) == LOW) {
 Serial.print("Button counter: ");
 Serial.print(button);
 Serial.print("\t");
 ++button;

 Serial.print("FR1: [HEX]");
 Serial.print(fr1,OCT);
 Serial.print("\t");

Serial.print("FR2: [HEX]");
 Serial.print(fr2,OCT);
 Serial.print("\n");
 Serial.print("\n");
 delay(1000);
 }
 while (digitalRead(8) == LOW) {}
}
int fr1 = analogRead(A5);
int fr2 = analogRead(A0);

Dlaczego ten fragment musi się znajdować w pętli loop, a nie poza programem jak "int button"? Gdy daję go właśnie tam, to wartości na obu fotorezystorach są równe 0. Czym to jest uwarunkowane?

Link do komentarza
Share on other sites

thequeash, ponieważ wtedy program nie ma jak i kiedy odczytywać wartości. Na samą górę można ewentualnie przenieść deklarację zmiennych:

int fr1 = 0; 
int fr2 = 0;

Jednak w pętli loop i tak będzie trzeba odczytywać wartości z czujników:

fr1 = analogRead(A5); 
fr2 = analogRead(A0);
  • Lubię! 1
Link do komentarza
Share on other sites

Dlaczego tekst o złej komendzie pojawia mi się dwa razy albo raz mimo włączenia się diody?

PS. Dziękuję Treker za odpowiedź na poprzedniego posta 🙂 Odwalasz kawał dobrej roboty!

#define zielona 8
#define czerwona 9

int odebraneDane = 0;

void setup() {
 Serial.begin(9600);
 pinMode(zielona, OUTPUT);
 pinMode(czerwona, OUTPUT);

 digitalWrite(zielona, LOW);
 digitalWrite(czerwona, LOW);
}

void loop() {
 while(Serial.available() >0) {
   odebraneDane = Serial.read(); 

 switch (odebraneDane) {
   case 'r':
   digitalWrite(czerwona,HIGH);
   delay(1000);
   digitalWrite(czerwona,LOW);
   break;
   case 'g':
   digitalWrite(zielona, HIGH);
   delay(1000);
   digitalWrite(zielona,LOW);
   break;

default:
   Serial.println("Bad command.");
   delay(100);
   break;
 }
}
}
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.