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

Inne artykuły z tej kategorii
Jak wyświetlić cyfry o rozmiarze 10x8 i 10x16 pikseli?














































































































