Skocz do zawartości

Kurs Arduino - #3 - UART (komunikacja z PC), zmienne


Pomocna odpowiedź

bool ostatniStan = false;

void setup() {
pinMode(2, OUTPUT);
digitalWrite(2, LOW);
pinMode(3, INPUT_PULLUP);
}

void loop() {
if(digitalRead(3) == LOW){
 
    if(ostatniStan == false){
      digitalWrite(2, HIGH);
      ostatniStan = true;
    }

    else if(ostatniStan == true){
      digitalWrite(2, LOW);
      ostatniStan = false;
    }
    delay(500);
  }
  }

Po paru dniach walki udało mi się zrobić ostatnie zadanie, a nawet je trochę przerobić :-- ) 

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

Cześć!

Zrobiłem taką trochę prostszą wersje ostatniego zadania (pominąłem krok z kilkoma podejściami - albo wygrywasz albo przegrywasz). Wszystko działa okej, tylko problem jest z tym, że od czasu do czasu napięcie które rzekomo jest na pinie A5 jest totalnie z kosmosu. Np. wiem, że jest to wartość graniczna 0 lub 1023, bo przekręciłem na maksa, a tutaj nie wiadomo skąd 300... Czy ktoś mógłby mi coś tutaj doradzić?

#define potPin A5
#define green 9
#define red 10
#define switchPin 2
int potVal;
int potVal05;
int potVal15;
int delayTime1= 3000;
int delayTime2= 2000;
int delayTime3= 10000;

int readVal;
int plusMinusVal = 50;
String msg6 = "Potencjometr to takie urzadzenie, ze mozemy zmieniac napiecie na jego wyjsciu (w naszym przypadku na pomaranczowym kabelku)";
String msg0 = "Twoim Zadaniem Jest Zgadnac Jakie Napiecie Jest na Potencjometrze"; 
String msg = "Ustaw Napiecie na Potencjometrze (Pokrec Srubokrentem) i Kliknij w Przycisk";
String msg1 = "Teraz Wpisz Liczbe od 0 do 1023, Ktora Oznacza Wartosc Napiecia i Kliknij Enter. Margines zaliczanej odpowiedzi to +/- 50";
String msg2 = "Brawo!!! Dobra Odpowiedz! Wygrales!";
String msg3 = "Niestety. Tym Razem Nie Trafiles. Przegrales.";
String msg4 = "Strzelasz, ze Napiecie na Potencjometrze Wynosi: ";
String msg5 = "Tak Naprawde Napiecie Wynosi: ";

void setup() 
{
Serial.begin(9600);
pinMode(potPin, INPUT);
pinMode(green, OUTPUT);
pinMode(red, OUTPUT);
pinMode(switchPin, INPUT_PULLUP);

}

void loop() 
{
Serial.println (msg6);
delay(delayTime2);
Serial.println();

Serial.println (msg0);
delay(delayTime2);
Serial.println();

Serial.println (msg);
Serial.println();

potVal = analogRead(potPin);
potVal05 = potVal - plusMinusVal;
potVal15 = potVal + plusMinusVal;

while(digitalRead(switchPin) == HIGH) {}

if(digitalRead(switchPin) == LOW){
  Serial.println(msg1);
  Serial.println();
  delay(delayTime2);}

while(Serial.available() == 0) {}

readVal = Serial.parseInt();
delay(delayTime2);
Serial.print(msg4);
Serial.println(readVal);
Serial.println();
delay(delayTime2);
if(potVal05 <= readVal && potVal15 >= readVal) {
  digitalWrite(green, HIGH);
  Serial.println(msg2);
  Serial.println();
  delay(delayTime1);
  digitalWrite(green, LOW);
 
  
} else {
  digitalWrite(red, HIGH);
  Serial.println (msg3);
  Serial.println();
  delay(delayTime1);
  digitalWrite(red, LOW);
  
}
delay(delayTime2);
Serial.print (msg5);
Serial.println (potVal);
Serial.println ();
Serial.println();
delay(delayTime3);
}

 

272302612_465378558464509_1281402985905156300_n.jpg

Link do komentarza
Share on other sites

@Franek100 wolę nie pytać dlaczego masz przycisk pomiędzy szyną + i -. Mam nadzieję, że to działa jak należy 🙂 

Pierwsza uwaga do kodu to unikaj tylu Stringów, testowałem kiedyś moment, w którym Arduino UNO powie dosyć i jest to sporo więcej, ale zwracaj na to uwagę. Tu pod koniec masz test: 

 

