Skocz do zawartości

Kurs Arduino - #6 - kontynuacja UART, serwomechanizmy


Komentator

Pomocna odpowiedź

polishbeer, piny 0 i 1 są pinami od UARTu, przez te same piny Arduino komunikuje się z komputerem (na płytce są w tym celu poprowadzone odpowiednie połączenia). W związku z tym czasami podłączenie tam różnych peryferiów może blokować proces programowania.

Jeśli chodzi o inne Twoje problem, to teraz ciężko już pomóc. Na 99,99% błędy tkwiły jednak w programie. Daj znać, gdy będziesz miał podobny problem opisz wtedy dokładnie wszystkie podłączenia. Postaram się pomóc, a tymczasem cieszę się, że już wszystko działa 🙂

Link do komentarza
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;
   }
 }
}

Witam, mam podobny problem z tym zadaniem:

#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 'c':
    digitalWrite(czerwona,HIGH);
    delay(1000);
    Serial.println("Wlaczyles kolor czerwony prawidlowy");
    digitalWrite(czerwona,LOW);
    break;

 case 'z':

     digitalWrite(zielona,HIGH);
     delay(1000);
     Serial.println("Wlaczyles kolor zielony prawidlowy");
     digitalWrite(zielona,LOW);
     break;

 default:
     Serial.println("Wpisales nieprawidlowy kolor!");
     break;

 }
}
 }

Przy podaniu znaku 'z' dostaję taki komunikat:

Wlaczyles kolor zielony prawidlowy
Wpisales nieprawidlowy kolor!
Wpisales nieprawidlowy kolor!

oczywiscie dioda zapala się i gaśnie. Ale komunikat powinnien mieć ten pierwszy tylko. Gdzie tu robię błąd? Pozdrawiam

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

Gdzie tu robię błąd?

Nie robisz 🙂 Jest tak samo, jak odpisałem na post, który cytujesz. Program działa poprawnie. W takiej wersji analizujemy każdy znak osobno. Dlatego litera "z" jest interpretowana jako poprawna, a każda inna jako zła.

Link do komentarza
Share on other sites

Zobacz czy terminal ci czegoś nie dodaje, na przykład \r\n.

BINGO:) Miałeś rację, teraz działa jak należy. Moja nieuwaga. Pozdrawiam

[ Dodano: 20-06-2016, 11:38 ]

Gdzie tu robię błąd?

Nie robisz 🙂 Jest tak samo, jak odpisałem na post, który cytujesz. Program działa poprawnie. W takiej wersji analizujemy każdy znak osobno. Dlatego litera "z" jest interpretowana jako poprawna, a każda inna jako zła.

Dzięki za odpowiedz. Poprawione dzięki podpowiedzi kolegi....🙂

Link do komentarza
Share on other sites

Witam piszę swój pierwszy post i tak chciałem przedstawić wam swoje rozwiązanie zadania 6.2

Denerwowało mnie że nie można było wyselekcjonować w programie całego słowa uruchamiającego ledę tzn żeby funkcja switch używała nie tylko znaku ale i poprawnie wpisanej nazwy koloru ledy który miał się zaświecić i w końcu mi się udało więc chciałem się z wami podzielić 🙂

#define zielona 8
#define czerwona 9
String odebraneDane = "";
bool stanZielonej = 0;
bool stanCzerwonej = 0;
char kolor;

void setup() {
 Serial.begin(9600);
 pinMode(zielona, OUTPUT);
 pinMode(czerwona, OUTPUT);
 digitalWrite(zielona, LOW);
 digitalWrite(czerwona, LOW);
 Serial.println("Wybierz kolor ledy, ktory chcialbys wlaczyc");
 Serial.println("Do wyboru masz: zielony albo czerwony");
}

void loop() {
 if(Serial.available() >0) {
   odebraneDane = Serial.readStringUntil('\n');
   if(odebraneDane == "zielony"){
     kolor = '1';
     Serial.println("Zapaliles zielona Led");
   } else if(odebraneDane == "czerwony"){
     kolor = '2';
     Serial.println("Zapaliles czerwona Led");
   } else {
     kolor = '0';
   }

   switch(kolor){
     case '1':
       stanZielonej = !stanZielonej;
       digitalWrite(zielona, stanZielonej);
     break;
     case '2':
       stanCzerwonej = !stanCzerwonej;
       digitalWrite(czerwona, stanCzerwonej);
     break;
     default:
       Serial.println("Nie ma takiego koloru!");
     break;
   }
 }
 delay(50);
}

wpisanie słów kluczowych "zielony lub czerwony" włączy odpowiednie ledy a jak ktoś zrobi literówkę to wywali błąd

Pozdrawiam 🙂

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

rapskot, dobra robota 🙂 Właśnie tak można to rozwiązać w stosunkowo prosty sposób. Trochę zatraca się wtedy sens korzystania "drugi raz" ze switch'a (bo w takiej wersji można od razu zmienić stan diod w if'ach), ale grunt, ze działa 🙂

Link do komentarza
Share on other sites

Tez tak myslalem ale jak wpisywalem komende "czerwony" to tam wystepuje znak "c" i "z" a to powodowalo ze od razu zaswiecaly sie dwie diody. Wiec musialem sie tego jakos pozbyc a tylko w taki sposob program mi dzialal 😉

Moze ktos zna jeszcze inny sposob latwiejszy?

Link do komentarza
Share on other sites

Zadanie 6.1

#define przycisk 8 

