Skocz do zawartości
Komentator

Kurs Arduino - #6 - kontynuacja UART, serwomechanizmy

Pomocna odpowiedź

W takim razie wstawiam swoje rozwiązania 🙂

Zadanie 6.1

#define przycisk 8

int potencjometr = 0;
int fotorezystor1 = 0;
int fotorezystor2 = 0;
int wcisnieciePrzycisku = 0;

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

void loop() {
 potencjometr = analogRead(A5);
 fotorezystor1 = analogRead(A3);
 fotorezystor2 = analogRead(A4);

 while(digitalRead(przycisk)==HIGH); ////Program czeka na wciśnięcie przycisku
 delay(500); //Odczekanie dla uniknięcia powielania
 wcisnieciePrzycisku++;  //Po wciśnięciu przycisku zostanie dodana wartość

 Serial.print("Fotorezystor 1: ");
 Serial.print(fotorezystor1);
 Serial.print(", fotorezystor2: ");
 Serial.print(fotorezystor2);
 Serial.print(", potencjometr: ");
 Serial.print(potencjometr);
 Serial.print(", przycisk wcisnieto ");
 Serial.print(wcisnieciePrzycisku);
 Serial.print(" razy.\n");
 Serial.println();
}

Zadanie 6.2

#define czerwona 8
#define zielona 9

int odebraneDane = 0;

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

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

void loop() {

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

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

   case 'c':
     digitalWrite(czerwona,HIGH);
     delay(1000);
     digitalWrite(czerwona,LOW);
   break;

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

 delay(1000);
}

Zadanie 6.3 (trochę prowizoryczne, ale działa 😋 )

#include <Servo.h>

Servo serwomechanizm; //Obiekt, dzięki któremu możemy odwołać się do serwa
byte pozycja = 0; //0*-180*
int pozycjaPoprzednia = 0;
int odczytCzujnika = 0;
int maksimum = 0;
int minimum = 10000;

void setup() {
 serwomechanizm.attach(10);
 Serial.begin(9600);
}

void loop() {
 odczytCzujnika = analogRead(A5);

 if(odczytCzujnika > maksimum)
   maksimum = odczytCzujnika;

 if(odczytCzujnika < minimum)
   minimum = odczytCzujnika;
 pozycja = map(odczytCzujnika, 0, 900, 0, 180);

 if(abs(pozycja-pozycjaPoprzednia) > 5){ //Sprawdzamy, czy pozycje różnią się o ponad 5 stopni
   serwomechanizm.write(pozycja); //Wykonujemy ruch
   pozycjaPoprzednia = pozycja; //Zapamiętujemy aktualną pozycję nadpisując poprzednią
 }

 Serial.print("Aktualny odczyt: ");
 Serial.println(odczytCzujnika);
 Serial.print("Maksimum: ");
 Serial.println(maksimum);
 Serial.print("Minimum: ");
 Serial.println(minimum);
 Serial.println();
 delay(1000);
}

Zadanie 6.4

Nie mam niczego specjalnego - zwykły orczyk i mały, kwadratowy prostokąt, ale jak już wstawiam wszystkie zadania, to i zdjęcie wrzucę 😉

Przy okazji: jak można zmienić kierunek obrotu serwa na zgodny ze wskazówkami zegara?

Udostępnij ten post


Link to post
Share on other sites

Fajeczny,

Przy okazji: jak można zmienić kierunek obrotu serwa na zgodny ze wskazówkami zegara?

Odwrócić je o 180 st?

Udostępnij ten post


Link to post
Share on other sites

Zadanie 6.3 i 6.4

