Изменение файловых атрибутов даты-времени при создании/корректировке файлов на SD-карте
- Войдите на сайт для отправки комментариев
В процессе работы с записью данных на SD-карту (Arduino Mega 2560 + Ethernet Shield) понадобилось устанавливать файловые атрибуты, связанные с датой-временем, которые в обычном случае жестко устанавливаются в 01.01.2000 01:00.
Беглое ознакомление с библиотеками показало, что в libraries\SD\utility\SdFat.h наличествуют функции класса SdFile: timestamp и sync , позволяющие работать с файловыми атрибутами
Данные функции использовались в решении, описанном тут: http://forums.adafruit.com/viewtopic.php?f=31&t=20355
Не могли бы участники форума опубликовать пример установки атрибутов даты-времени для файлов, обрабатываемых скетчем, использующем стандартную библиотеку SD?
Предположительно, это могло бы выглядеть как-то так.
#include <SD.h>
#include <Time.h>
...
SD.begin()
...
File file = SD.open("filename.txt", FILE_WRITE );
...
file.print("12345");
...
boolean T_C = file.timestamp( T_CREATE, year(), month(), day(), hour(), minute(), second() );
...
file.sync();
...
SD.close();
Данная схема, кстати, неверна, т.к. функции-методы timestamp , sync принадлежат классу, отличному от SD.
Буду благодарен за работающий пример установки атрибутов даты-времени при создании, и/или корректировке файла.
Добрый вечер.
Не специалист в данном вопросе, платы Ethernet Shield у меня нет.
Поэтому рабочий пример не дам, возможно кто-то еще откинется.
Возможно ответ тут, взял из кеша гугола.
http://webcache.googleusercontent.com/search?q=cache:IsnxaGOOBwIJ:forums.adafruit.com/viewtopic.php%3Ff%3D31%26t%3D20355+SdFat+set+the+date&cd=1&hl=ru&ct=clnk&gl=ru
Там Fat16, как я понял это маленькая библиотека, огрызок от SdFat.
// set creation date time if (!file.timestamp(T_CREATE,now.year(),now.month(),now.day(),now.hour(), now.minute(),now.second() )) { error("create time"); } // set write/modification date time if (!file.timestamp(T_WRITE,now.year(),now.month(),now.day(),now.hour(), now.minute(),now.second() )) { error("write time"); } // set access date if (!file.timestamp(T_ACCESS,now.year(),now.month(),now.day(),now.hour(), now.minute(),now.second() )) { error("access time"); }Тут посдсмотрел, как работает, без лишнего кода.
http://arduino.cc/forum/index.php?topic=116510.0
Возможно решение будет примерно таким, но....
Внимание, прежде чем запускать, нужно убедиться, что у вас именно 10 пин, осуществляет работу с SD.
Я плохо знаю сам Arduino, поэтому не подскажу какой именно у вас порт, в примере 10, но не факт, что у вас такой же.
Применое решение.
Дополнение
Да надо скачать библиотеку
sdfatlib20120719.zip http://code.google.com/p/sdfatlib/downloads/list.
Только, что увидел, есть официальный пример.
sdfatlib20121219\SdFat\examples\Timestamp
/* * This sketch tests the dateTimeCallback() function * and the timestamp() function. */ #include <SdFat.h> SdFat sd; SdFile file; // Default SD chip select is SS pin const uint8_t chipSelect = SS; // create Serial stream ArduinoOutStream cout(Serial); //------------------------------------------------------------------------------ // store error strings in flash to save RAM #define error(s) sd.errorHalt_P(PSTR(s)) //------------------------------------------------------------------------------ /* * date/time values for debug * normally supplied by a real-time clock or GPS */ // date 1-Oct-09 uint16_t year = 2009; uint8_t month = 10; uint8_t day = 1; // time 20:30:40 uint8_t hour = 20; uint8_t minute = 30; uint8_t second = 40; //------------------------------------------------------------------------------ /* * User provided date time callback function. * See SdFile::dateTimeCallback() for usage. */ void dateTime(uint16_t* date, uint16_t* time) { // User gets date and time from GPS or real-time // clock in real callback function // return date using FAT_DATE macro to format fields *date = FAT_DATE(year, month, day); // return time using FAT_TIME macro to format fields *time = FAT_TIME(hour, minute, second); } //------------------------------------------------------------------------------ /* * Function to print all timestamps. */ void printTimestamps(SdFile& f) { dir_t d; if (!f.dirEntry(&d)) error("f.dirEntry failed"); cout << pstr("Creation: "); f.printFatDate(d.creationDate); cout << ' '; f.printFatTime(d.creationTime); cout << endl; cout << pstr("Modify: "); f.printFatDate(d.lastWriteDate); cout <<' '; f.printFatTime(d.lastWriteTime); cout << endl; cout << pstr("Access: "); f.printFatDate(d.lastAccessDate); cout << endl; } //------------------------------------------------------------------------------ void setup(void) { Serial.begin(9600); while (!Serial) {} // wait for Leonardo cout << pstr("Type any character to start\n"); while (!Serial.available()); delay(400); // catch Due reset problem // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with // breadboards. use SPI_FULL_SPEED for better performance. if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt(); // remove files if they exist sd.remove("CALLBACK.TXT"); sd.remove("DEFAULT.TXT"); sd.remove("STAMP.TXT"); // create a new file with default timestamps if (!file.open("DEFAULT.TXT", O_CREAT | O_WRITE)) { error("open DEFAULT.TXT failed"); } cout << pstr("\nOpen with default times\n"); printTimestamps(file); // close file file.close(); /* * Test the date time callback function. * * dateTimeCallback() sets the function * that is called when a file is created * or when a file's directory entry is * modified by sync(). * * The callback can be disabled by the call * SdFile::dateTimeCallbackCancel() */ // set date time callback function SdFile::dateTimeCallback(dateTime); // create a new file with callback timestamps if (!file.open("CALLBACK.TXT", O_CREAT | O_WRITE)) { error("open CALLBACK.TXT failed"); } cout << ("\nOpen with callback times\n"); printTimestamps(file); // change call back date day += 1; // must add two to see change since FAT second field is 5-bits second += 2; // modify file by writing a byte file.write('t'); // force dir update file.sync(); cout << pstr("\nTimes after write\n"); printTimestamps(file); // close file file.close(); /* * Test timestamp() function * * Cancel callback so sync will not * change access/modify timestamp */ SdFile::dateTimeCallbackCancel(); // create a new file with default timestamps if (!file.open("STAMP.TXT", O_CREAT | O_WRITE)) { error("open STAMP.TXT failed"); } // set creation date time if (!file.timestamp(T_CREATE, 2009, 11, 10, 1, 2, 3)) { error("set create time failed"); } // set write/modification date time if (!file.timestamp(T_WRITE, 2009, 11, 11, 4, 5, 6)) { error("set write time failed"); } // set access date if (!file.timestamp(T_ACCESS, 2009, 11, 12, 7, 8, 9)) { error("set access time failed"); } cout << pstr("\nTimes after timestamp() calls\n"); printTimestamps(file); file.close(); cout << pstr("\nDone\n"); } void loop(void){}Artur1985, огромное Вам спасибо! Буду осваивать матчасть.
(пример с Fat16 видел, тупое скрещивание стоковой SD и Fat16 мне не помогло; зато теперь есть обильная пища для ума и рук)
Не за что, если используйте какие-то внешние библиотеки, смотрите последние версии.
И примеры, они или на сайте разработчика или внутри папки с библиотекой.
Хочу распросить вас о связке Arduino Mega 2560 + Ethernet Shield, у моего знакомого проблема с Ethernet Shield.
Поэтому себе не покупал.
Какая у вас плата, оригинал или нет?
Вы пробовали работу сети?
И как вы подключали плату, просто вставили и все?
Может ему достался не удачный экземпляр.
Сорри за задержку с ответом, не заметил Ваш вопрос.
У меня не оригинальная Мега, а отечественный клон Freeduino Mega 2560 http://mk90.ru/store/ru/microcontrollers/50-freeduino-mega-2560.html
Сетевой шилд http://mk90.ru/store/ru/shields/4-ethernet-shield.html оттуда же.
Использую несколько пар Мега+Шилд, в одном случае Мега версии 2.0.0, в остальных 3.0.0 (особеннности национального ардуиностроения: требуется установить оригинальный драйвер, плата поставляется вместе с драйверами семейства Freeduino). Схемотехника незначительно изменена в лучшую сторону по сравнению с оригиналом: применены кварцы и более стабильная частотозадающая цепь.
На Мега+Шилд реализован веб-клиент, он же веб-сервер.
У шилда есть особенность, связанная общим управлением кардридером и сетевой частью и тем, что у меги и у остальных Ардуин в этой части различная распиновка (53 и 10 пины соответственно). Поэтому, опуская детали, следует явно устанавливать режим работы с сетевым интерфейсом и с кардридером
digitalWrite( 4, HIGH); // SD disabled digitalWrite( 10, LOW ); // LAN enabledили
digitalWrite( 10, HIGH ); // LAN disabled digitalWrite( 4, LOW ); // SD enabledЕсли этого не делать, дребезг на неустановленных пинах приводит к спорадическим зависаниям устройства.
ПС
Для работы с картой я использовал стандартную библиотеку SD и удивлялся ее ограниченной функциональности иобилием используемых в официальных примерах недокументированных возможностей. В противоположность ей, SdFat отлично документирована и полнофункциональна. Но протестировать ее работу вместе с сетевой частью я еще не успел, так что о стабильности работы сетевого и карточного интерфейсов говорить с уверенностью не могу, хотя и предполагаю, что проблемы маловероятны.
День добрый.
>> Сорри за задержку с ответом, не заметил Ваш вопрос.
Бывает.
Спасибо за подробное разъяснение.
Надо будет, присмотрится к Freeduino.
Цена приятная, сетевая почти в 2 раза дешевле, да и мега.
Конечно, это не ebay, но последняя доставка не дошла, да и ждать месяц.
У меня оригинальные меги у друга тоже и сетевой.
Теперь сетевой достался мне, он не такой упорный:), но увы пока не пашет.
Код который вы указали, пробовал.
Пациент скорее мертв, чем жив.
Пингуется, глазками моргает, но не пашет.
Буду воевать с ней.
>> Но протестировать ее работу вместе с сетевой частью я еще не успел
Одновременно они не работают, но можно переключать как у вас в коде.
Еще раз спасибо.
И удачи!
Всем привет!Столкунулся с такой же проблемой,но ничего не понял,что написали выше.Как то строанно,что такой важной функции как установка атрибутов даты и времени для файлов отсутствует в стандартной библиотеке для работы с SD.Ковыряя библиотеку SD обнаружил в файле SdFat.h константы установки даты и времени по умолчанию FAT_DEFAULT_DATE и FAT_DEFAULT_TIME,может быть можно как то прикрутить к этому файлу использование данных с библиотеки часов например из этой ds3231.Прошу помощи у знатоков которые смоглибы использовать в библиотеке данные, полученные из другой библиотеке.
Исходные данные:
Используем SD и RTC (ну и Wire для RTC)
План реализации:
Пишем callback-функцию дату-время и подсовываем её SD.
Реализация:
#include <SD.h> #include <Wire.h> #include <RTClib.h> RTC_DS3231 RTC; // define the Real Time Clock object //------------------------------------------------------------------------------ // call back for file timestamps void cb_dateTime(uint16_t* date, uint16_t* time) { DateTime now = RTC.now(); // return date using FAT_DATE macro to format fields *date = FAT_DATE(now.year(), now.month(), now.day()); // return time using FAT_TIME macro to format fields *time = FAT_TIME(now.hour(), now.minute(), now.second()); } //------------------------------------------------------------------------------ void setup() { Serial.begin(9600); Wire.begin(); if (!RTC.begin()) { Serial.println("RTC failed"); while(1); }; // set date time callback function SdFile::dateTimeCallback(cb_dateTime); //теперь все операции с файлами должны брать время с RTC } //------------------------------------------------------------------------------ void loop() {}Источник: первая ссылка Гугла "arduino sd file date time".
Вроде компилится. Моя Arduin-ка только едет ко мне, так что мне проверить не на чем. Может протестит кто?
Проверил ,работает,но у меня другая библиотека для работы с часами 3231,пришлось немного подправить представленный код за который вам огромное спасибо.Вот что у меня получилось при работе с библиотекой DS3231
#include <SD.h> #include <Wire.h> #include <DS3231.h> Time t; DS3231 rtc(SDA, SCL); File myFile; //------------------------------------------------------------------------------ // call back for file timestamps void cb_dateTime(uint16_t* date, uint16_t* time) { t = rtc.getTime(); // return date using FAT_DATE macro to format fields *date = FAT_DATE(t.year, t.mon, t.date); // return time using FAT_TIME macro to format fields *time = FAT_TIME(t.hour, t.min, t.sec); } //------------------------------------------------------------------------------ void setup() { Serial.begin(9600); Wire.begin(); rtc.begin(); t = rtc.getTime(); pinMode(53, OUTPUT);// change this to 53 on a mega if (!SD.begin(53)) { Serial.println("initialization failed!"); } else { Serial.println("initialization done."); } // set date time callback function SdFile::dateTimeCallback(cb_dateTime); //теперь все операции с файлами должны брать время с RTC //создаем тестовый файл для проверки myFile = SD.open ("Test1.txt", FILE_WRITE); Serial.println("file created !"); myFile.close(); } //------------------------------------------------------------------------------ void loop() {}Проверил ,работает
Спасибо за тест! DS3231 тоже едет :)) Так заберу Ваш проверенный код к себе в копилку.
у меня заработало но может что не такили библиотек нету