• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
rejestrator zdażeń
#1
Mam mały problem którego nie wiem jak ugryźć. Chcę zrobić rejestrator zdarzeń z opcją wyświetlania na lcd.
Kod:
#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include "RTClib.h"
File myFile;

DateTime now;

RTC_DS3231 rtc;

String Plik;

void setup ()
{
    Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.print("Initializing SD card...");

  SD.remove("test");
 
  if (!SD.begin(SPI_QUARTER_SPEED, 4)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");

 
  Serial.begin(9600);
  if (! rtc.begin())
  {
    Serial.println("Couldn't find RTC Module");
    while (1);
  }

  if (rtc.lostPower())
  {
    Serial.println("RTC lost power, lets set the time!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}

void loop ()
{
  now = rtc.now();
// czasIdata();
  Serial.println();
  zapisSD();
  Serial.println();
  odczytSD();
  delay(30000);
  Plik;
}
/*
void czasIdata()
{
  Serial.print(now.hour());
  Serial.print(':');
  if (now.minute() < 10) {
    Serial.print("0");
    Serial.print(now.minute());
  } else {
    Serial.print(now.minute());
  }
  Serial.print(" ");

  if (now.day() < 10) {
    Serial.print("0");
    Serial.print(now.day());
  } else {
    Serial.print(now.day());
  }
  Serial.print('/');
  if (now.month() < 10) {
    Serial.print("0");
    Serial.print(now.month());
  } else {
    Serial.print(now.month());
  }
  Serial.print('/');
  Serial.print(now.year());
}*/

void zapisSD(){
  Serial.println("zapis");
  myFile = SD.open("plik.txt", FILE_WRITE);
  if (myFile) {
    myFile.print("\n");
    myFile.print(now.hour());
  myFile.print(':');
  if (now.minute() < 10) {
    myFile.print("0");
    myFile.print(now.minute());
  } else {
    myFile.print(now.minute());
  }
  myFile.print("\n");

  if (now.day() < 10) {
    myFile.print("0");
    myFile.print(now.day());
  } else {
    myFile.print(now.day());
  }
  myFile.print('/');
  if (now.month() < 10) {
    myFile.print("0");
    myFile.print(now.month());
  } else {
    myFile.print(now.month());
  }
  myFile.print('/');
  myFile.print(now.year());
  myFile.print("\n"); 
  myFile.close();
}
else {
    Serial.println("error opening test.txt");
  }
}

void odczytSD(){
   Serial.println("odczyt");
   myFile = SD.open("plik.txt");
  if (myFile) {
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    myFile.close();
  } else {
    Serial.println("error opening test.txt");
  }
}

Założenia mam takie, że co 24 godziny będzie się zmieniać nazwa pliku na aktualną datę. Nie mam pojęcia jak to zrobić. Najłatwiej było by zapisać datę do zmiennej string "data", następnie zmienną data połączyć z ".txt" i otrzymać: "data.txt". (tak to widzę: myFile = SD.open(data, FILE_WRITE); ). I tu mam problem. Jak zapisać datę pod stringiem?
 
Odpowiedź
#2
Pokażę Ci wycinek mojego programu do dobowej rejestracji danych, może Ci coś podpowie ten przykład.
Kod:
void ZapisDanychNaKarte()
{
  //dt = clock.getDateTime(); //zegar jest pytany co 2 minuty w Rej_Danych więc tu nie potrzeba już go "molestować" o godzinę co petlę

  if (dt.hour == 23 && dt.minute > 50 && DataZap == 0 )
  {
    RokZap = dt.year;
    MiesZap = dt.month;
    DzienZap = dt.day;
    DataZap = 1;
  }

  if (zapiszNaKarte == 1) // "zapiszNaKarte" ustawiane w "rejestracji danych" w momencie zakończenia pomiarów dobowych, może to być do 2 minut po północy (dt.hour jest wtedy = 0)
  {
    GD.__end(); // zatrzymanie biblioteki wyświetlacza

    // zapis dobowych danych Pa na kartę ----------------------------------------

    pliki = SD.open("pa.txt", FILE_WRITE);
    if (pliki) // jeżeli jest otwarty zapisujemy / nadpisujemy poniższe dane
    {
      pliki.print(RokZap);
      pliki.print(",");
      pliki.print(MiesZap);
      pliki.print(",");
      pliki.print(DzienZap);
      pliki.print(",Pa,");
      for (i = 0; i < 24; i++)
      {
        pliki.print(dobowaRejPa [i]);
        pliki.print(",");
      }
      pliki.println("");
    }
    pliki.close(); // zamykamy plik
Plik nie jest kompletny bo to jest jego część, tu zapisuję średnie cogodzinne ciśnienie atmosferyczne raz na dobę,
Zauważ, że muszę zapamiętać datę poprzedniego dnia a sam zapis odbywa się już w dniu następnym. Występują tam też zmienne ustawiane w innych częściach programu.
 
Odpowiedź
#3
Dzięki. Natchnęło mnie i ogarnąłem to zupełnie inaczej. Teraz chciałbym wyświetlić to na lcd:

Kod:
14:17:02.268 -> liniaczas1 14:15 10/07/2020
14:17:02.268 -> liniaZdarzenie2 kocek focek
14:17:02.301 ->
14:17:02.301 -> liniaczas3 14:15 10/07/2020
14:17:02.336 -> liniaZdarzenie4 kocek focek
14:17:02.370 ->
14:17:02.370 -> liniaczas5 14:15 10/07/2020
14:17:02.405 -> liniaZdarzenie6 kocek focek
14:17:02.439 ->
14:17:02.439 -> liniaczas7 14:16 10/07/2020
14:17:02.473 -> liniaZdarzenie8 kocek focek
14:17:02.508 ->
14:17:02.508 -> liniaczas9 14:16 10/07/2020
14:17:02.542 -> liniaZdarzenie10 kocek focek
14:17:02.577 ->
14:17:02.577 -> liniaczas11 14:16 10/07/2020
14:17:02.612 -> liniaZdarzenie12 kocek focek


Założenie mam takie aby po naciśnięciu klawiasza na klawiaturze wyświetlały się jednocześnie oba wiersze na lcd. tzn tylko napisy "14:16 10/07/2020" i "kocek focek", aby można było w jakiś sposób odróżnić linie dodałem "liniaczas" i "liniazdarzenie" z numerami które będą się zmieniały gdy będzie trzeba coś zarejstrować.  Z wyciągnięciem czasu i zdarzenia do jakiejś zmiennej nie mam problemu, za to mam problem jak zrobić, żeby po naciśnięciu jakiegoś klawisza ( np "A")  wyswietlane były 2 kolejne wiersze w przód, a jeżeli nacisnę jakiś inny klawisz dwa wiersze do tyłu. Macie jakieś pomysły?
 
Odpowiedź
#4
Zrób sobie "podprogramy" np. void ekran_dlowny (), np void 2_wiersze_w_przod () i np void 2_wiersze_w_tyl () i w loop w zależności od "naduszenia" przycisku, wywołuj odpowiedni "podprogram". Tu pomocne może być hasło flaga. Flagę ustawiasz przyciskami a ona przełącza podprogramy wyświetlacza, tu wystarczy użyć if.
 
Odpowiedź
#5
Właśnie tak myślałem, żeby to rozdzielić. Co do odczytania mam taki plan, że każdy wiersz zakończę "\n" następnie plik txt będę czytał wiersz po wierszu,  następnie każdy odczytany wiersz  będę zapisywał  do zmiennej String. Zmienną tą po przeczytaniu wiersza będę przeszukiwał w celu znalezienia "liniaczas(numer)" - gdzie wartość zmiennej "numer "będzie się zmieniać z każdym przyciśnięciem przycisku. Jeżeli znajdzie tą linijkę to wstrzymuje czytanie. Zapisuję ją do String. Następnie zmienną String przycinam, zostawiam co mnie interesuje i  przerzucam na lcd.print(String). I teraz pytanie, czy jest ktoś kto mógłby by pomóc z ogarnięciem kodu? chodzi mi tylko o czytanie wiersz po wierszu, resztę bez problemu ogarnę.

//edit. 

Coś takiego wymodziłem: 
Kod:
File myFile = SD.open(nazwaPliku);
  if (myFile)
  {
    while (myFile.available())
    {
      char c = myFile.read();
      if (isPrintable(c))
      {
        odczytanaLinia.concat(c);
      }
      else if (c == '\n')
      {
        Serial.print("odczytanaLinia: ");
        Serial.println(odczytanaLiniaCzas);
        odczytanaLiniaCzas = "";
      }
    }
  }
  myFile.close();
}

wydruk z portu:
Kod:
118:25:08.209 -> liniaczas1 18:10 10/07/2020
18:25:08.256 -> liniaZdarzenie2 kocek focek
18:25:08.256 -> liniaczas1 18:11 10/07/2020
18:25:08.291 -> liniaZdarzenie2 kocek focek
18:25:08.341 -> liniaczas1 18:11 10/07/2020
18:25:08.341 -> liniaZdarzenie2 kocek focek
18:25:08.388 -> liniaczas1 18:15 10/07/2020
18:25:08.434 -> liniaZdarzenie2 kocek focek
18:25:08.434 -> liniaczas1 18:15 10/07/2020
18:25:08.481 -> liniaZdarzenie2 kocek focek
18:25:08.528 -> liniaczas1 18:21 10/07/2020
18:25:08.528 -> liniaZdarzenie2 kocek focek
18:25:08.528 -> liniaczas1 18:21 10/07/2020
18:25:08.575 -> liniaZdarzenie2 kocek focek
18:25:08.622 -> liniaczas3 18:21 10/07/2020
18:25:08.669 -> liniaZdarzenie4 kocek focek
18:25:08.669 -> liniaczas5 18:21 10/07/2020
18:25:08.715 -> liniaZdarzenie6 kocek focek
18:25:08.762 -> liniaczas7 18:22 10/07/2020
18:25:08.762 -> liniaZdarzenie8 kocek focek
18:25:08.809 -> liniaczas9 18:22 10/07/2020
18:25:08.856 -> liniaZdarzenie10 kocek focek
18:25:08.903 -> liniaczas11 18:23 10/07/2020
18:25:08.903 -> liniaZdarzenie12 kocek focek
18:25:08.903 -> liniaczas13 18:23 10/07/2020
18:25:08.950 -> liniaZdarzenie14 kocek focek
18:25:08.996 -> liniaczas15 18:24 10/07/2020
18:25:08.996 -> liniaZdarzenie16 kocek focek
18:25:09.043 -> liniaczas17 18:24 10/07/2020
18:25:09.090 -> liniaZdarzenie18 kocek focek
18:25:09.153 -> liniaczas19 18:24 10/07/2020
18:25:09.153 -> liniaZdarzenie20 kocek focek

Teraz, jak to ogarnąć, żeby  linia liniaczas1 była zapisywana do "odczytanaLiniaCzas"
liniaZdarzenie2 do "odczytanaLiniaZdarzenie2" ?


Ogarnąłem w bardzo prosty sposób:
Kod:
void lcdCzas(){
myFile = SD.open(nazwaPliku, FILE_READ);
while (myFile.available() != 0) {
odczytanyCzas = myFile.readStringUntil('\n');
if (odczytanyCzas.indexOf(F("liniaczas3")) >= 0){
Serial.println("odczytanyCzas: ");
Serial.println(odczytanyCzas);
break;}
   }
   myFile.close();
  }
void lcdZdarzenie(){
myFile = SD.open(nazwaPliku, FILE_READ);
while (myFile.available() != 0) {
odczytaneZdarzenie = myFile.readStringUntil('\n');
if (odczytaneZdarzenie.indexOf(F("liniaZdarzenie4")) >= 0){
Serial.println("odczytaneZdarzenie: ");
Serial.println(odczytaneZdarzenie);
break;}
   }
   myFile.close();
  }
 i wydruk serial portu :
Kod:
21:16:53.380 -> liniaczas3 19:34 10/07/2020
21:16:53.380 -> odczytaneZdarzenie
21:16:53.413 -> liniaZdarzenie4 kocek focek
21:17:03.376 -> Aktualny czas: 21:16_10_07_2020
21:17:03.423 -> 10_07_2020.txt
21:17:03.423 -> odczytanyCzas
21:17:03.458 -> liniaczas3 19:34 10/07/2020
21:17:03.458 -> odczytaneZdarzenie
21:17:03.507 -> liniaZdarzenie4 kocek focek
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości