Skocz do zawartości

Problem z programem - menu na LCD


Pomocna odpowiedź

Ja bym jeszcze dodał:

plik = SD.open("temp.txt", FILE_WRITE);
if (!plik) {
  Serial.println("Nie mogę otworzyć pliku");
  return;
}

Eliminuje to możliwość udawania Chucka Norrisa 🙂

 

  • Lubię! 1
(edytowany)

Będę się starał poprawić z estetyką pisania kodów, myślę że z czasem nabiorę wprawy.

Wracając do kodu, w monitor portu szeregowego elegancko odlicza zadane 8 sekund, niestety gorzej jest z zapisem danych na kartę, tam wrzucana jest ogromna ilość danych, tak jakby co kilka milisekund był nowy zapis danych, przez tak krótki czas temperatura na czujniku się nie zmieni. 

Dodam jeszcze, że czujnik temperatury zbiera dane podobnie jak w funkcji zapisu danych, tylko co 7 sekund.

Edytowano przez zirael3
15 minut temu, zirael3 napisał:

Będę się starał poprawić z estetyką pisania kodów, myślę że z czasem nabiorę wprawy.

Nie "będę się starał" a "następnym razem wkleję prawidłowo sformatowany kod". Nie masz myśleć i nabierać wprawy, ale użyć narzędzi które ludzie do tego wymyślili. Nawet w tym czymś co w Arduino IDE robi za edytor masz opcję sformatowania kodu... będziesz nabierał wprawy w klikaniu w menu?

17 minut temu, zirael3 napisał:

Wracając do kodu

Pokaż tu cały kod (oczywiście po poprawkach które sugerował @Belferek i moich), pokaż wyniki na monitorze, bo nikomu się po prostu nie chce składać tego czegoś z kawałków zamieszczonych na trzech różnych podstronach. Jeśli napiszę że "błąd jest w linijce nr. 7" to która to będzie linijka u Ciebie w programie?

21 minut temu, zirael3 napisał:

gorzej jest z zapisem danych na kartę, tam wrzucana jest ogromna ilość danych, tak jakby co kilka milisekund był nowy zapis danych, przez tak krótki czas temperatura na czujniku się nie zmieni. 

To po co robisz 100 pomiarów pod rząd i wywalasz te wyniki na kartę?

Po poprawce @Belferek tak jak wspominałem ilość pomiarów jest ogromna. Wrzuciłem zatem opóźnienie do pętli for, niestety nie uwzględnia ona wzrostu i.

void karta()
{
  aktualnyCzas1 = millis();
  Serial.print("Aktualny:");    Serial.println(aktualnyCzas1);
  Serial.print("Zapamietany:"); Serial.println(zapamietanyCzas1);
  Serial.print("Roznica:");     Serial.println(aktualnyCzas1 - zapamietanyCzas1);
  plik = SD.open("temp.txt", FILE_WRITE);
  for (int i = 0; i < 100; i++)
  {
    if (aktualnyCzas1 - zapamietanyCzas1 >= 8000)
    { zapamietanyCzas1 = aktualnyCzas1;
      plik.println("Odczyt temperatury nr: ");
      plik.println(i);
      plik.println("Temperatura w pokoju");
      plik.println(sensor1.getTempCByIndex(0));
      plik.println("Temperatura na zewnątrz");
      plik.println(sensor2.getTempCByIndex(0));
      plik.println("Temperatura na grzejniku");
      plik.println(sensor3.getTempCByIndex(0));
    }
  }
  plik.close();
}

 

Ten kod natomiast uwzględnia ilość zapisanych danych na karcie

Powiedz w ogóle, co Ty chcesz zrobić i po co ta cała pętla. Tak swoimi słowami, bez żadnych kodów.

Bo na razie jak będziesz losowo wstawiał różne instrukcje w różne miejsca to Ci prędzej Hamlet wyjdzie niż program.
 

Chcę żeby na karcie SD zapisywały mi się pomiary z 3 czujników temperatury co 10 sekund i żeby każdy z tych pomiarów był kolejno numerowany. Po dokonaniu 99 pomiarów zapis na karcie ma się skończyć.

Zacznijmy od jednego: Arduino działa "w kółko" i nie da się tak po prostu zrobić mu "stop" - coś zawsze musi robić. Można je np. wprowadzić w martwą pętlę albo uśpić.

