Moduły kart: mikroSD (po lewej) i SD (po prawej) |
Specyfikacja
- zasilanie 5V (moduł posiada regulator napięcia)
- komunikacja
- magistrala SPI
- bezpośrednio z arduino (wbudowany konwerter poziomów napięć 3,3V - 5V)
Piny
- 5V, GND - zasilanie
- CS, SCK, MOSI, MISO - piny magistrali SPI
Uruchomienie
Do uruchomienia użyłem biblioteki SDFat i moduł czytnika z konwerterem poziomów napięć oraz karty Sandiska microSD o pojemności 8GB sformatowanej w FAT32. Początkowo użyłem modułu z dzielnikami napięcia do konwersji napięć szyny SPI (pierwsze zdjęcie, po prawej), bo tylko taki miałem, ale okazało się to poważnym błędem. W dokumentacji SDFat jest on w ogóle odradzany, a jeśli już chcemy go koniecznie użyć, to wskazane jest obniżenie o połowę częstotliwości pracy szyny SPI (szczegóły - katalog extras z biblioteki). W moim przypadku, wzięty z brzegu i raczej podstawowy przykład ReadWrite.ino (tworzony jest plik, zapisywane są do niego dane, a potem odczytywane) z tej biblioteki nie działał. Wobec tego pogrzebałem w sieci i napisałem coś pod własne potrzeby (przykład poniżej), który raz działał, raz nie (dla tego samego kodu), czyli niestabilnie. Generalnie straciłem przy nim mnóstwo czasu, a sama zmiana modułu (na taki z konwerterem) sprawiła, że problemy z brakiem zapisu na kartę zniknęły jak ręką odjął.
Uruchomienie modułu |
#include <SPI.h> #include <TimeLib.h> #include "SdFat.h" #define SD_CS_PIN SS SdFat sd; File file; ArduinoOutStream coutF(file); ArduinoOutStream coutS(Serial); void setup() { Serial.begin(9600); pinMode(SD_CS_PIN, OUTPUT); coutS << F("Initializing SD card...") << endl; if (!sd.begin(SD_CS_PIN)) { coutS << F("Initialization failed!") << endl; } else { coutS << F("Initialization done") << endl; coutS << F("Time\t\tValue") << endl; if (file.open("log.csv", FILE_WRITE)) { coutF << F("Time\t\tValue") << endl; file.flush(); } else { coutS << F("Cannot open file") << endl; } } //Generowanie losowej wartości randomSeed(analogRead(0)); } void loop() { long val = millis() / 1000; int days = elapsedDays(val); int hours = numberOfHours(val); int minutes = numberOfMinutes(val); int seconds = numberOfSeconds(val); int randomValue = random(40, 60); printToSerial(days, hours, minutes, seconds, randomValue); printToFile(days, hours, minutes, seconds, randomValue); delay(5000); } void printToSerial(int days, int hours, int minutes, int seconds, int randomValue) { coutS << int(days); coutS << ":" << ((hours < 10) ? "0" : "") << int(hours); coutS << ":" << ((minutes < 10) ? "0" : "") << int(minutes); coutS << ":" << ((seconds < 10) ? "0" : "") << int(seconds); coutS << "\t" << randomValue << endl; } void printToFile(int days, int hours, int minutes, int seconds, int randomValue) { coutF << int(days); coutF << ":" << ((hours < 10) ? "0" : "") << int(hours); coutF << ":" << ((minutes < 10) ? "0" : "") << int(minutes); coutF << ":" << ((seconds < 10) ? "0" : "") << int(seconds); coutF << "\t" << randomValue << endl; file.flush(); }
W kodzie dla oszczędności pamięci, łańcuchy znaków zapisuje w pamięci flash. Kolejna wygodna rzecz to klasa ArduinoOutStream z SDFat pozwalająca na wygodniejsze łączenie łańcuchów znaków w miejsce przydługawego klepania linii z funkcją print (dla Serial i File).
Podłączenia pinów arduino i modułu czytnika są następujące:
- CS - pin 10
- MOSI - pin 11
- MISO - pin 12
- CLK - pin 13
Dane z terminala i z pliku |
QuickStart - podłączenia pinów |
QuickStart - informacje o karcie |
Źródła
1) Biblioteka SdFat
Brak komentarzy:
Prześlij komentarz