Skocz do zawartości
Komentator

Kurs Arduino - #7 - Wyświetlacz tekstowy, LCD 2x16

Pomocna odpowiedź

(edytowany)

@leh1992Wszystko fajnie. Pytanie: czy za pół roku jak spojrzysz w ten kod, będziesz pamiętał co znaczy stan numer dwa?

A tak przy okazji: jeśli zmienna czas jest typu int, co ma niby oznaczać

czas+0.01;

Jak myślisz - jeśli zmienna czas ma wartość x to jaką będzie miała po dodaniu 0.01?

 

Edytowano przez ethanak

Udostępnij ten post


Link to post
Share on other sites

@ethanak

3 godziny temu, ethanak napisał:

Pytanie: czy za pół roku jak spojrzysz w ten kod, będziesz pamiętał co znaczy stan numer dwa?

Myślę że wywnioskuję to z ogólnej budowy kodu. A jest możliwość nazywania przypadków w funkcji switch słownie?

 

3 godziny temu, ethanak napisał:

A tak przy okazji: jeśli zmienna czas jest typu int, co ma niby oznaczać


czas+0.01;

Zmienna czas jest typu float

float czas = 0.0;

 

Udostępnij ten post


Link to post
Share on other sites
(edytowany)
6 godzin temu, leh1992 napisał:

A jest możliwość nazywania przypadków w funkcji switch słownie?

Oczywiście. Możesz użyć np. dyrektywy #define, coś w rodzaju:
 

#define STAN_CZEKAM 1
#define STAN_COS_ROBIE 2
#define STAN_COS_INNEGO 3

i dalej w kodzie coś w stylu:
 

stan = STAN_CZEKAM;
...
switch(stan) {
   case STAN_CZEKAM:

W ten sposób zarówno Ty za pięć lat, jak i ktoś kto widzi kod po raz pierwszy będzie od razu wiedział o co chodzi w kodzie i że dana gałąż switch będzie wykonana w stanie oczekiwania.

Wygodniejszym sposobem jest użycie enum, czyli:
 

enum {
  STAN_CZEKAM = 1,
  STAN_COS_ROBIE,
  STAN_COS_INNEGO
};

W ten sposób w ogóle nie zajmujesz się drobiazgami typu "który stan odpowiada jakiej liczbie" bo w rzeczywistości nikogo to nie interesuje, a enum automatycznie przydzieli kolejne wartości kolejnym stanom. Oczywiście to najprostszy sposób zastosowania enum, można stworzyć np. nowy typ i zmienne tego typu, np.:

typedef enum {
  STAN_CZEKAM = 1,
  STAN_COS_ROBIE,
  STAN_COS_INNEGO
} stany; // tworzymy nowy typ "stany" do przechowywania stanów maszyny

stany stan; // i zmienną "stan" przed chwilą utworzonego typu

Temat dość obszerny - wpisz w google "typ wyliczeniowy" i poczytaj na ten temat trochę więcej jeśli chcesz.
 

6 godzin temu, leh1992 napisał:

Zmienna czas jest typu float

A, to zwracam honor, cóż - starość nie radość i oczy już nie te... chyba mi się dwie linijki ze sobą połączyły 😞

Edytowano przez ethanak
  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

@leh1992 fajnie, że wrzuciłeś swoje rozwiązanie i przyznam, że to wygląda ładnie. To o czym pisze @ethanak to dobry zwyczaj w programowaniu, który poprawia czytelność kodu. Ja ze swojej strony polecam autoformat z Arduino bo trochę się nawiasy rozjechały pod koniec (Ctrl-T), a tak to dobra robota 🙂 

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

@ethanak Dzięki za podpowiedź! Na pewno pogrzebie w tym temacie!

@Gieneq O autoformacie też pierwsze słyszę, rzeczywiście ułatwia życie 😉

 

Tutaj już kod z zastosowanymi waszymi poradami

#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

float czas = 0.0;
int stanLicznika = 0;

enum stanLicznika {oczekiwanie, pomiar, wynik};

unsigned long aktualnyCzas = 0;
unsigned long zmianaCzasu = 0;
unsigned long zmiana = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);

  lcd.begin(16, 2);
}

void loop() {
  aktualnyCzas = millis();

  switch (stanLicznika) {
    case oczekiwanie:
      lcd.setCursor(0, 0);
      lcd.print("Wcisnij");
      lcd.setCursor(0, 1);
      lcd.print("przycisk");
      if (digitalRead(8) == LOW) {
        lcd.clear();
        zmianaCzasu = aktualnyCzas;
        stanLicznika = pomiar;
      }
      break;
    case pomiar:
      lcd.setCursor(0, 0);
      lcd.print("Pomiar czasu");

      zmiana = aktualnyCzas - zmianaCzasu;
      if (zmiana >= 10) {
        zmianaCzasu = aktualnyCzas;
        czas = czas + 0.01;
      }
      lcd.setCursor(0, 1);
      lcd.print(czas);
      if (digitalRead(9) == LOW) {
        lcd.clear();
        stanLicznika = wynik;
      }
      break;

    case wynik:
      lcd.setCursor(0, 0);
      lcd.print("Koniec pomiaru");
      lcd.setCursor(0, 1);
      lcd.print(czas);
      if (digitalRead(10) == LOW) {
        lcd.clear();
        czas = 0;
        stanLicznika = oczekiwanie;
      } else if (digitalRead(8) == LOW) {
        lcd.clear();
        stanLicznika = pomiar;
      }
      break;
  }
}

 

Edytowano przez leh1992
Dodany kod
  • Lubię! 2

Udostępnij ten post


Link to post
Share on other sites

@leh1992 teraz wygląda bardzo ładnie, choć jeszcze jakbyś zastąpił wszystkie tzw. "magiczne liczby" w pinach jakimiś definami bo jednak nie jest to takie oczywiste:

else if (digitalRead(8) == LOW)

Widzę, że udało Ci się dać tylko jeden odczyt Seriala i dodać enuma jak sugerował @ethanak więc jest dużo lepiej 🙂 tak trzymaj!

  • Lubię! 1

Udostępnij ten post


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