Trochę rozwinąłem to zadanie dodając regulację skrajnych wychyleń serwa w celu dopasowania do różnych tarcz. Autokalibracja i regulacja wychylenia jest możliwa w trybie konfiguracyjnym (patrz kod). Niestety, z racji braku kondensatorów (po weekendzie czeka mnie wycieczka do sklepu) nie mogłem dać na serwo zasilania z gniazda Vin, więc podpiąłem je pod gniazdo 5V. Do zasilania wykorzystałem zasilacz impulsowy 12V 2A. Wklejam kod i zdjęcie układu poniżej. Czekam na wszelkie opinie i rady, gdyż jestem nowy w elektronice i każda pomoc się przyda 🙂

/* 
 This program is used to measure current level of light
 and write it to the servomechanism, which is used as 
 a simulation of analog gauge. The program includes the
 configuration mode with autocalibration.

 USE CONFIGURATION MODE BEFORE FIRST USE!
*/

#include <Servo.h> //includes servo library

#define potPin A1 //potentiometer pin
#define lightPin A0 //photoresistor pin
#define switchPin 9 //tact-switch pin
#define servoPin 10 //servo controller pin

Servo servo; //servo initialisation

void setup() {

 pinMode(switchPin, INPUT_PULLUP); //sets switch pin to pull up mode
 servo.attach(servoPin); //attaches servo pin to object
 Serial.begin(9600); //initialisation of serial monitor

}

int minValue = 0; //minimum value of rotation
int maxValue = 180; //maximum value of rotation
int rotationValue = 0; //current rotation value
int previousValue = 0; //previous rotation value
int maxReadValue = 1023; //maximum read value of light in current environment

void loop() {

 //CONFIGURATION MODE
 if (digitalRead(switchPin) == LOW) //if button pushed go into configuration mode
 {
   delay(300); //eliminates bouncing on button

   //ADJUST MINIMUM VALUE
   while (digitalRead(switchPin) == HIGH) //loop until the button is pushed
   {
     rotationValue = analogRead(potPin); //reads potentiometer value
     rotationValue = map(rotationValue, 0, 1023, 180, 90); //maps value to fit the rotation
     servo.write(rotationValue); //writes the rotation to servo to show current setting
     delay(100); //delay for smoother effect
   }
   delay(300); //eliminates bouncing on button
   minValue = rotationValue; //sets chosen value as minimum rotation value

   //ADJUST MAXIMUM VALUE
   while (digitalRead(switchPin) == HIGH)
   {
     rotationValue = analogRead(potPin); //reads potentiometer value
     rotationValue = map(rotationValue, 0, 1023, 0, 90); //maps value to fit the rotation
     servo.write(rotationValue); //writes the rotation to servo to show current setting
     delay(100); //delay for smoother effect
   }
   delay(300); //eliminates bouncing on button
   maxValue = rotationValue; //sets chosen value as maximum rotation value
   rotationValue = 90;

   //AUTOCALIBRATION
   Serial.println("Light measurement started");

   for(int i = 0; i < 50; i++) //loop lasts for 5s -> 50 * 100ms = 5000 ms = 5s
   {
     maxReadValue = analogRead(lightPin); //reads value from photoresistor
     delay(100); //delay for smoother effect
   }

   Serial.println("Light measurement finished");

   maxReadValue *= 2; //doubles maximum read value

   if(maxReadValue > 1023) //if the value is over the maximum supported value
   {
      maxReadValue = 1023; //sets value to maximum supported value
   }

 }

 //NORMAL MODE
 else
 {
   int lightValue = analogRead(lightPin); //reads current photoresistor value
   rotationValue = map(lightValue, 0, maxReadValue, minValue, maxValue); //maps value for rotation

   if (abs(rotationValue - previousValue) > 5) //if the difference of values is bigger than 5 degrees
   {
     servo.write(rotationValue); //writes current rotation value to servo
     previousValue = rotationValue; //sets current value as previous value
     delay(100); //delay for smoother effect
   }

   Serial.println(lightValue); //sends current light value to terminal
   delay(100); //delay for smoother effect

 }

}

__________

Komentarz dodany przez: Treker

Udostępnij ten post


Link to post
Share on other sites

Zadanie 6.1

#define przycisk 7

