Skocz do zawartości

Kurs Arduino - #6 - kontynuacja UART, serwomechanizmy


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 🙂

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

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.

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

  • 2 tygodnie później...

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

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 🙂

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?

  • 1 miesiąc później...

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

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
}

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 🙂

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