Skocz do zawartości
Komentator

Kurs Arduino - #6 - kontynuacja UART, serwomechanizmy

Pomocna odpowiedź

Niestety kupiłem w Botlandzie inny zestaw niż przewidziany w kursie...
Swój zakupiłem właśnie dzięki linkom z lekcji #0

No to zdecyduj się - albo kupiłeś kurs Forbota, albo nie. Najlepiej podaj kod produktu, to nie będzie żadnej wątpliwości i pomoc będzie łatwiejsza. Inaczej jest to wróżenie ze szklanej kuli, bo nie wiemy czym dysponujesz.

Udostępnij ten post


Link to post
Share on other sites

Na spokojnie, jeszcze raz.

Kupiłem nie kurs a zestaw startowy ARD-01715.

Nie ma w tym zestawie wyświetlacza, kondensatorów, stabilizatora, serwomechanizmu.

W trakcie lektury kursu dokupiłem zestaw kondensatorów ceramicznych PAS-02146, servo 2-BB1-4.6 (takie, ponieważ, tego opisywanego w kursie czasowo nie było na stanie sklepu), wyświetlacz, stabilizator 2-AG2-17.6, adapter i in.

Nie wiem, po co, to wszystko wymieniać... proszę tylko o pomoc przy dobraniu kondensatorów, które owiane są jakąś tajemnicą 😅 ...

Udostępnij ten post


Link to post
Share on other sites
Nie wiem, po co, to wszystko wymieniać...

Po to, że aby udzielić Ci dobrej rady musimy wiedzieć czym dysponujesz, a Ty co chwile zmieniasz zdanie. Raz kupiłeś zestaw do kursu od Forbota, a raz nie.

Jak sam zwróciłeś uwagę linki w kursie prowadzą do podstrony z 4 zestawami (2 do kursu elektroniki i 2 do kursu Arduino). Ty natomiast kupiłeś coś zupełnie innego, więc nie mam pojęcia jaki jest tam serwomechanizm, bateria oraz reszta elementów. To nie jest mój zestaw 🙂

Do filtrowania zasilania przy serwomechaniźmie oprócz kondensatorów ceramicznych warto użyć elektrolityczne (> 10uF). Dużą rolę w tym zadaniu odgrywa również bateria. Nie na każda będzie na tyle wydajna, aby zasilić serwomechanizm. Dlatego do zestawów Forbota dodawane są takie, z którymi nie ma żadnego problemu.

Udostępnij ten post


Link to post
Share on other sites

ok bardzo dziękuję za cierpliwość. Nie mam pojęcia dlaczego wyszło małe zamieszanie. Czytam swoje posty wstecz i nie widzę tam nic z czego bym się potem wycofał... ale tak bywa ze słowem pisanym.

Jeszcze raz dziękuję.

Udostępnij ten post


Link to post
Share on other sites

cześć, wstawiam swój kod do zadania 6.3, bez zdjęć bo przyznam, że nie chciało mi się robić tarczy ze skalą.

Program działa poprawnie. początkowo miałem problem w momencie gdy ustawiałem wartość maksymalną na jakimś niskim poziomie ale szybko "odkryłem", ze przyczyną byl typ zmiennej pozycja, ktory byl ustawiony na byte. nie wiedzialem jak dokładnie działa mapowanie.

#include <Servo.h>

Servo serwo;
int pozycja = 0;
int odczytanaWartosc = 0;
int wartoscPoprzednia = 0;
int wartoscMaks = 800;

void setup() {
 Serial.begin(9600);
 serwo.attach(3);
 pinMode(12, INPUT_PULLUP);
}

void loop() {
   odczytanaWartosc = analogRead(A5);
 if (digitalRead(12) == LOW){         // w momencie wcisniecia guzika 
   wartoscMaks = odczytanaWartosc;    // ustawiam maksymalne natezenie
 }
 pozycja = map(odczytanaWartosc, wartoscMaks, 0, 0, 180);

 if (abs(pozycja-wartoscPoprzednia) > 5){
   serwo.write(pozycja);
   wartoscPoprzednia = pozycja;
 }
 Serial.println(wartoscMaks);
 delay(1000);
}

Piszę jednak głownie z innego powodu. Moje serwo nie działa do końca poprawnie i nie wiem co jest przyczyną. Filmik demonstruje co się dzieje

Chodzi mi o te drgania.

Delay jest ustawiony na jedna sekundę, do tego używam wartości bezwzględnej żeby serwo nie uwzględniało bardzo małych zmian.

Początkowo myślałem, że to wina braku kondensatorów przy stabilizatorze bo ich nie używałem ale znalazłem kondensatory 220nF (nie wiem jakie są w zestawie bo Arduino miałem już wcześniej więc kupiłem pozostałe elementy oddzielnie) i nic to nie zmieniło.

Udostępnij ten post


Link to post
Share on other sites

wykonałem ten układ, jednak bez stabilizatora napięcia i kondesatorów, czy to jest przyczyną tego, że serwomechanizm cały czas pracuje (utrzymując tą samą pozycję nadal słychać, że pracuje)?

/*

update:

tak to przez to, ale

-dlaczego tak się dzieje?

-jak dobierać parametry do filtrowania napięcia

-kiedy filtrujemy napięcie (bo pewnie nie tylko przy serwomechanizmach?

*/

Udostępnij ten post


Link to post
Share on other sites
-dlaczego tak się dzieje?

Silnik pobiera prąd nieliniowo, zmienia się napięcie na zasilaniu, zmienia się odczyt ADC z potencjometru, silnik zaczyna pracować, ad infinitum.

-jak dobierać parametry do filtrowania napięcia

Jak nie masz oscyloskopu to na oko średni ceramiczny i duży elektrolit.

Jak masz to zmieniasz aż znikną szumy.