Czyli ma być to coś takiego:
 

Czy minęło juz 8 sekund od ostatniego zapisu?
Jeśli tak:
    otwórz plik na karcie do zapisu
    zapisz numerek
    zapisz dane z pomiarów
    zamknij plik
    zwiększ numerek o 1
    czy osiągnąłeś 100 zapisów?
    Jeśli tak:
        wyłącz Arduino
    

Albo jeśli Arduino coś jeszcze oprócz tego robi:

Czy osiągnięto już 100 zapisów?
Jeśli nie:
    czy od ostatniego zapisu minęło 8 sekund?
    Jeśli tak:
        otwórz plik do zapisu
        zapisz numerek
        zapisz dane
        zamknij plik
        zwiększ numerek o 1

Widzisz tu jakąś pętlę for?

void karta()
{
  int i = 0;
  aktualnyCzas1 = millis();
  if (i == 100)
  {
    plik.close();
  }
  else
  {
    aktualnyCzas1 - zapamietanyCzas1 >= 8000;
    if    (zapamietanyCzas1 = aktualnyCzas1)
    {
      plik = SD.open("temp.txt", FILE_WRITE);
      plik.println("Odczyt temperatury nr: ");
      plik.println(i);
      plik.println("Temperatura w pokoju");
      plik.println(sensor1.getTempCByIndex(0));
      plik.println("Temperatura na zewnątrz");
      plik.println(sensor2.getTempCByIndex(0));
      plik.println("Temperatura na grzejniku");
      plik.println(sensor3.getTempCByIndex(0));
      plik.close();
      i = i + 1;
    }
  }
}

1. Czy i = 100? Jeśli tak zamknij plik, Jeśli nie wykonaj warunek

2. Czy minęło 8 sekund? Jeśli tak wykonaj warunek

3.Otwórz plik

4.Zapisz dane

5.Zamknij plik

6.Zwiększ i

No prawie dobrze... tyle że teraz zamykasz zamknięty plik, a zmienna i po wejściu do funkcji będzie miała zawsze nową ciekawą wartość, najczęściej zupełnie inną niż przed ostatnim wyjściem. Czy wiesz dlaczego? Gdzie jest zadeklarowana zmienna "zapamietanyCzas1" i dlaczego właśnie tam?

Oczywiście musiałeś wprowadzić swoje modyfikacje do paru linijek algorytmu... czy ja gdzieś pisałem o zamykaniu pliku jeśli osiągnięto 100? Po co go zamykać jak się go nie otwierało? DLaczego w ogóle zmienna plik jest zadeklarowana poza jedyną funkcją która z niej korzysta i która nie musi przechowywać jej wartości między wywołaniami?

if (i == 100)
  {
    plik.close();
  }

Co mam w takim wypadku wpisać w pierwszym if, mogę go zostawić po prostu z klamrami { }?

38 minut temu, ethanak napisał:

 zmienna i po wejściu do funkcji będzie miała zawsze nową ciekawą wartość, najczęściej zupełnie inną niż przed ostatnim wyjściem. Czy wiesz dlaczego?

Zmienna i będzie miała inną wartość ponieważ w ostatnim warunku zawsze zwiększam ją o 1.

38 minut temu, ethanak napisał:

 Gdzie jest zadeklarowana zmienna "zapamietanyCzas1" i dlaczego właśnie tam?

Zamienna "zapamietanyCzas1" jest tam ponieważ to ona sprawdza czy minął określony przeze mnie czas. Jest wrzucona w warunek if żeby sprawdzić czy się zgadza, jeśli tak to warunek musi zostać wykonany

void karta()
{
  int i = 0;
  aktualnyCzas1 = millis();
  if (i == 100)
  {
  }
  else
  {
    aktualnyCzas1 - zapamietanyCzas1 >= 8000;
    if    (zapamietanyCzas1 = aktualnyCzas1)
    {
      plik = SD.open("temp.txt", FILE_WRITE);
      plik.println("Odczyt temperatury nr: ");
      plik.println(i);
      plik.println("Temperatura w pokoju");
      plik.println(sensor1.getTempCByIndex(0));
      plik.println("Temperatura na zewnątrz");
      plik.println(sensor2.getTempCByIndex(0));
      plik.println("Temperatura na grzejniku");
      plik.println(sensor3.getTempCByIndex(0));
      plik.close();
      i = i + 1;
    }
  }
}

