Skocz do zawartości

Kurs Arduino - #9 - Czujnik odległości HC-SR04, funkcje


Komentator

Pomocna odpowiedź

@Treker w tej części kursu mamy ciekawy błąd :), Zadanie domowe 1, zadanie domowe 2, zadanie domowe 1, zadanie domowe 3, zadanie domowe 4.

 Zadanie domowe1 , znajduję się w środkowej części tuż nad " Ultradźwiękowy czujnik odległości HC-SR04" 

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

Witam
Wykonując zadanie 9.1 napotkałem na pewien problem, a mianowicie chciałem wykorzystać instrukcję switch/case, jednak po wpisaniu odpowiedniej litery do konsoli w Serial Monitorze program nie wykonywał żądanej akcji, jedynie możliwe było wykonanie obliczeń dla pierwszego przypadku case zapisanego w kodzie, a mianowicie (dla poniższego przykładu) dla case 't'. Zamiana miejscami warunków case spowodała iż inny znajdujący się na pierwszym miejscu w kodzie był w stanie się wykonać po wprowadzeniu do konsoli jego litery. Długo nad tym myślałem, ale nie byłem w stanie wykombinować dlaczego tak się dzieje, czy ktoś może mi z tym pomóc?
Zaznaczę jedynie iż zdaję sobie sprawę, że można to zastąpić instrukcją warunkową if, tak też później zrobiłem i to działa, jednak bardzo jestem ciekaw dlaczego nie funkcjonuje to przy użyciu funkcji switch/case.
Z góry dziękuję za odpowiedź.

int receivedData = 0;
void setup() {
  Serial.begin(9600);
  while(!Serial);
}

void loop() {
  Serial.println("Wybierz dla jakiej figury płaskiej chcesz obliczyć pole: ");
  Serial.println("p to prostokąt, o to okrąg, t to trójkąt");
  while (Serial.available() == 0) {}
      receivedData = Serial.read();
      switch (receivedData) {
      
        case 't':
          
          Serial.println("Podaj długość podstawy trójkąta");

          while (Serial.available() == 0) {}
          int a1 = 0;
          int h = 0;

          a1 = Serial.readStringUntil('\n').toInt();
          Serial.println("Podaj wysokość trójkąta");

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

          h = Serial.readStringUntil('\n').toInt();
          int wynik2 = triangleArea(a1, h);
          Serial.print("Pole trójkąta wynosi: ");
          Serial.println(wynik2);
          delay(1500);
          break;

        case 'p':
         
          Serial.println("Podaj długość boku a:");
        
          while (Serial.available() == 0) {}
          int a = 0;
          int b = 0;
          a = Serial.readStringUntil('\n').toInt();
          Serial.println("Podaj długość boku b:");

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

          b = Serial.readStringUntil('\n').toInt();
          int wynik = rectangleArea (a, b);
          Serial.print("Pole prostokąta wynosi: ");
          Serial.println(wynik);
          delay(1500);

          break;
        case 'o':
          
          Serial.println("Podaj promień okręgu:");
          
          while (Serial.available() == 0) {}
          int r = 0;

          r = Serial.readStringUntil('\n').toInt();
          int wynik1 = circleArea(r);
          Serial.print("Pole prostokąta wynosi: ");
          Serial.println(wynik1);
          delay(1500);

          break;
        
        default:
          Serial.println("Źle zdefiniowana figura geometryczna");
          delay(1500);
          break;
      }
  
}

int rectangleArea (int a, int b) {
  int wynik = 0;
  wynik = a * b;

  return wynik;
}

int circleArea (int a1) {
  int wynik1 = 0;
  wynik1 = PI * a1 * a1;

  return wynik1;
}

int triangleArea (int a2, int h) {
  int wynik2 = 0;
  wynik2 = 0.5 * a2 * h;

  return wynik2;
}

 

Link do komentarza
Share on other sites

@Bartek10 Instrukcja break wymusza wyjście z treści instrukcji po wykonaniu jednej instrukcji. Jeśli i wartość jest równa -1, tylko n jest zwiększana. Poniższa break instrukcja n++; powoduje, że kontrolka wykonywania jest pomijana z treści instrukcji, pomijając pozostałe instrukcje.5 lip 2024 - na szybko znalazłem w necie

 

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

Rozpatrując poprawiony kod przez użytkownika "orb777" i wprowadzając zmiany w swoim kodzie doszedłem do wniosku, że czynnikiem, który naprawił działanie funkcji switch/case było dodanie nawiasów klamrowych po rozpoczęciu każdej instrukcji case i przed definicją break (sprawdziłem to tylko na symulatorze firmy Autodesk o nazwie TinkerCad, gdyż na chwilę obecną nie mam dostępu do płytki Arduino i to działa). Jednak odnosząc się do I kursu arduino w rozdziale #6, gdzie opisywana jest instrukcja switch, nie wspomniano o konieczności korzystania z tychże nawiasów, a mimo to funkcja działała (obrazek z kodem załączyłem poniżej. Stąd moje pytanie dlaczego to zadziałało, przez to że zawarte wtedy instrukcje wyświetlania były prostsze od tego co umieszczałem w zadaniu 9.1?
I jeszcze jedno pytanie. W poprawionym kodzie od użytkownika orb777 znajduje się zapis "switch ((char)Serial.read())" czy on się różni od "switch (Serial.read())" czyli bez dopisku char? Za pomoc z góry dziękuję.image.thumb.png.7b18d6977eee09301036c9e77d82ac95.png

Link do komentarza
Share on other sites

2 godziny temu, Bartek10 napisał:

Stąd moje pytanie dlaczego to zadziałało, przez to że zawarte wtedy instrukcje wyświetlania były prostsze od tego co umieszczałem w zadaniu 9.1?

Większa ilość instrukcji wymaga nawiasów {}

 

2 godziny temu, Bartek10 napisał:

zapis "switch ((char)Serial.read())" czy on się różni od "switch (Serial.read())" czyli bez dopisku char?

Serial.read() - Ta funkcja zwraca wartość typu int.
(char) - Operator rzutowania zmienia typ wartości na char.

Link do komentarza
Share on other sites

(edytowany)

@Bartek10 , nie dostałeś żadnego ostrzeżenia w kompilatorze? Thinkercad wyświetla info, że wprowadzasz dodatkowe zmienne w case, więc wymaga określenia jawnego zakresu (lokalnego) dla nich, stąd klamry. Chociaż "wokwi" też nie pokazuje ostrzeżenia i gubi się kiedy zabierzesz "{}".

Edytowano przez orb777
Link do komentarza
Share on other sites

@orb777 Właśnie gdybym otrzymał komunikat od kompilatora to nie byłbym w stanie wgrać tego programu na płytkę, a tutaj kompilator, że tak powiem puścił to i w trakcie egzekwowania programu już na płytce działy się takie rzeczy, o których pisałem w pierwszej wiadomości objaśniającej problem. Dziękuje za pomoc, kluczowe były nawiasy klamrowe.

Link do komentarza
Share on other sites

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

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.