[163] Karta SD cz. 3

Czas na operacje wewnątrz plików. W końcu dotąd uprawialiśmy sztukę dla sztuki, pliki to nośniki danych i teraz te dane stworzymy, a potem je odczytamy.


#include <SD.h>  // Biblioteka obsługi karty SD
File file;
const byte cardCS = 4;  // Deklaracja adresu linii CS11

void setup() {
  Serial.begin(115200);                                      // Inicjuj port monitora.
  Serial.println(F("\
Czekam na sygnał z karty SD..."));     // Wyślij komunikat.
  if (!SD.begin(cardCS)) {                                   // Inicjuj kartę określając port CS (jeśli brak - pin 10)
    Serial.println(F("Niepowodzenie, nie wykryto karty."));  // Karta nie została wykryta.
    while (1)                                                // Koniec programu.
      ;
  }
  Serial.println(F("Powodzenie, wykryto kartę."));

  Serial.println(F("\
Usunę plik DANE.TXT..."));
  SD.remove("DANE.TXT");  // Usuwam plik DANE.TXT

  Serial.println(F("\
Stworzę plik DANE.TXT..."));  // Zapis w pliku.
  file = SD.open("DANE.TXT", FILE_WRITE);           // Otwieram plik DANE.TXT, który będzie zapisywany.
  if (file) {                                       // Jeśli udało się otworzyć plik...
    Serial.println(F("Powodzenie, stworzyłem plik DANE.TXT"));
    Serial.println(F("\
W pliku DANE.TXT zapiszę zdanie: Ala ma kota..."));
    file.println(F("Ala ma kota."));  // Zapisuję w nim zdanie "Ala ma kota."
    file.close();                     // Zapisuję wcześniej otwarty plik na karcie.
    Serial.println(F("Plik został zapisany."));
  } else {
    Serial.println(F("Niepowodzenie, nie dałem rady stworzyć pliku DANE.TXT"));
  }

  Serial.println(F("\
Odczytam plik DANE.TXT..."));  // Odczyt zawartości pliku.
  file = SD.open("DANE.TXT");                        // Otwieram plik DANE.TXT, który będzie odczytywany.
  if (file) {                                        // Jeśli udało się otworzyć plik...
    Serial.print(F("Zawartość pliku DANE.TXT: "));
    while (file.available()) {    // Powtarzam do ostatniego bajtu w pliku...
      Serial.write(file.read());  // Czytam bajt i wysyłam go na monitor.
    }
    file.close();  // Zamykam otwarty plik.
  } else {
    Serial.println(F("Niepowodzenie, nie dałem rady otworzyć pliku DANE.TXT"));
  }
}
void loop() {}

Początek programu jest identyczny. Następnie stworzymy – albo też otworzymy, jeśli istniał wcześniej – plik DANE.TXT To będzie istotne, ale do tego wrócę zaraz. Ten proces już przeprowadzaliśmy.

Serial.println(F("\
Stworzę plik DANE.TXT..."));  // Zapis w pliku.
file = SD.open("DANE.TXT", FILE_WRITE);           // Otwieram plik DANE.TXT, który będzie zapisywany.
if (file) {                                       // Jeśli udało się otworzyć plik...
  Serial.println(F("Powodzenie, stworzyłem plik DANE.TXT"));
  Serial.println(F("\
W pliku DANE.TXT zapiszę zdanie: Ala ma kota..."));
  file.println(F("Ala ma kota."));  // Zapisuję w nim zdanie "Ala ma kota."
  file.close();                     // Zapisuję wcześniej otwarty plik na karcie.
  Serial.println(F("Plik został zapisany."));
} else {
  Serial.println(F("Niepowodzenie, nie dałem rady stworzyć pliku DANE.TXT"));
}

Po otwarciu pliku zapiszemy w nim zdanie „Ala ma kota.”, po czym plik zamkniemy – pamiętajmy, bez tej operacji dane poginą. Ufamy jednak, że się zapisały, ale co sprawdzone to pewne.

Serial.println(F("\
Odczytam plik DANE.TXT..."));  // Odczyt zawartości pliku.
file = SD.open("DANE.TXT");                        // Otwieram plik DANE.TXT, który będzie odczytywany.
if (file) {                                        // Jeśli udało się otworzyć plik...
  Serial.print(F("Zawartość pliku DANE.TXT: "));
  while (file.available()) {    // Powtarzam do ostatniego bajtu w pliku...
    Serial.write(file.read());  // Czytam bajt i wysyłam go na monitor.
  }
  file.close();  // Zamykam otwarty plik.
} else {
  Serial.println(F("Niepowodzenie, nie dałem rady otworzyć pliku DANE.TXT"));
}

Zatem teraz znowu otworzymy nasz plik i za pomocą instrukcji file.read odczytamy jego zawartość. Tutaj słówko wyjaśnienia: instrukcja czyta tylko jeden bajt, z adresu tak zwanego kursora. Więc aby przeczytać całość, musimy powtarzać odczyt tyle razy, ile bajtów siedzi w pliku. Po to w pętli występuje druga instrukcja: zwraca liczbę bajtów od pozycji bieżącej do końca zawartości pliku. Adres bieżący zmienia się automatycznie przy każdym odczycie, więc nie trzeba o nim myśleć. Gdy liczba bajtów osiągnie wartość zero, wychodzimy z procedury przekazu zawartości pliku na monitor, zamykamy plik i kończymy zabawę. Tak wygląda zrzut z monitora.

Czekam na sygnał z karty SD...
Powodzenie, wykryto kartę.

Stworzę plik DANE.TXT...
Powodzenie, stworzyłem plik DANE.TXT

W pliku DANE.TXT zapiszę zdanie: Ala ma kota...
Plik został zapisany.

Odczytam plik DANE.TXT...
Zawartość pliku DANE.TXT: Ala ma kota.

Problem pojawi się po resecie. Za każdym razem przybędzie kolejna Ala i kolejny kot. Dlaczego? Bo na końcu pozostawiliśmy plik na karcie, nie usuwając go. Wobec tego instrukcja powołująca do życia ten plik widząc go zignorowała jego tworzenie, a blok zapisujący zdanie „Ala ma kota.” dopisywał je do tego, co znalazł. Po każdym resecie pojawiał się nowy wpis i w ten sposób plik mógł puchnąć w nieskończoność. Dopisanie polecenia usunięcia pliku sprawę rozwiąże.

Generalnie biblioteka ogranicza zabawy z plikami do typowych zadań arduinowych. Nie mamy więc tutaj narzędzi do edycji plików. Jest to możliwe tylko po wydobyciu ich zawartości, przepisaniu do pamięci, przeprowadzeniu wymaganych operacji i zapisaniu ich z powrotem – uwzględniając ewentualne wyczyszczenie wcześniejszej zawartości, co najłatwiej uczynić usuwając plik i tworząc nowy, o tej samej nazwie.

No właśnie – o ile czytać karty można w nieskończoność, zapisywać bez opamiętania nie wolno. Chyba każdy słyszał o ograniczonej żywotności kart SD i jeśli napiszemy program, który nie uwzględni pewnych zasad z tym związanych, możemy kartę zamordować dosłownie w kilka dni. O tym jak się przed tym ustrzec, napiszę w ostatniej części serii poświęconej kartom SD.

Płytka edukacyjna TME-EDU-ARD-2Płytka edukacyjna TME-EDU-ARD-2

Inne artykuły z tej kategorii

Nasi partnerzy

TMETech Master EventTME EducationPoweredby
Copyright © 2026 arduino.pl