Skocz do zawartości

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

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ą

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

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.

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 🙂

  • 2 miesiące później...

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

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.

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ąć ?

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

  • 5 tygodnie później...

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
  • 2 tygodnie później...

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?

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

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;
 }
}
}

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