Czy powinienem dać inny warunek niż ten (zapamietanyCzas1 = aktualnyCzas1) ? Jeśli tak to jaki i czy ta linijka powinna wygądać tak:

else
  {
    aktualnyCzas1 - zapamietanyCzas1 >= 8000;
  zapamietanyCzas1 = aktualnyCzas1;
    if    ( jaki warunek zatem?)
    {
    }

Przepraszam za chaotyczną odpowiedź.

Przed chwilą, zirael3 napisał:

Co mam w takim wypadku wpisać w pierwszym if, mogę go zostawić po prostu z klamrami { }?

A dlaczego nie można napisać np.

if (i != 100)

albo lepiej

if (i < 100)

 

2 minuty temu, zirael3 napisał:

Zmienna i będzie miała inną wartość ponieważ w ostatnim warunku zawsze zwiększam ją o 1.

Nieprawda. Zmienna po wyjściu z funkcji zostaje zniszczona i po wejściu przyjmuje nową, zupełnie przypadkową wartość.

2 minuty temu, zirael3 napisał:
44 minuty temu, ethanak napisał:

 Gdzie jest zadeklarowana zmienna "zapamietanyCzas1" i dlaczego właśnie tam?

Zamienna "zapamietanyCzas1" jest tam ponieważ to ona sprawdza czy minął określony przeze mnie czas. Jest wrzucona w warunek if żeby sprawdzić czy się zgadza, jeśli tak to warunek musi zostać wykonany

Czy rozumiesz różnicę między słowem "zadeklarowana" a "użyta"?

Czy jeśli sąsiad zobaczy Ciebie na ulicy z całą torbą świeżo kupionego papieru toaletowego i zapyta gdzie ko kupiłeś, opowiesz mu ze szczegółami jak go używasz czy "panie, w Biedronce towar rzucili"?

 

Czyli zmienną i muszę zadeklarować globalnie jeszcze przed funkcją setup(), tak samo jak zmienną zapamietanyCzas1.

 

void karta()
{
 
  aktualnyCzas1 = millis();
  if (i != 100)
  {
    aktualnyCzas1 - zapamietanyCzas1 >= 8000;
    if    (zapamietanyCzas1 = aktualnyCzas1)
    {
      plik = SD.open("temp.txt", FILE_WRITE);
      plik.println("Odczyt temperatury nr: ");
      plik.println(i);
      plik.println("Temperatura w pokoju");
      plik.println(sensor1.getTempCByIndex(0));
      plik.println("Temperatura na zewnątrz");
      plik.println(sensor2.getTempCByIndex(0));
      plik.println("Temperatura na grzejniku");
      plik.println(sensor3.getTempCByIndex(0));
      plik.close();
      
    }
    i = i + 1;
  }
}

Niestety czas nadal nie jest uwzględniany

(edytowany)

Porównaj to co napisałeś z tym co ja napisałem - teraz masz ładne wcięcia w programie i łatwo możesz zobaczyć gdzie jest różnica (też miałem wcięcia, prawda?).

Poza tym teraz to masz babola w ifie takiego jak stąd do Pernambuko 🙂

Porównaj to co masz:

    aktualnyCzas1 - zapamietanyCzas1 >= 8000;
    if    (zapamietanyCzas1 = aktualnyCzas1)
    {

z tym co powinno być:

    if (aktualnyCzas1 - zapamietanyCzas1 >= 8000)
    {
        zapamietanyCzas1 = aktualnyCzas1;

Jako ćwiczenie przeanalizuj, co robi linijka:

    if    (zapamietanyCzas1 = aktualnyCzas1)

 

Edytowano przez ethanak
Czy osiągnięto już 100 zapisów?
Jeśli nie:
    czy od ostatniego zapisu minęło 8 sekund?
    Jeśli tak:
        otwórz plik do zapisu
        zapisz numerek
        zapisz dane
        zamknij plik
        zwiększ numerek o 1

Jeśli się nie mylę (a pewnie się mylę) to różnica jest tylko ze zwiększeniem zmiennej i

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