Skocz do zawartości

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


Pomocna odpowiedź

sprawdziłem w cosmic rejestr pod adresem 0x500c PC_ODR o ile dobrze pamiętam. Odniosłem się do piątego bitu w sposób specyficzny dla tego kompilatora. Sprawdziłem adres i pokazuje to samo 0x500c. 

Link to post
Share on other sites
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 to post
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 to post
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 to post
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

#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 to post
Share on other sites

@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 to post
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 to post
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 to post
Share on other sites
(edytowany)
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 to post
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 to post
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 to post
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 to post
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 to post
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 to post
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 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!

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.