Skocz do zawartości
Komentator

Kurs Arduino - #6 - kontynuacja UART, serwomechanizmy

Pomocna odpowiedź

cześć,
a czy jest szansa na artykuł z komunikacją gsm? Bo nie mogę znaleźć nic satysfakcjonującego, a na oficjalnym z gotowców nie chcę mi działać coś 😉

pozdrawiam

Udostępnij ten post


Link to post
Share on other sites

bziakot, na ten moment nie planuję takiego tekstu 🙁

Udostępnij ten post


Link to post
Share on other sites
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ą

Udostępnij ten post


Link to post
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!");}
            }
 }

Udostępnij ten post


Link to post
Share on other sites

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.

Udostępnij ten post


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

Udostępnij ten post


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

Udostępnij ten post


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

Udostępnij ten post


Link to post
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ąć ?

Udostępnij ten post


Link to post
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ć.

Udostępnij ten post


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

Udostępnij ten post


Link to post
Share on other sites

szmajdzik, super, wygląda bardzo fajnie 🙂

Udostępnij ten post


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

Udostępnij ten post


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

Udostępnij ten post


Link to post
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;
 }
}
}

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!

Gość
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...