Co do tej losowej wartości, to może na płytce coś nie styka albo jest źle połączone. Spróbuj zmontować jeszcze raz - jak będzie luźne połączone to wetknij blisko siebie, albo 2 kabelki w jeden otwór. Jak nie zadziała dodaj kondensator pomiędzy ADC a masą.

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

#define zielona 8
#define czerwona 10

String odebraneDane = "";
boolean przelaczG = false; //do sprawdzania, czy dioda zielona była wybierana
boolean przelaczR = false; //do sprawdzania, czy dioda czerwona była wybierana

void setup() {
  Serial.begin(9600); //komunikacja z portem COM

  pinMode(zielona, OUTPUT);
  pinMode(czerwona, OUTPUT);

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

}

void loop() {
  if (Serial.available() > 0) {
    odebraneDane = Serial.readStringUntil('\n'); //Odczyt tekstu z komputera


    if (odebraneDane == "zielona") //przypadek 1: wybrano zieloną diodę
    {
      if (przelaczG == false) { //sprawdzenie czy już ktoś wybierał wcześniej diodę zieloną, domyślnie nie była wybrana
        digitalWrite(zielona, HIGH);
        przelaczG = true;
      }
      else if (przelaczG == true) { //jeśli była wybrana wcześniej, to zostanie wybrany stan przeciwny
        digitalWrite(zielona, LOW);
        przelaczG = false;
      }
    }

    else if (odebraneDane == "czerwona") //przpadek 2: wybrano diodę czerwoną
    {
      if (przelaczR == false) { //sprawdzenie czy ktoś wybierał wcześniej diodę czerwoną
        digitalWrite(czerwona, HIGH);
        przelaczR = true;
      }
      else if (przelaczR == true) { //jeśli była wybrana wcześniej, to zostanie wybrany stan przeciwny
        digitalWrite(czerwona, LOW);
        przelaczR = false;
      }
    }
    else (Serial.println("Błędny kolor!")); //komunikat, gdy nie wybrano koloru zielonego lub czerwonego
  }

}

Oto moje rozwiązanie zadania 2.5 z wybieraniem przeciwnych statusów diod. 

  • Lubię! 1
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

@slv7 super 🙂 

To taka edukacyjna uwaga:

if (przelaczR == false) { //sprawdzenie czy ktoś wybierał wcześniej diodę czerwoną
        digitalWrite(czerwona, HIGH);
        przelaczR = true;
      }
      else if (przelaczR == true) {

możesz uprościć warunku:

if (!przelaczR) { //sprawdzenie czy ktoś wybierał wcześniej diodę czerwoną
        digitalWrite(czerwona, HIGH);
        przelaczR = true;
      }
      else if (przelaczR) {

 

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

Witam proszę o sugestie jak możemy skonfigurować jeszcze zadanie 2.4

Użyłem else...

#define zielona 8
#define czerwona 9
 
String odebraneDane = ""; //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 odebrało dane
    //Jeśli tak, to odczytujemy je do znaku końca linii i zapisz w zmiennej odebraneDane
    odebraneDane = Serial.readStringUntil('\n'); 
    
    if (odebraneDane == "zielona") { //Jeśli odebrano słowo "zielona"
      digitalWrite(zielona, HIGH); //To włączamy diodę zieloną
      delay(1000);
      digitalWrite(zielona, LOW); 
    }
    if (odebraneDane == "czerwona") { //Jeśli odebrano słowo "czerwona"
      digitalWrite(czerwona, HIGH); //To włączamy diodę czerwoną
      delay(1000);
      digitalWrite(czerwona, LOW); 
    }
    else
    {
       Serial.println("zly kolor");
    }
    
    
  }
}

 

Link do komentarza
Share on other sites

Dnia 18.05.2015 o 18:11, pempol napisał:

o widzisz, spróbuję ponownie 🙂

/edit

Spróbowałem, zacząłem od nowa z zadaniem 2.3 i dało radę. Wcześniej miałem taką sytuację, że nawet jak wpisałem poprawny kolor to wyświetlało mi komunikat o błędzie. Po zmianie wygląda to tak.


//Zadanie domowe 2.3
//Gdy wpisany zły kolor diody, wyświetla komunikat o błędzie
//

#define GREEN 8
#define RED 9

String odebraneDane = ""; //pusty ciąg odebranych danych