int potencjometr=0;
int fotorezystor1=0;
int fotorezystor2=0;
int nacisniecia=0;

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

}

void loop() {
  potencjometr=analogRead(A4);
  fotorezystor1=analogRead(A5);
  fotorezystor2=analogRead(A3);

  if(digitalRead(przycisk)==LOW){

     Serial.print("Fotorezystor 1: ");
     Serial.print(fotorezystor1);
     Serial.print("\t Fotorezystor 2: ");
     Serial.print(fotorezystor2);
     Serial.print("\t Potencjometr: ");
     Serial.print(potencjometr);
     nacisniecia+=1;
     Serial.print("\t Nacisniecia: ");
     Serial.print(nacisniecia);
     Serial.print("\n");
     delay(300);

   }
}

Zadanie 6.2

#define zielona 8
#define czerwona 9

int odebraneDane=0; 

void setup() {
 Serial.begin(9600); //Uruchomienie komunikacji
 pinMode(zielona, OUTPUT); //Konfiguracja wyjść
 pinMode(czerwona, OUTPUT);

 digitalWrite(zielona, LOW); //Wyłączamy diody
 digitalWrite(czerwona, LOW);
}

void loop() {
 if(Serial.available() > 0) { //Czy Arduino odebrano dane
                              //Jeśli tak, to odczytujemy je do znaku końca linii i zapisz w zmiennej odebraneDane
   odebraneDane = Serial.read(); 

   switch(odebraneDane){
     case '1':
       digitalWrite(zielona,HIGH);
       delay(1000);
       digitalWrite(zielona, LOW);
     break;
     case '2':
      digitalWrite(czerwona, HIGH); //To włączamy diodę czerwoną
      delay(1000);
      digitalWrite(czerwona, LOW);
     break;
     default:
      Serial.println("Bledny kolor. 1-zielona, 2-czerwona");
     break;

   }
 }
}

Udostępnij ten post


Link to post
Share on other sites

Witam,
W sumie to widzę, że w kodach poprzedników jest ten sam "błąd" ale ja jednak chciałbym dowiedzieć się jak to naprawić.

A więc program działa dobrze jeżeli wpiszemy do "szeregowego monitora" jeden znak.