-kiedy filtrujemy napięcie (bo pewnie nie tylko przy serwomechanizmach?

Zawsze. A poważnie to zawsze, ale szczególnie gdy coś pobiera sporo prądu w sposób impulsowy (czyli najczęściej silniki).

Udostępnij ten post


Link to post
Share on other sites

Robiąc zadanie 6.2 napotkałem na pewien problem, mianowicie napisałem taki kod:

#define niebieska 5
#define czerwona 11

int odebraneDane = ""; //pusty ciąg odebramych danych

void setup() {
 // put your setup code here, to run once:
 Serial.begin(9600);
 pinMode(niebieska, OUTPUT);
 pinMode(czerwona, OUTPUT);

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

void loop() {
 // put your main code here, to run repeatedly:
 if(Serial.available() > 0) { //czy arduino odebrało dane
   odebraneDane = Serial.read ('\n');
 }

   switch (odebraneDane) {
     case 'n':
       digitalWrite(niebieska, HIGH);
       delay(1000);
       digitalWrite(niebieska, LOW);
       break;
     case 'c':
       digitalWrite(czerwona, HIGH);
       delay(1000);
       digitalWrite(czerwona, LOW);
       break;

       default:
         Serial.println("Zle wpisana wartosc");
         break;
}
}

Kompilator wyrzucał błędy konwersji jednych typów zmiennych na inne, albo błąd, polegający na tym, że switch nie jest liczbą całkowitą.

Na początku zmieniłem linijkę:

int odebraneDane = "";

na

int odebraneDane = 0;

Nie pomogło więc poszukałem w komentarzach poprawnie działającego kodu. Natrafiłem na post użytkownika Fajeczny. Zmieniłem

if(Serial.available() > 0) { //czy arduino odebrało dane
   odebraneDane = Serial.read ('\n');

na

while(Serial.available()==0);
     odebraneDane = Serial.read();

i zaczęło działać 😃 Może mi ktoś wyjaśnić dlaczego warunek z if'em nie działa? Ja to rozumiem tak, że jeżeli dane przychodzące są większe od 0 (różne?) to ma je przepisać do zmiennej odebraneDane. W pętli while też chodzi o to aby przychodzące dane był różne od 0? Mam nadzieję, że jasno wyjaśniłem mój problem, a tym czasem idę dalej z częścią 6.

Udostępnij ten post


Link to post
Share on other sites
albo błąd, polegający na tym, że switch nie jest liczbą całkowitą.

Porównaj jak realizujesz swoje odczytanie danych, które podajesz później do switch, z tym co robiłem ja we wcześniejszym przykładzie 🙂

Jeśli chodzi o drugą sprawę, to poniższy kod:

if(Serial.available() > 0) { //czy arduino odebrało dane 
   odebraneDane = Serial.read ('\n');

podczas "przelatywania" całej pętli sprawdza, czy w danej chwili są do oczytania jakieś znaki. Jeśli tak, to wykonuje tę czynność.

while(Serial.available()==0); 
     odebraneDane = Serial.read();

W tym przypadku wstrzymujesz cały program, do momentu, gdy nadejdą dane (krążysz w pustej pętli).

Udostępnij ten post


Link to post
Share on other sites

Zadanie 6.1

#define przycisk 2
int foto1 = 0; //Definicje zmiennych
int foto2 = 0;
int potencjometr = 0;
int i = 0;

void setup() {
 pinMode(przycisk, INPUT_PULLUP); //Definicja przycisku
 Serial.begin(9600); //Połączenie z serial monitorem
}

void loop() {
 if (digitalRead(przycisk) == LOW) { //Warunek sprawdzający czy wciśnięto przycisk
   foto1 = analogRead(A4); //Pobieranie wartości z fotorezystorów oraz potencjometru
   foto2 = analogRead(A3);
   potencjometr = analogRead(A5);
   i++; //Licznik wciśnięć
   Serial.print("Fotorezystor 1: "); //Wysyłane informacje
   Serial.print(foto1);
   Serial.print("\tFotorezystor 2: ");
   Serial.print(foto2);
   Serial.print("\tPotencjometr: ");
   Serial.print(potencjometr);
   Serial.print("\tPrzycisk wcisnieto ");
   Serial.print(i);
   Serial.print(" razy.\n");
   while (digitalRead(przycisk) == LOW) {} //Pętla zapobiegająca automatycznemu naliczaniu
 }
 delay(50);
}

Zadanie 6.2

int green = 8;
int red = 9;
int kolor = 0;

void setup() {
 Serial.begin(9600); //Inicjalizacja połączenia z PC
 pinMode(8, OUTPUT); //Ustawianie pinów 8 i 9 na output
 pinMode(9, OUTPUT);
}

void loop() {
 if (Serial.available() > 0) { // sprawdzanie czy coś zostało wpisane
   kolor = Serial.read(); // pobieranie wartości
   switch(kolor) {
     case 'c':
       if (digitalRead(red) == HIGH) {
         digitalWrite(red, LOW);
       } else {
         digitalWrite(red, HIGH);
       }
      break; 
      case 'z':
       if (digitalRead(green) == HIGH) {
         digitalWrite(green, LOW);        
       } else {
       digitalWrite(green, HIGH);        
       }
      break;
      default:
       Serial.println("Bledny kolor! Wprowadz 'c' dla czerwonej albo 'z' dla zielonej");
      break;
   }
 }
}
  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Takie coś znalazłem: linijka 8 przykład programu na czujnik.

serwomechanizm.attach(11); //Serwomechanizm podłączony do pinu 9

Poza tym, mała modyfikacja zadania domowego: ustawianie 2 serw za pomocą potencjometrów, wysyłanie położenia do kompa. Nie działało najlepiej, więc dodałem diody przy wykryciu aktywności. Okazuje się, że się zapalały nawet bez zabawy potencjometrami. Nie mam pojęcia dlaczego (na przykład przy zbliżeniu palucha do obudowy potencjometru).

#include <Servo.h>
Servo Serwo1;
Servo Serwo2;
int odczyt1 = 0;
int odczyt1a = 0;
int odczyt2 = 0;
int odczyt2a = 0;

void setup() {
Serial.begin(9600); //Ustawienie prędkości transmisji
Serwo1.attach(1); //Serwomechanizm 1
Serwo2.attach(2); //Serwomechanizm 2
pinMode(3, OUTPUT); //Dioda1
digitalWrite(3, LOW);
pinMode(4, OUTPUT); //Dioda2
digitalWrite(4, LOW);
}

void loop() {
 //odczytanie nastaw potęcjometrów
 odczyt1 = analogRead(A1);
 odczyt2 = analogRead(A2);
 //Dioda, jezeli zmiana
 delay(250);
 odczyt1a = analogRead(A1);
 odczyt2a = analogRead(A2);

 if(odczyt1 == odczyt1a) {
   //brak zmiany na potęcjmetrze 1
   digitalWrite(3, LOW);
 } else {
    odczyt1 = map(odczyt1, 0, 1023, 0, 180); //Przetworzenie bitów na kąt
    Serwo1.write(odczyt1);
    digitalWrite(3, HIGH); //załącz diodę1
    Serial.println(odczyt1); //informacja zwrotna
 }

  if(odczyt2 == odczyt1a) {
   //brak zmiany na potęcjmetrze 1
   digitalWrite(4, LOW);
 } else {
    odczyt2 = map(odczyt2, 0, 1023, 0, 180); //Przetworzenie bitów na kąt
    Serwo2.write(odczyt2);
    digitalWrite(3, HIGH); //załącz diodę1
    Serial.println(odczyt2); //informacja zwrotna
 }
}

Działało by chyba lepiej, po wsadzeniu drugiego IF w pierwsze...

Udostępnij ten post


Link to post
Share on other sites

Kurojatka, błędny komentarz poprawiłem - dziękuję za zwrócenie uwagi 🙂

Jeśli chodzi o problemy z odczytami ADC, to zerknij do odpowiedniej części: Kurs Arduino – #4 – Przetwornik ADC. Szczególnie w okolice zadania domowego 4.2. ADC jest bardzo czułe i odczyty nie są zbyt stabilne - trzeba brać to pod uwagę.

Udostępnij ten post


Link to post
Share on other sites

Ok. Podłączyłem z zasilacza, działa pięknie. Dla pewności znieczuliłem na zmiany mniejsze niż 5 stopni. Dzięki.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Witam. Mam pewien problem z zadaniem 6.1 i nie wiem, czy nie jest to jakiś problem z arduino.

Mój kod wygląda tak:

int swiatlo1 = 0;
int swiatlo2 = 0;
int przycisk = 0;
int potencjometr = 0;

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

void loop() {
   swiatlo1 = analogRead(A4);
   swiatlo2 = analogRead(A3);
   potencjometr = analogRead(A5);

 if(digitalRead(2) == LOW) {
   delay(150);
   przycisk = przycisk + 1;
   Serial.println("");
   Serial.print(" Fotorezystor1: ");
   Serial.print(swiatlo1);
   Serial.print("\t");
   Serial.print(" Fotorezystor2: ");
   Serial.print(swiatlo2);
   Serial.print("\t");
   Serial.print(" Potencjometr: ");
   Serial.print(potencjometr);
   Serial.print("\t");
   Serial.print(" Wcisniecia guzika: ");
   Serial.print(przycisk);
   delay(10);
     }   
     else {
       delay(50);
    }

}

I już tutaj zaczął się ciąg problemów:

1. Wiadomość nie wysyła się jednorazowo, tylko arduino nią spamuje (z początku myślałem, że jest to problem mojego programu, jednak gdy wkleiłem programy innych użytkowników forum było to samo)

2. Gdy już pozmieniałem kod dodając kolejne warunki tak, żeby wiadomość wysyłała się jednorazowo, to faktycznie tak było. Tylko to nie była wiadomość, tylko ciąg losowych znaków. (Takich, jakie się pojawiają, jak prędkości transmisji są różne.)

O dziwo problemy znikały, kiedy prędkość transmisji ustawiałem na 57600 baudów. Wiadomość wysyłała się pojedynczo i bez "zniekształceń".

W czym leży problem? To troche dziwne, żeby sama prędkość transmisji wpływała na działanie całego programu. Z początku myślałem, że to wadliwy guzik który blokuje swój stan, jednak wymieniłem go na inny i było to samo. Czy może być to wina samej płytki z arduino?

EDIT: Dobra, wróciłem do problemu i spróbowałem wpiąć guzik na 7 pin, a nie na drugi i... działa. Czy ktoś może mi wyjaśnić dlaczego? Pamiętam, że już kiedyś miałem podobny problem, że nie mogłem wgrać programu na płytkę, bo miałem coś wpięty w zerowy albo pierwszy pin (już nie pamiętam).

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