void setup() {
 Serial.begin(9600); //Ustawienie prędkości transmisji ilość baudów
 //Inicjalizacja połączenia z PC
 pinMode(GREEN, OUTPUT); //Konfiguracja wyjść
 pinMode(RED, OUTPUT);

 digitalWrite(GREEN, LOW); //Wyłączamy diody
 digitalWrite(RED, LOW);
}

void loop() {
 // put your main code here, to run repeatedly:
 if (Serial.available() > 0) {//Czy Arduino odebrało dane
 //Jeśli tak, to odczytaj je do znaku końca linii i zapisz w zmiennej odebraneDane
   odebraneDane = Serial.readStringUntil('\n'); 

   if (odebraneDane == "green") { //gdy wpisane 'green'
     digitalWrite(GREEN, HIGH); //wlaczamy diode GREEN
     delay(1000);
     digitalWrite(GREEN, LOW);
   }
   else {
     if (odebraneDane == "red") { //gdy wpisane 'red'
       digitalWrite(RED, HIGH);
       delay(1000);
       digitalWrite(RED, LOW);
     }
     else {
       //Wyświetla komunikat o błędnie wprowadzonym kolorze
       Serial.println("Blad. Wprowadzona nazwa nie jest obslugiwanym kolorem diody.");
       Serial.println("Obslugiwane kolory: 'green' oraz 'red'.");
     }
   } //end of else od odebraneDane=="green"
 } //end of if wprowadzono >0 znakow
 //pusty else
} //end of void loop()
 

I odpowiednio po zastosowaniu tego w połączeniu ze zmienną logiczną, mamy odpowiedź na zadanie 2.4, która prezentuje się tak


//Zadanie domowe 2.4
//Napisz program, który po wysłaniu koloru diody zmieni jej stan na przeciwny. 
//Jeśli dioda jest włączona, to zostanie wyłączona i na odwrót.

#define GREEN 8
#define RED 9

String odebraneDane = ""; //pusty ciąg odebranych danych

boolean AreGreenON = false; //zmienna logiczna, czy GREEN (8) ON
boolean AreRedON = false; //zmienna logiczna, czy Red (9) ON 


void setup() {
 Serial.begin(9600); //Ustawienie prędkości transmisji ilość baudów
 //Inicjalizacja połączenia z PC
 pinMode(GREEN, OUTPUT); //Konfiguracja wyjść
 pinMode(RED, OUTPUT);

 digitalWrite(GREEN, LOW); //Wyłączamy diody
 digitalWrite(RED, LOW);
}

void loop() {
 // put your main code here, to run repeatedly:
 if (Serial.available() > 0) {//Czy Arduino odebrało dane
 //Jeśli tak, to odczytaj je do znaku końca linii i zapisz w zmiennej odebraneDane
   odebraneDane = Serial.readStringUntil('\n');
   if (odebraneDane == "green") { //jak wpisane 'green'
     delay(100);
     AreGreenON = !AreGreenON; //negacja wartosc AreGreenOn     
     digitalWrite(GREEN, AreGreenON); //To włączamy lub wyłaczamy diodrę GREEN
     delay(500);
     Serial.println("AreGreenON = ");
     Serial.println(AreGreenON);
     Serial.println("");
   }
   else { //w przeciwnym wypadku
     if (odebraneDane == "red") { //gdy wpisane 'red'
       delay(100);
       AreRedON = !AreRedON; //negacja wartosci AreRedOn
       digitalWrite(RED, AreRedON); //To wl/wyl diodę RED w zaleznosci od AreRedOn
       delay(500);
       Serial.println("AreRedON = ");
       Serial.println(AreRedON);
       Serial.println("");
     }
     else { //w przeciwnym wypadku - od 'red' i takze od 'green'
       //Wyświetla komunikat o błędnie wprowadzonym kolorze
       Serial.println("Blad. Wprowadzona nazwa nie jest obslugiwanym kolorem diody.");
       Serial.println("Obslugiwane kolory: 'green' oraz 'red'.");
     } //end of else 'red'
   } //end of else od 'green'
 } //end of if gdy wprowadzono wiecej niz 0 znakow
} //end of void loop()
 

Miłego dnia i czekam na kolejne lekcje:]

pempol