Natomiast jeśli wpiszę np. zxcvbn to zaświeci mi się dioda (bo pierwsza litera to prawidłowe "z" i wyskoczy mi 5 razy, że wpisałem złą liczbę kolejno dla x, c, v, b, n.

Wiecie jak temu zaradzić?

Oto kod:

#define zielona 8
#define czerwona 9

int odebraneDane = 0; //Pusty ciąg odebranych danych

void setup() {
 Serial.begin(9600); //Uruchomienie komunikacji
 pinMode(zielona, OUTPUT); //Konfiguracja wyjść
 pinMode(czerwona, OUTPUT);

 digitalWrite(zielona, LOW); //Wyłączamy diody
 digitalWrite(czerwona, LOW);
}

void loop() 
{
 if(Serial.available() > 0) { //Czy Arduino odebrano dane
   //Jeśli tak, to odczytujemy je do znaku końca linii i zapisz w zmiennej odebraneDane
   odebraneDane = Serial.read(); 


   switch (odebraneDane) { 
     case 'z':  //Jeśli odebrano "z"

       digitalWrite(zielona, HIGH); //To włączamy diodę zieloną
       delay(1000);
       digitalWrite(zielona, LOW); 
     break;

     case 'c':  //Jeśli odebrano "c"

       digitalWrite(czerwona, HIGH); //To włączamy diodę czerwoną
       delay(1000);
       digitalWrite(czerwona, LOW); 
     break;

     default:
       Serial.println("Podano zly kolor, podaj [z] dla diody zielonej");
       Serial.println("[c] dla diody czerwonej");
       break;
   }
 }
}

Udostępnij ten post


Link to post
Share on other sites

Razor1996, wszystko się zgadza, program sprawdza po jednej literze, więc każda kolejna interpretowana jest osobno.

Udostępnij ten post


Link to post
Share on other sites
pozycja = map(odczytCzujnika, 0, 900, 0, 180); //Zamieniamy ją na pozycję serwa

Treker mógłbyś mi powiedzieć dlaczego masz wartosć w tej linijce "900"?

Udostępnij ten post


Link to post
Share on other sites

piotr1990, wartość taka została dobrana eksperymentalnie. W moim przypadku nigdy wartość odczytana z fotorezystora nie przekraczała ~950 jednostek. Chciałem lepiej wykorzystać zakres ruchu, więc nie rezerwowałem końca skali dla odczytów, które się nigdy nie pojawiały.

Udostępnij ten post


Link to post
Share on other sites

Czy mogę prosić o przetłumaczenie na język ludzki 😅 jednej linijki kodu.

Zrobiłem zadanie domowe nr 6.2

Po wpisaniu litery moje diody migały. Sprawdziłem więc rozwiązania kolegów na forum i okazało się, że kolega Fajeczny zrobił zadanie prawie identycznie. Różnica jest taka:

Ja wpisałem:


if (Serial.available() > 0)
   {
     odebraneDane = Serial.read();
   }

a Fajeczny:


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

Nie potrafię sobie "przetłumaczyć" instrukcji Fajecznego: "dopóki nie odczytujesz nic..., odczytaj pierwszy znak i wrzuć do zmiennej odebraneDane" ??? Kompletnie się zgubiłem...

Udostępnij ten post


Link to post
Share on other sites

Zauważ, że w linii zawierającej while jest średnik. To oznacza, że ciało tej instrukcji jest puste a jej działanie można wytłumaczyć jako: dopóki nie ma żadnego znaku, rób nic (czyli czekaj). Wcięcie w następnej linii jest zupełnie niepotrzebne i zaciemnia obraz. Lepsza byłaby forma:

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

wyraźnie pokazująca "pustość" pętli while;

Udostępnij ten post


Link to post
Share on other sites

aaa, noo właśnie 😃 Bardzo Ci dziękuję za pomoc teraz już kapuję!

Jeszcze tylko jedna kwestia.

Kolejny problem na jaki natrafiłem to zero odpowiedzi ze strony serwomechanizmu (HD-1370A). Zasłaniam fotorezystor i odsłaniam (wartości od ~900 do ~1010) a servo ani drgnie.

Czy jest to możliwe, że mam założone zbyt duże kondensatory?

Niestety kupiłem w Botlandzie inny zestaw niż przewidziany w kursie... potem dokupiłem zestaw kondensatorów ale okazało się, że nie ma tam wartości uF 😕

Mam więc założone 2 x 100nF...

Udostępnij ten post


Link to post
Share on other sites

Kapat, ciężko mi doradzić, jeśli wykorzystałeś inne części od wymaganych w kursie. 200nF to zdecydowanie zbyt mało dla filtracji zasilania przy wykorzystaniu silnika. Sprawdź informacje z kursu elektroniki: Kurs elektroniki – #4 – kondensatory

Udostępnij ten post


Link to post
Share on other sites

Szkoda bo jestem zielony i właściwie wszystko na początku sprawia trudności.

Swoją drogą to troszkę irytujące jest doszukiwanie się w każdej lekcji, czy aby na pewno mam właściwy zestaw... Swój zakupiłem właśnie dzięki linkom z lekcji #0. Niestety po kliknięciu, w sklepie Botland pojawiają się cztery zestawy. Który jest właściwy? Ten najdroższy?

Treker a mogę Cię choć prosić, żebyś podał jaki zakres kondensatorów mogę użyć na pewno?

Wiem, że już ktoś o to pytał ale nie mogę znaleźć.

Udostępnij ten post


Link to post
Share on other sites

One się różnią tylko obecnością Arduino i gadżetów Frobota o ile dobrze pamiętam. Masz wszystko w opisach.

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