byte ilosc = 1;
int frez1 = 0;
int frez2 = 0;
int potencjometr = 0;

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

Serial.println("Fotorezystor 5-10kO: F 1"); //legenda
Serial.println("Fotorezystor 20-30kO: F 2");
Serial.println("Potencjometr 5kO: P");
} 

void loop() 
{ 
 potencjometr = analogRead(A0); //odczyty wartosci przez ADC
 frez1= analogRead(A1);      
 frez2= analogRead(A2);  


 if(digitalRead(przycisk)==LOW)//jesli guzik wcisniety
 { 
  Serial.print("|F 1: "); 
  Serial.print(frez1); 

  Serial.print("\t|F 2: "); 
  Serial.print(frez2); 

  Serial.print("\t|P: "); 
  Serial.print(potencjometr); 

  Serial.print("\t|Przycisk wcisnieto:"); 
  Serial.print(ilosc); 
  Serial.print(" razy|\n"); 
  ilosc++; 

 while(digitalRead(przycisk)==LOW) ; //Do nastepnego wciśniecia
 } 
 delay(50); //Opoznienie
}

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

 Serial.println("Wybierz kolor diody"); //Legenda
 Serial.println("1-zielona, 2-czerwona");
} 

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); //To włączamy diodę zieloną
       delay(1000); 
       digitalWrite(zielona, LOW); 
     break; 
     case '2': 
      digitalWrite(czerwona, HIGH); //To włączamy diodę czerwoną 
      delay(1000); 
      digitalWrite(czerwona, LOW); 
     break; 
     default: //Jezeli inne 
      Serial.println("Bledny kolor. 1-zielona, 2-czerwona"); 
     break; 

   } 
 } 
}

No i 6.4 - tym razem garażowo 😉

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

Mam pytanie, czy to przy kontrolowaniu serwa przez potencjometr, czy przez fotorezystor, odczyty ciągle skaczą +-30, przez co serwo caly czas pracuje. Próbowałem zasilać z zasilacza, wkladać elektrolit 1mF miedzy zasilanie fotorezystora a masę - dalej to samo.

A tu jakby ktoś chciał, kod do zadania 6.3

#include <Servo.h> //Biblioteka odpowiedzialna za serwa
#define button 7
#define led 6
#define fotorezystor A5

Servo serwomechanizm;  //Tworzymy obiekt, dzięki któremu możemy odwołać się do serwa 
byte pozycja = 0; //Aktualna pozycja serwa 0-180
int pozycjaPoprzednia = 0;
int prog_dolny = 0;
int prog_gorny = 900;
int temp = 0;

void setup() { 
 serwomechanizm.attach(9);  //Serwomechanizm podłączony do pinu 11
 Serial.begin(9600);
 pinMode(button, INPUT_PULLUP);
 pinMode(led, OUTPUT);
} 

void loop() 
{ 
 int odczytCzujnika = analogRead(fotorezystor); //Odczytujemy wartość z czujnika
 pozycja = map(odczytCzujnika, prog_dolny, prog_gorny, 0, 180); //Zamieniamy ją na pozycję serwa

 if(digitalRead(button) == 0){
   delay(5000); // po 5s jesli dalej wciskasz, to sie dzieje magia
   digitalWrite(led, HIGH); //zapal diode, ze przechodzisz juz do opcji wyboru progu dolnego

   if(digitalRead(button) == 0){
     temp = prog_dolny;
     prog_dolny = analogRead(fotorezystor);
     delay(1000);
     digitalWrite(led,LOW); //zgas diode - jestes w tym trybie, zostaly ci 2 sekundy a przejdziesz do kolejnego trybu
     delay(1700); //teraz zamrugaj diodami, ze przechodzisz  do 2 trybu.
     digitalWrite(led,HIGH);
     delay(100);
     digitalWrite(led,LOW);
     delay(100);
     digitalWrite(led,HIGH);
     delay(100);
     digitalWrite(led,LOW);

     if(digitalRead(button) == 0){
       prog_dolny = temp; //zeruj do poprzedniej wartosci, uzytkownikowi chodzilo o prog gorny
       temp = prog_gorny;
       prog_gorny = analogRead(fotorezystor);
       delay(2500); // za 2500 wyjdziesz z opcji wyboru i wszystko bedzie jak bylo
       digitalWrite(led,HIGH); //mrug babe mrug 3x
       delay(100);
       digitalWrite(led,LOW);
       delay(100);
       digitalWrite(led,HIGH);
       delay(100);
       digitalWrite(led,LOW);
       delay(100);
       digitalWrite(led,HIGH);
       delay(100);
       digitalWrite(led,LOW);
       if(digitalRead(button) == 0){
         prog_gorny = temp;
         delay(1000);
       }
     }
   }
 }

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

 Serial.print("Odczyt Czujnika: "); 
 Serial.print(odczytCzujnika); //Wysyłamy wartość do terminala
 Serial.print("\t prog dolny: ");
 Serial.print(prog_dolny);
 Serial.print("\t prog gorny: ");
 Serial.println(prog_gorny);
 delay(300); //Opóźnienie dla lepszego efektu
}
Link do komentarza
Share on other sites

gawroon7, jeśli piszesz o "skokach" w odczytach ADC, to jest to normalne. Raczej nigdy nie będzie tak, że wartości będą "stałe". To już miejsce, w którym musi popisać się programista - możesz np. dorobić tam uśrednianie wartości na podstawie kliku odczytów 🙂

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.