Hejka, fajny przykład ale nie potrafię zrozumieć zmieniłem boolean na true i w programie nic się nie zmieniło działa tak samo. Poza tym negacje AreRedON = !AreRedON nie wiem jakie to ma działanie. Negujemy czyli zaprzeczamy czemuś wiec czy wpisując red jeśli faktyczny stan jest niski to negacją tego stanu będzie wysoki? i na odwrót gdy dioda świeci mamy stan wysoki wpisujemy red wtedy gaśnie bo mamy tą negacje 😂 ? Sorki chłopaki ale jakoś lepiej mi się myśli pisząc 😂  Proszę dajcie znać jak mogę to łatwiej zrozumieć. Pozdrówki.  

Link do komentarza
Share on other sites

20 godzin temu, mn860618 napisał:

jeśli faktyczny stan jest niski to negacją tego stanu będzie wysoki?

@mn860618 tak właśnie będzie. Czasem też w mowie pytamy o jakieś zaprzeczenia, bo do czegośjest nam potrzebna informacja. Np nie pytasz: "Czy samochód działa" bo zazwyczaj działa. Chyba że ktoś ma skarbonkę. Zazwyczaj interesujesz się faktem że nie działa. I jeżeli:

działa = nie, czyli false

to nie działa = negacja(nie) = tak, czyli true

Edytowano przez Gieneq
Link do komentarza
Share on other sites

Dnia 10.06.2015 o 01:19, Elvis napisał:

Składnia instrukcji if w języku C wygląda następująco:

if ()

Blok instrukcji jest traktowany jako jedna instrukcja, czyli jeśli pojawią się nawiasy klamrowe { }, wykonuje się cały blok.

Średnik jest separatorem instrukcji, więc możemy przykładowo w jednej linii napisać dwie instrukcje:

printf("%d", a); a = 5

jeśli pominiemy jedną z nich i napiszemy

; a = 5

to kompilator potraktuje pierwszą, jako instrukcję pustą (często nazywaną NOP):

NOP(); a = 5

Teraz zobaczmy trudniejszy przykład:

if(receivedData == "blueled") printf("hello"); printf("world");

tutaj mamy instrukcję if, gdzie warunek to (receivedData == "blueled"). Jeśli warunek jest prawdziwy, wykonywana jest instrukcja warunkowa printf("helllo"). W tym miejscu kończy się całość związana z if, średnik oznacza koniec instrukcji. Więc printf("world") wykona się niezależnie od warunku.

Jeśli usuniemy printf, a zostawimy średnik, otrzymamy:

if(receivedData == "blueled") ; printf("world");

Kompilator zrobi dokładnie to samo, co wcześniej, czyli doda instrukcję pustą.

Kod który napisałeś, działa więc tak:

if(receivedData == "blueled") NOP();

Natomiast dodanie nawiasów klamrowych jedynie grupuje pozostały kod, co w tym wypadku nie wpływa na kod wynikowy programu.

Hejka, masz namyśli dodanie nawiasów klamrowych zezwoli nam na dodanie więcej instrukcji? Jakoś mam z tym problem. Ale generalnie nauczyłem się stawiać instrukcje w {}. Czy jeśli dodam więcej niż jedną instrukcje bez {} jak rozumie i ta pierwsza będzie:

 instrukcja; 

   a druga:

instrukcja2;

to ta druga będzie nie będzie należeć do tego

if()

 bo maksymalnie jak rozumie bez nawiasów klamrowych mogę użyć tylko jedną instrukcje po danym

if()

?

Link do komentarza
Share on other sites

Dnia 2.11.2016 o 16:27, Treker napisał:

KarolMateusz, dzięki za wiadomość, mam nadzieję, że uda się rozwiązać Twoje problemy.

1) Jeśli pierwsza wiadomość nie pojawia się w monitorze portu szeregowego, to spróbuj w sekcji setup dodać jedną linijkę za inicjalizacją UARTa:


void setup(){
 Serial.begin(9600); //Ustawienie prędkości transmisji
 while (!Serial) {}
 Serial.println("Witaj na Forbocie!"); //Jednorazowe wysłanie tekstu
}
 

Dodanie tego while sprawia, że program jest zatrzymywany w pustej pętli do momentu, gdy port szeregowy będzie gotowy. Daj znać, czy pomogło 🙂

2) Błędy wynikające z ustawienia złej prędkości prowadzą do wyświetlania (mówiąc potocznie) chińskich znaków w terminalu. Spróbuj w oknie terminala zmienić prędkość na sporo mniejszą lub sporo większą, powinny zacząć pojawiać się dziwne znaki.

3) W kwestii zmian nr portu COM, to już może być wiele przyczyn związanych z Twoim konkretnym komputerem. Samo Arduino na pewnie "nie skacze" po różnych portach.

4) Program działa dokładnie tak jak piszesz, czyli przechodzi przez całą instrukcję. Dioda powinna gasnąć po 1 sekundzie. Sprawdziłem przed chwilą program dla pewności i właśnie tak się dzieje.

Hejka, mam problem z zrozumieniem tego:

 while(!Serial) delay(10); // czekamy na otwarcie serial monitora
   Serial.println("Przekrec potencjometr i nacisnij przycisk.");

zmieniałem czas i po otwarciu monitora komunikat wyświetla się tak samo nie ważne ile ms

Czy możesz wytłumaczyć do czego możemy użyć opcji delay w tym przypadku?

Link do komentarza
Share on other sites

delay() jest sobie tam tylko "ot tak"  petla while wykona sie tylko wtedy kiedy Serial sie nie uruchomi, a ze za kazdym razem uruchamia sie poprawnie to nie ma znaczenia czy delay() ma sekunde czy godzine, bo i tak jest pomijany...stad wlasnie nie widzisz roznicy cokolwiek bys wpisal do delay()...(choc oczywiscie nie zaleca sie wpisywac tam duzych wartosci)

Link do komentarza
Share on other sites

(edytowany)

witam

korzystając z nabytej tu wiedzy bazuję na monitorze i zmianie statusu diody poprzez komendy - wszystko działa, chciałem wykorzystać także pętle while do migania diody - wszystko super działa, tylko jest jeden mały problem - nie da się już raz załączonej pętli przez monitor wyłączyć - czy ma ktoś jakiś pomysł co robię nie tak? z góry dzięki za wskazówki

[code]
String kolor = "";
void setup() {
Serial.begin(9600);
pinMode(13, OUTPUT);
}

void loop() {
if(Serial.available()>0){
  kolor = Serial.readStringUntil('\n');
  if(kolor == "start") {
    digitalWrite(13, HIGH);
    Serial.println("dioda załączona");
  }
  if(kolor == "stop") {
    digitalWrite(13, LOW);
        Serial.println("dioda wyłączona");
  }
 if(kolor == "mig") {
    while(kolor == "mig"){
    digitalWrite(13, HIGH);
    delay(1000);    
    digitalWrite(13, LOW);
    delay(1000);             
    }
    }
 
  if(kolor not_eq "start" and kolor not_eq "stop" and kolor not_eq "mig"){
    Serial.println("nie ma takiego polecienia");
  }
}
}
[/code]

 

Edytowano przez merinum
poprawa wklejenia kodu
Link do komentarza
Share on other sites

@merinum problem leży w tym miejscu:

 if(kolor == "mig") {
    while(kolor == "mig"){
    digitalWrite(13, HIGH);
    delay(1000);    
    digitalWrite(13, LOW);
    delay(1000);             
    }
    }

Pozostałe warunki działają ok i nie wpadniesz w pułapkę bo one nie mają pętli. Żeby jakoś sobie z tym poradzić wyrzuć pętlę while i tak ułóż kod że gdy kolor == 'miga' to jakaś zmienna zmienia naprzemiennie stan, albo toggle na pinach:

 if(kolor == "mig") {
    digitalWrite(13, !digitalRead(13));
    delay(1000);             
}

 

Link do komentarza
Share on other sites

(edytowany)

Zmienna kolor nie ulega zmianie w while, wiec ta petla jest petla nieskonczona...tak jak kolega @Gieneq odpowiedzial, wywal tego while bo go wogole tam nie potrzebujesz...no chyba ze chcesz migac ciagle i komenda stop wylaczyc diode...wtedy pasuje do while wrzucic kod sprawdzajacy cos jak...

    while(kolor == "mig"){
    digitalWrite(13, HIGH);
    delay(1000);    
    digitalWrite(13, LOW);
    delay(1000);  
   if(Serial.available()>0){
    kolor = Serial.readStringUntil('\n');
        }
     }
  

(Zainteresuj sie millis() i funkcjami...to znacznie przyspieszy, przestanie blokowac i upiekszy kod😉)

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

50 minut temu, farmaceuta napisał:

while(kolor == "mig"){ digitalWrite(13, HIGH); delay(1000); digitalWrite(13, LOW); delay(1000);

witam

Panowie dziękuję za pomoc - o to chodziło - teraz działa jak należy. co do millis i funkcji to jak najbardziej, ale ja dopiero raczkuję w tym temacie i staram się to ogarniać krok po kroku.

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.