Запись/чтение на sd-карту с arduino

Arduino: чтение и запись файлов на SD карту

Вы можете использовать SD карту в ваших устройствах на Arduino, чтобы сохранять и извлекать информацию.

В некоторых приложениях на Arduino полезно иметь возможность локально сохранять и извлекать информацию. Вы можете сделать это с помощью Secure Digital, или SD, карты.

SD карта – это энергонезависимая карта памяти, широко используемая в портативных устройствах, таких как мобильные телефоны, цифровые фотоаппараты, навигационные устройства GPS, карманные консоли и планшетные компьютеры. Другой тип SD карт – это карта microSD.

Это самая маленькая карта памяти, ее размеры составляют 15 мм x 11 мм x 1 мм. Это примерно четверть размера SD карты обычного размера.

Карта памяти microSD

Для подключения карты памяти microSD к нашей плате Arduino Mega мы будем использовать плату расширения Ethernet shield со встроенным слотом microSD. Однако, есть множество других плат расширения, доступных для других типов SD карт.

Распиновка карты памяти microSD

Как показано на рисунке выше, карта памяти microSD имеет 8 выводов. Описание каждого вывода приведено в таблице ниже.

Описание выводов карты памяти microSDНомер выводаНазваниеОписание
1 NC не подключен
2 CS выбор чипа / выбор ведомого (SS)
3 DI выход мастера / вход ведомого (MOSI)
4 VDD напряжение питания
5 CLK тактовый сигнал (SCK)
6 VSS земля
7 DO вход мастера / выход ведомого (MISO)
8 RSV зарезервировано

Если вы решили попробовать подключить SD карту самостоятельно, то убедитесь, что подключили выводы SD карты к соответствующим выводам платы Arduino. Так как мы используем имеющуюся в продаже плату расширения, то у нас с этим проблем нет.

Всё, что нам нужно сделать, это сконфигурировать вывод Arduino, использующийся по умолчанию, как CS (выбор чипа), для работы в качестве выхода. В нашей Arduino Mega это вывод 53. На плате расширение Ethernet shield выводом CS является вывод 4.

Вы должны правильно указать это в коде для SD карты.

Эксперимент 1

В этом эксперименте мы рассмотрим, как прочитать файл с SD карты.

Комплектующие

Arduino Mega с установленной платой расширения Ethernet shield

Код

Для чтения с SD карты мы будем использовать библиотеку SD.h. Данный код предполагает, что файл “” уже записан на SD карту.

#include const int cs = 4; void setup() { Serial.begin(9600); Serial.print(“Initializing card…”); // убедитесь, что стандартный вывод выбора чипа работает как выход pinMode(53, OUTPUT); // посмотреть, есть ли карта if (!SD.begin(cs)) { Serial.println(“Card failed to initialize, or not present”); return; } Serial.println(“card initialized.”); // открыть файл с именем ourfile.txt File myfile = SD.open(“ourfile.txt”); // если файл доступен, прочитать его if (myfile) { while (myfile.available()) { Serial.write(myfile.read()); } myfile.close(); } else // если файл не может быть открыт, то выдать сообщение об ошибке { Serial.println(“error opening the text file”); } } void loop() { }

Эксперимент 2

В этом эксперименте мы рассмотрим, как создать файл, записать его, а затем прочитать его с SD карты.

Комплектующие

Мы будем использовать то же самое аппаратное обеспечение, что и в предыдущем эксперименте.

Код

Чтобы записать файл на SD карту и прочитать его же, мы снова будем использовать библиотеку SD.h.

#include File myfile; void setup() { Serial.begin(9600); Serial.print(“Initializing card…”); // объявить стандартный CS вывод как выход pinMode(53, OUTPUT); if (!SD.begin(4)) { Serial.println(“initialization of the SD card failed!”); return; } Serial.println(“initialization of the SDcard is done.”); myfile = SD.open(“textFile.txt”, FILE_WRITE); if (myfile) { Serial.print(“Writing to the text file…”); myfile.println(“Congratulations! You have successfully wrote on the text file.”); myfile.close(); // закрыть файл Serial.println(“done closing.”); } else // если файл не может быть открыт, то выдать сообщение об ошибке { Serial.println(“error opening the text file!”); } // снова открыть текстовый файл для чтения myfile = SD.open(“textFile.txt”); if (myfile) { Serial.println(“textFile.txt:”); // прочитать весь текст, записанный в файле while (myfile.available()) { Serial.write(myfile.read()); } // закрыть файл myfile.close(); } else // если файл не может быть открыт, то выдать сообщение об ошибке { Serial.println(“error opening the text file!”); } } void loop() { }

Надеюсь, статья оказалась полезной. Оставляйте комментарии!

Оригинал статьи:

  • Editorial Team. Reading and Writing Files from an SD Card with an Arduino

Arduino Mega 2560

Отладочная плата Arduino Mega 2560 построена на микроконтроллере ATmega2560.

Она имеет 54 цифровых входных/выходных выводов (15 из которых могут использоваться в качестве ШИМ выходов), 16 аналоговых входов, 4 порта UART (аппаратных последовательных порта), кварцевый резонатор 16 МГц, подключение USB, разъем питания, разъем ICSP и кнопку перезагрузки. Она содержит всё необходимое для работы с микроконтроллером;…

Плата расширения Ethernet Shield W5100 R3 (для Arduino)

Макетная плата Arduino Ethernet Shield подключит вашу плату Arduino к интернету всего за несколько минут.

Просто установите данный модуль на вашу плату Arduino, подключите его к вашей сети с помощью кабеля RJ45 и следуйте нескольким простым инструкциям, чтобы начать управлять вашим проектом через интернет.

Как всегда с Arduino, каждый элемент платформы – оборудование, программное обеспечение…

Источник: https://radioprog.ru/post/139

Подключение sd карты к ардуино

SD и microSD карты могут существенно расширить возможности проектов ардуино, работающих с большими объемами данных: регистраторов данных, метеостанций, систем умного дома. Платы arduino оснащены сравнительно небольшой внутренней памятью, всего до 4 килобайт, включая и флэш-память, и EEPROM.

Этой памяти не хватит для записи больших объемов данных, тем более, если плата будет постоянно выключаться или выключаться. Подключение SD карты ардуино в качестве внешнего накопителя позволяет многократно увеличить место для хранения любой информации. Съемные накопители SD стоят дешево, легко подключаются и удобны в использовании.

О правильном подключении SD карты к Arduino и пойдет речь в статье.

Описание модуля для SD карты памяти

Работа с памятью SD в ардуино не представляет особых трудностей. Самым простым способом является подключение готового модуля и использование стандартной библиотеки. С этого варианта мы и начнем.

Использование готового модуля обладает различными преимуществами. Это довольно простое и удобное средство для работы с большим объемом данных. Он не требует особых навыков в подключении, все разъемы подписаны прямо на плате. За удобство приходится платить, но стоимость модуля относительно не велика, его легко можно найти по доступным ценам в российских и зарубежных интернет-магазинах.

Универсальный модуль представляет собой обыкновенную плату, на которой помещены слот для карты, резисторы и регулятор напряжений. Он обладает следующими техническими характеристиками:

  • Диапазон рабочих напряжений 4,5-5 В;
  • Поддержка SD карты до 2 Гб;
  • Ток 80 мА;
  • Файловая система FAT 16.

Модуль SD-карты реализует такие функции как хранение, чтение и запись информации на карту, которая требуется для нормального функционирования прибора на базе микроконтроллера.

Естественно, у недорогих модулей карт памяти есть и недостатки. Например, самые дешевые и распространенные модели поддерживают только карты до 4Гб и почти все модули позволяют хранить на SD карте файлы объемом до двух гигабайт – это ограничение используемой в большинстве моделей файловой системы FAT.

Еще одним недостатком карт памяти является относительно долгое время записи, однако существуют пути работы с ней, позволяющие увеличить ее скорость работы. Для этого используется механизм кэширования, когда данные сначала копятся в оперативной памяти, а потом сбрасываются за раз на карту памяти.

Платы Arduino для работы с SD

Для работы с SD card существует несколько различных плат:

  • Arduino Ethernet – эта  плата оснащена специальным модулем для вывода данных. Для выхода CS используется контакт 4. Для правильной работы нужно применять команду SD.begin(4).
  • Adafruit Micro-SD – это отладочная плата, которая используется при работе с Micro-SD картами.
  • Sparkfun SD – закрепляется сверху Ардуино, для выхода CS использует 8 контакт. В новой версии платы есть соединение с 3.3 В и встроен шестиразрядный инвертор.

Подключение SD и microSD к ардуино

Существует два вида карт — microSD и SD. Они одинаковы по подключению, структуре и программе, различаются же только размером. Перед работой советуется отформатировать карту SD.

Обычно новые карты уже отформатированы и готовы к работе, но если используется старая карта, то лучше провести форматирование в файловой системе Arduino. Для проведения процедуры на компьютере должна быть установлена библиотека SD, желательно FAT16.

Для форматирования на Windows нужно щелкнуть на иконке карты и нажать «Format».

Для подключения карты используется 6 контактов, взаимодействие производится по интерфейсу SPI. Она выглядит на плате как разъем на лицевой поверхности с шестью штырями.

Чтобы подключить карту, нужны сам контроллер, модуль карты и 6 проводов. Помимо SPI существует режим SDIO, но он сложен в реализации и слабо совместим с Ардуино.

SPI легко налаживается для работы со всеми микроконтроллерами, поэтому советуется использовать именно его.

Подключение цифровых выводов производится так: для платы  Arduino Nano или Uno контакт MOSI подключается к D11, MISO к D12,SCK к D13, CS к 4, VCC на +5 В,.GND к GND.

На плате имеются разъемы для подключения к 3,3 и 5 вольтам. Питание самой карты составляет 3,3 вольт, поэтому проще применять микроконтроллер с таким же питанием, в ином случае нужен преобразователей уровней напряжения.

На самых распространенных платах ардуино такой выход есть.

При подключении SD карты нужно учитывать соответствие SPI контактов для разных тип плат Arduino:

Плата Пин MOSI Пин MISO Пин SCK
Arduino Nano, Uno 11 12 13
Arduino Mega2560 51 50 52

Библиотека ардуино для работы с SD и microSD

Для удобства работы с внешними накопителями данных в среде Arduino IDE доступны уже готовые библиотеки. Ничего дополнительно скачивать или устанавливать в большинстве случаев не понадобится.

Для подключения библиотеки в скетче нужно использовать инструкцию include:

#include
#include

Библиотека SPI нужна для правильной работы устройств, подключаемых по SPI.

Библиотечные функции нужно для считывания и записи данных на карту. Библиотека может поддерживать SD и SDHC карты.

Имена записываются в формате 8.3, то есть 8 знаков для названия, 3 для расширения. Путь к файлу записывается с помощью слэшей «/».

Встроенные примеры библиотеки SD

В Arduino IDE встроены готовые примеры для быстрого изучение функций бибилотеки:

  • Card Info – это извлечение информации, хранящейся в SD карте. С ее помощью можно узнать, в какую файловую систему отформатирована карта, наличие свободного места, какие данные записаны.
  • Yun Datalogger – позволяет записывать лог-данные с трех сенсоров на карту.
  • Datalogger – регистрирует и созраняет данные, полученные с датчика на карту.
  • Dump File – считывание данные с карты, передает их в серийный порт.
  • Files – создает и удаляет данные. Существует функция file.write(), которая помещает записанные данные в буфер. Перемещение информации на карту происходит при вызове функций flush() или close(), поэтому важно закрывать его после каждого открытия файла, иначе данные будут потеряны.
  • Read Write – записывает и считывает файлы с карты.

Функции библиотеки SD

Ардуино-библиотека SD содержит различные функции, с помощью которыми можно управлять данными. Функции класса SD:

  • begin() – функция инициализирует библиотеку, присваивает контакт для сигнала.
  • exists() – призвана проверить, имеется ли на карте необходимая информация.
  • mkdir() – позволяет создать нужную папку на карте памяти.
  • rmdir() – с помощью этой функции можно удалить папку. Важно, чтобы удаляемая папка была пустой.
  • open() – позволяет открыть файл, который нужен для записи или чтения. Если нужный файл отсутствует на карте, то он будет создан.
  • remove() – удаляет любой файл.

В ответ на все эти функции должно прийти одно из значений – true, в случае удачного завершения операции и false при неудаче.

Создание, редактирование и удаление файлов

Для работы с файлами в ардуино существует класс File. В него входят функции, которые предназначены для записи и чтения информации с карты:

  • available() – проверяет наличие в файле байт, которые доступны для чтения. В ответ приходит количество места, которое доступно для чтения.
  • close() – закрывает файл, перед эти проверяет, сохранены ли данные на карту.
  • flush() – функция позволяет убедиться, что данные записаны на карту.
  • name() – возвращает указатель на имя.
  • peek() – считывает байты данных, при этом не перемещает указатель на следующий символ.
  • position() – находит текущее положение указателя в файле.
  • print() – выводит данные в отдельный файл.
  • println() – печатает данные в файл до места, где появляется символ перевода каретки и пустая строка.
  • seek() – меняет положение текущей позиции в файле.
  • size() – выводит информацию о размере данных.
  • read() – считывает информацию.
  • write() – производит запись в файл.
  • isDirectory() – с помощью этого метода происходит проверка, является ли файл директорией, то есть каталогом или папкой.
  • openNextFile() – выводит имя последующего файла.
  • rewindDirectory() – возвращает к первому файлу в директории.

Для корректной работы платы нужно проследить, чтобы был сконфигурирован SS выход.

Скетч примера работы с SD библиотекой ардуино

Ниже приведен скетч, демонстрирующий пример работы с модулем карты памяти.

/* Регистратор данных с использованием SD карт Пример сохранения данных с аналоговых портов на SD карте. Данные будут сохраняться в файле в виде набора строк с разделителем полей в виде символа “,” Схема подключения: * Аналоговые сенсоры подключаются к аналоговым пинам * Модуль SD карты подключен в SPI по стандартной схеме: ** MOSI – пин 11 ** MISO – пин12 ** CLK – пин 13 ** CS – pin 4 */ #include
#include const int PIN_CHIP_SELECT = 4; void setup() { Serial.begin(9600); Serial.print(“Initializing SD card…”); // Этот пин обязательно должен быть определен как OUTPUT pinMode(10, OUTPUT); // Пытаемся проинициализировать модуль if (!SD.begin(PIN_CHIP_SELECT)) { Serial.println(“Card failed, or not present”); // Если что-то пошло не так, завершаем работу: return; } Serial.println(“card initialized.”);
} void loop() { // Строка с данными, которые мы поместим в файл: String logStringData = “”; // Считываем данные с портов и записываем в строку for (int i = 0; i < 5; i++) { int sensor = analogRead(i); logStringData += String(sensor); if (i < 4) { logStringData += ","; } } // Открываем файл, но помним, что одновременно можно работать только с одним файлом. // Если файла с таким именем не будет, ардуино создаст его. File dataFile = SD.open("datalog.csv", FILE_WRITE); // Если все хорошо, то записываем строку: if (dataFile) { dataFile.println(logStringData); dataFile.close(); // Публикуем в мониторе порта для отладки Serial.println(logStringData); } else { // Сообщаем об ошибке, если все плохо Serial.println("error opening datalog.csv"); } }

Создание файла и выбор названия для arduino SD card

Создание файла — одна из самых распространенных задач, возникающих при работе с SD картами в ардуино. Как мы убедились в предыдущем скетче, для создания файла достаточно просто открыт его. Если мы захотим проверить, есть ли такой файл, можно использовать функцию exists():

  • SD.exists(«datalog.csv»);

Функция возвращает TRUE, если файл существует.

Популярной практикой при создании проектов — регистраторов данных является разбивка больших файлов на более мелкие, которые удобнее обновлять и открывать на компьютере.

Например, вместо одного очень большого файла datalog.csv на SD карте можно иметь несколько маленьких, добавляя к концу номер по порядку: datalog01.csv, datalog02.csv и т.д.

Вот пример скетча, который поможет вам выполнить эту работу:

char filename[] = “datalog00.CSV”; // Первоначальное название for (uint8_t i = 0; i < 100; i++) { filename[6] = i / 10 + '0'; filename[7] = i % 10 + '0'; if (! SD.exists(filename)) { // Проверяем наличие logfile = SD.open(filename, FILE_WRITE); break; // Дальше продолжать смысла нет } }

Заключение

Источник: https://ArduinoMaster.ru/datchiki-arduino/podklyuchenie-sd-karty-k-arduino/

Урок 20. Подключение и работа с флеш картой на Arduino

В этом уроке мы научимся создавать, редактировать и удалять файлы на MicroSD карте.

Нам понадобится:

Для реализации проекта не требуется установка дополнительных библиотек. Библиотека для работы с адаптером карт MicroSD v1.0 входит в стандартный набор Arduino IDE > Эскиз > Include Library > SD.

Схема подключения:

Подключение адаптера карт MicroSD v1.0 к Arduino Uno осуществляется к аппаратным выводам SPI (4 вывода: CS, SCK, MOSI, MISO).

Адаптер карт MicroSDArduino Uno
CS (Chip Select) 10
SCK (Serial ClocK) 13
MOSI (Master Out Slave In) 11
MISO (Master In Slave Out) 12
Vcc 5V
GND GND

Питание:

Питание адаптера подаётся на выводы Vcc и GND, напряжением 5В постоянного тока.

Базовые функции, для работы с файлами SD-карты:

// создание переменной myFile класса File библиотеки SD, которая будет служить “указателем” на файл File myFile; // переменная потребуется для открытия и закрытия файла, а так же для работы с открытым файлом
// открытие файла “iarduino.txt” для чтения и записи, начиная с конца файла: myFile = SD.open(“iarduino.txt”, FILE_WRITE); // если файла с именем “iarduino.

txt” – нет, то он будет создан.
// запись строки в файл >”iarduino.txt”: myFile.print(“начало строки, “); // запись строки в открытый файл “iarduino.txt”, без добавления символов перехода на новую строку. myFile.println(“продолжение строки.”); // запись строки в открытый файл “iarduino.txt”, с добавлением символов перехода на новую строку.
// закрытие файла “iarduino.

txt”: myFile.close();
// открытие файла “iarduino.txt” для чтения, начиная с начала файла: myFile = SD.open(“iarduino.txt”); // если файла с именем “iarduino.txt” – нет, то он не будет открыт.
// чтение строк из файла “iarduino.txt”: while(myFile.available()){ // если есть данные для чтения из открытого файла “iarduino.txt” Serial.write(myFile.

read()); // читаем очередной байт из файла и выводим его в последовательный порт. }
// удаление файла “iarduino.txt”: SD.remove(“iarduino.txt”); // функция возвращает результат удаления true/false
// создание файла “iarduino.txt”: myFile = SD.open(“iarduino.txt”, FILE_WRITE); // если файла с именем “iarduino.txt” – нет, то он будет создан. myFile.

close(); // закрываем файл “iarduino.txt” без записи данных.
// проверка существования файла “iarduino.txt”: if(SD.exists(“example.txt”)){…;} // условие будет выполнено, если файл “iarduino.txt” существует на SD-карте
// проверка открытия файла “iarduino.txt”: if(myFile){…;} // условие будет выполнено, если файл был успешно открыт: myFile = SD.open(…

)
// создание каталога “my_Dir” SD.mkdir(“my_Dir”); // функция возвращает результат создания true/false. Если указать “first_Dir/my_Dir”, то будет создано два каталога (каталог my_Dir в каталоге first_Dir)
// удаление каталога “my_Dir” SD.rmdir(“my_Dir”); // функция возвращает результат удаления true/false. Удаляемый каталог должен быть пустым

Создадим два скетча.

В первом будим создавать файл и записывать в него информацию, а во втором, удалим созданный файл.

Создание файла:

// подключение библиотек SPI и SD:
#include
#include
const uint8_t PIN_CS = 10; // указываем номер вывода arduino подключенного к выводу CS адаптера
File myFile; // создаём переменную myFile класса File, которая будет служить “указателем” на открытый файл
void setup(){ Serial.

begin(9600); // открываем последовательный порт на скорости 9600 бод while(!Serial){;} // ожидаем соединение последовательного порта
//используем ответ инициализации, для определения работоспособности карты и адаптера if(!SD.begin(PIN_CS)){ // инициализация SD карты с указанием номера вывода CS Serial.

println(“SD-card not found”); return; // ошибка инициализации. карта не обнаружена или не подключён (неправильно подключён) адаптер карт MicroSD }
//проверяем наличие файла “iarduino.txt” на SD-карте if(SD.exists(“iarduino.txt”)){ // если файл с именем “iarduino.txt” существует, то … Serial.println(“file exists”); }else{ // иначе … Serial.

println(“file doesn't exist”); }
//открываем файл “iarduino.txt” для чтения и записи, начиная с конца файла, и записываем в него строку myFile = SD.open(“iarduino.txt”, FILE_WRITE); // если файла с именем “iarduino.txt” – нет, то он будет создан. if(myFile){ // если файл доступен (открыт для записи), то … Serial.

println(“file is opened”); myFile.print(“The beginning of a line, “); // записываем первую часть строки в файл myFile.println(“The end of the line”); // записываем вторую часть строки в файл Serial.println(“data written to the file”); myFile.close(); // закрываем файл Serial.println(“file is closed”); }else{ // иначе … Serial.

println(“file is not opened”); }
//проверяем наличие файла “iarduino.txt” на SD-карте if(SD.exists(“iarduino.txt”)){ // если файл с именем “iarduino.txt” существует, то … Serial.println(“file exists”); }else{ // иначе … Serial.println(“file doesn't exist”); }
}
void loop(){
}

если подключить адаптер карт MicroSD v1.

0 к Arduino Uno, подключить Arduino Uno к ПК, загрузить скетч, вставить SD-карту и запустить Монитор последовательного порта, то в мониторе будут выведены следующие строки:

file doesn't exist (файл не обнаружен)file is opened (файл открыт) data written to the file (данные записаны в файл)file is closed (файл закрыт) file exists (файл обнаружен)

а на SD-карте появится файл “iarduino.txt” с одной строкой “The beginning of a line, The end of the line”.

Если загрузить скетч при вставленной в адаптер карт MicroSD v1.0 SD-картой, то на SD-карте появится файл “iarduino.txt” с двумя строками “The beginning of a line, The end of the line”, а первой строкой в мониторе последовательного порта будет “file exists” (файл обнаружен).

Дело в том, что функция setup() в обоих случаях выполняется дважды (сразу после загрузки скетча и после запуска монитора последовательного порта). Но в первом случае, после загрузки скетча, SD-карты не было в адаптере, следовательно, файл “iarduino.txt” был создан только после запуска монитора последовательного порта.

Удаление файла:

// подключение библиотек SPI и SD:
#include
#include
const uint8_t PIN_CS = 10; // указываем номер вывода arduino подключенного к выводу CS адаптера
void setup(){ Serial.

begin(9600); // открываем последовательный порт на скорости 9600 бод while(!Serial){;} // ожидаем соединение последовательного порта
//используем ответ инициализации, для определения работоспособности карты и адаптера if(!SD.begin(PIN_CS)){ // инициализация SD карты с указанием номера вывода CS Serial.

println(“SD-card not found”); return; // ошибка инициализации. карта не обнаружена или не подключён (неправильно подключён) адаптер карт MicroSD }
//проверяем наличие файла “iarduino.txt” на SD-карте if(SD.exists(“iarduino.txt”)){ // если файл с именем “iarduino.txt” существует, то … Serial.println(“file exists”);
// удаляем файл “iarduino.txt”: if(SD.remove(“iarduino.txt”)){ // функция возвращает результат удаления true/false Serial.

println(“file deleted”); }else{ Serial.println(“file is not deleted”); } }else{ // иначе … Serial.println(“file doesn't exist”); }
//проверяем наличие файла “iarduino.txt” на SD-карте if(SD.exists(“iarduino.txt”)){ // если файл с именем “iarduino.txt” существует, то … Serial.println(“file exists”); }else{ // иначе … Serial.

println(“file doesn't exist”); }
}
void loop(){
}

если подключить адаптер карт MicroSD v1.0 к Arduino Uno, подключить Arduino Uno к ПК, загрузить скетч, вставить SD-карту и запустить Монитор последовательного порта, то в мониторе будут выведены следующие строки:

file exists (файл обнаружен) file deleted (файл удалён) file doesn't exist (файл не обнаружен)

а файл “iarduino.txt” будет удалён с SD-карты.

Если загрузить скетч при вставленной в адаптер карт MicroSD v1.0 SD-картой, то файл “iarduino.txt” будет удалён с SD-карты, но в мониторе последовательного порта будут две строки “file doesn't exist” (файл не обнаружен).

Дело в том, что функция setup() в обоих случаях выполняется дважды (сразу после загрузки скетча и после запуска монитора последовательного порта). Но в первом случае, после загрузки скетча, SD-карты не было в адаптере, следовательно, файл “iarduino.txt” был удалён только после запуска монитора последовательного порта.

Источник: https://lesson.iarduino.ru/page/urok-20-podklyuchenie-i-rabota-s-flesh-kartoy-na-arduino/

Arduino: работаем с SD картами – Блог Ильи Житенёва (БЖ)

На днях мне пришёл заказанный модуль для работы с SD-картами.

 В этом посте я расскажу, как усовершенствовать, сделанный нами в прошлом, датчик для измерения температуры, а именно – мы избавим себя от надобности копирования данных из консоли вывода в Excel для дальнейшего анализа, заставив Arduino сохранять данные на SD-карту в виде csv-файла.

 Данные будут записываться в файл в два столбца – в первом будут единицы времени (или просто номер строки), а во втором значение напряжения на термисторе или ином датчике, которое, как Вы помните, пропорционально температуре.

Необходимые компоненты

Собираем схему

Описывать схему сборки измерителя температуры я не буду, если Вы забыли или не знаете как его собирать – обратитесь к посту, ссылка на который указана выше.

Схема подключения модуля SD-карт к Arduino

Рассмотрим схему подключения SD модуля. Каждый модуль имеет следующие контакты: GND, 5V, 3V (3.3V), CS, MOSI, SCLK (SCK), MISO, GND. Подключим некоторые из этих контактов к следующим контактам Arduino:

  • GND – к земле с Arduino;
  • 5V разъём к 5 вольтовому разъёму Arduino. (Аналогично 3.3V) Подключать оба разъёма одновременно – бессмысленно, я подключаю только 5V;
  • CS – к 4 разъёму;
  • MOSI – к 11 разъёму;
  • SCLK (SCK) – к 13 разъёму;
  • MISO – к 12 разъёму.

На этом наше подключение окончено. Для подключения можете использовать макетную плату – просто втыкаете туда SD модуль и в правильном порядке протягиваете провода от соответствующих дорожек к нужным разъёмам.

Подготавливаем SD-карту

SD модуль работает только с SD картами, отформатированными под файловую систему FAT16 или FAT32. Карту необходимо заранее отформатировать на компьютере. БУДЬТЕ ВНИМАТЕЛЬНЫ! При форматировании все данные, находящиеся на носителе, будут уничтожены! Не забудьте переписать их в другое место перед форматированием!

Программируем Arduino

// Подключаем библиотеку для работы с шиной SPI (необходима для работы библиотеки SD) #include // Подключаем библиотеку для работы с SD-картами #include File myFile; // Задаём начальное время (точку отсчёта) int time = 0; // Указываем номер аналогового разъёма для считывания данны int tempPin = 0; void setup() { // Открываем serial порт Serial.begin(9600); // Выдаём сообщение о том, что начинается инициализация SD-карты Serial.print(“Initializing SD card…”); pinMode(10, OUTPUT); // Проверяем готовность SD модуля. Если модуль не готов – выдаём сообщение if (!SD.begin(4)) { Serial.println(“initialization failed!”); return; } // Проверяем, существует ли на карте файл data.csv, если существует, то удаляем его. if(SD.exists(“data.csv”)) { SD.remove(“data.csv”); } // Выводим сообщение о том, что инициализация прошла успешно Serial.println(“initialization done.”); } void loop() { // Считываем данные (напряжение) с нулевого аналогового разъёма. int temp = analogRead(tempPin); // Увеличиваем значение времени (номер строки) на единицу. Если вы будете записывать данные раз в минуту, но хотите чтобы время записывалось в секундах – прибавляйте не единицу, а 60. time = time + 1; // Открываем файл data.csv для записи myFile = SD.open(“data.csv”, FILE_WRITE); // Если удалось открыть файл для записи, то записываем данные if (myFile) { // Выводим данные на экран Serial.print(time); Serial.print(“; “); Serial.println(temp); // Записываем время myFile.print(time); // Добавляем точку с запятой myFile.print(“;”); // Добавляем температуру и добавляем перенос строки myFile.println(temp); // закрываем файл myFile.close(); } else { // Выводим сооб щение о том, что открыть файл не удалось Serial.println(“error opening data.csv”); } // Повторяем считывание данных с датчика и запись на флэш-карту через одну секунду delay(1000); }<\p>

Загружаем наш скетч в Arduino, запускаем консоль (ctrl+shift+M) в среде Arduino и видим на экране каждую секунду две пары значений – номер строки (или же время) и значение напряжение, соответствующее данной температуре. Подождите, например, 10 секунд и отключите питание от Arduino. Извлеките карточку и вставьте её в компьютер. На карте у вас будет файл data.csv, открыв который в Excel вы увидите 2 столбика значений, что и в консоли Arduino. Теперь вы можете построить график или рассчитать среднее значение температуры в вашей комнате за какой-то промежуток времени.

На этом всё, задавайте свои вопросы мне в комментариях к этому посту, до скорых встреч!

Источник: https://zhitenev.ru/arduino-rabotaem-s-sd-kartami/

Arduino часть 3: Низкоуровневое чтение SD карты

Arduino часть 1: Arduino
Arduino часть 2: Shield для Arduino
Arduino часть 3: Низкоуровневое чтение SD карты

Некоторое время назад я приобрел Arduino Duemilanove на ATMEGA328P и начал с ним “играть”.

Некоторое из результатов покажу своему ЖЖ и сообществам 🙂 Пользуясь случаем, хочу сказать спасибо telegamochka, за позитив 🙂 Она смогла дать мне импульс мотивации оторвать задницу от дивана и начать снова программировать под микроконтроллеры.

В предыдущих записях я писал, что сделал небольшую платку для Arduino, с помощью которой подключил к нему SD-карту, которую теперь настало время испробовать в действии.

Лирическое отступление: по идее можно было бы взять готовую библиотеку для работы с SD картами, например SdFat. Но мне с одной стороны хотелось попробовать самому (процесс обучения), с другой – написать код, не используя Hardware-SPI. Кроме того, хочется написать очень минималистичную библиотеку.

Чтобы начать нужна документация, а еще лучше готовый пример. В качестве примера я взял код немецкого радиолюбителя Ulrich Radig (http://www.ulrichradig.de / много интересных проектов, но по-немецки), документацию на SPI-режим работы SD-карты можно взять тут.

Лирическое отступление 2: Уже не в первый раз я сталкиваюсь с иррациональным неприятием Arduino, примерно как и в свое время столкнулся с неприятием Visual Basic. Этого я в принципе не понимаю. У каждого языка есть свои задачи и своя область применения.

Никто же в здравом уме и твердой памяти не лезет писать вебсайты на C++, для этого берут Perl, PHP, ASP и еще черт знает что… Так же как и написание программы с GUI намного проще на Visual Basic (в современности .NET-языки), чем на “голом” С++.

На самом деле Arduino использует обьектно-ориентированный avrgcc в качестве основного компилятора, а значит и код не сильно отличается. Я попробую в тексте поста это наглядно показать, сравнивая исходный код на С и код на ардуиновом “С++”.

Библиотека Arduino имеет вид пары файлов (*.CPP, *.

H), лежащих в отдельной папке в директории “libraries” среды Arduino. Задача – их написать. Далее в тексте я буду выделять цветом код на С, и – код для Arduino, сравнивая их друг с другом.

Логика работы программы: инициализация карты происходит командами 0 и 1, после чего карта до выключения питания находится в последовательном режиме. Код будет давать возможность чтения отдельных секторов карты по их номеру, а также служебных данных карты (CID и CSD блоков). Для инициализации используется функция mmc_init(). Ее обьявление, конечно же, есть в *.

h файле:Но мы же работаем с обьектами! Поэтому мы в нашем *.h файле делаем обьявление класса, более того, вместо работы с константами заводим private элементы для сохранения номеров ног, к которым подключена карточка.

Номера ног передаем параметрами в Init, что позволит нам в основной программе легко конфигурировать обьект, не прибегая к помощи констант, а также иметь несколько полностью независимых SPI-интерфейсов:Пожалуй, это самое большое различие между программированием с обьектами и без. Дальнейший код выглядит намного более похоже друг на друга.

Реализация функции mmc_init() делится на несколько этапов: инициализация ног контроллера, выполнение команды 0, выполнение команды 1. Если эти этапы пройдены и карта отвечает на команды – маркируем карту (обьект) как проинициализированную.

По идее мы можем этот код перенять один к одному в код для Arduino, но это же не комильфо 🙂 Определим в заголовочном файле пару макросов, которые нам понадобятся:А в файле с кодом используем их:pinMode конфигурирует пин на вход или выход, digitalWrite используется для установки одного выходного пина в HIGH или LOW. Обе функции – стандартные функции Arduino.

По идее сделано все то же самое, разве что читабельность кода слегка возросла, но это – дело привычки.Теперь займемся инициализацией карты. Для начала нужно послать 74 или более “пустышек”-битов (скорее всего для очистки буфера карты).Сама же функция mmc_write_byte() определена в заголовочном файле:И ее реализация:Arduino не отстает.

В процедуре Init делаем то же самое:WriteByte будет использоваться только внутри класса, потому определяем его в заголовочном файле как private:Ee реализация выглядит немного проще, чем “оригинал”:Как видим, все абсолютно то же самое…

Особенно элегантно выглядит использование нами созданного класса в коде скетча:Код, приведенный тут – не полный, я для того, чтобы не делать пост сверхдлинным, их тут приводить не буду. Кому будет интересно увидеть полный код этой низкоуровневой библиотеки – обращайтесь, мне не жалко. Будет много желающих – выложу линк на архив прямо в пост.

Пожалуй, чтобы сделать несколько выводов информации достаточно. Во-первых, не так страшен черт – Arduino является самым обыкновенным контроллером семейства АТМЕГА и все, что контроллеру доступно, доступно и тут. Среду разработки можно сравнить с некоторого рода фреймворком, облегчающим процесс входа и работу с периферией. Возвращаясь к идее, что для каждой задачи есть свой наиболее подходящий инструмент, можно сказать, что для выполнения 90% задач, реализуемых на микроконтроллерах Arduino подойдет как нельзя лучше – задача выполняется быстрее за счет меньшего количества настроек. Недостаток – ограничение на определенные типы контроллеров (в принципе решается расширением среды разработки). Так что, не нужно holywar-ов, пользуйте на здоровье!

Источник: https://aterentiev.livejournal.com/21127.html

Модуль SD карты и Arduino

Если в вашем проекте необходимо обеспечить загрузку аудио, видео, графики, записи любых данных, возникает вопрос внешней памяти.

В большинстве микроконтроллеров встроенная память очень ограничена. Например, даже чип на Arduino Mega (Atmega2560) предоставляет всего лишь 4 Кбайта EEPROM для хранения данных. Конечно, флеш памяти побольше – 256 кбайт, но при ее использовании возникают проблемы с записью. Самое банальное – можно нечаянно перезаписать саму программу, загруженную на плату.

При загрузке графических или музыкальных файлов вам наверняка понадобится минимум 1 мегабайт хранилища. А если загружается больше информации? В этом случае можно использовать те же средства, что и в современных видеокамерах, сматфонах, mp3 плеерах: карта памяти!

Карты памяти часто называют SD или microSD картами и они позволяют хранить гигабайты информации. Продаются карты памяти в любом магазине электроники, так что проблем с покупкой не будет. Кроме того, на большинстве компьютеров есть кард-ридеры, так что с передачей полученной информации проблем не будет.

Что необходимо знать при использовании SD карт с Arduino

Первое. Карты рассчитаны на 3.3 В. При записи данных сила тока может достигать больших значений: до 100 мА и даже больше! Это говорит о том, что надо обеспечить качественное питание 3.3 В для карты. Кроме того, надо иметь источник питания 3.3 В для питания логики.

SD карты очень чувствительны – использование резисторов и длинных проводников при подключении приводят к значительному падению скорости передачи данных. Так что используйте максимально короткие коннекторы и избегайте резисторов в цепи питания логики.

Вместо этого можно использовать преобразователи уровня на базе чипов HEF4050, 74LVX245 или 74AHC125.

Второе. Есть два режима: SPI и SDIO. SDIO отрабатывает быстрее, но реализовать его при работе с Arduino сложно. SPI режим гораздо проще наладить при работе с любым микроконтроллером. Для подключения в режиме SPI понадобится всего четыре пина (более детально мы рассмотрим этот вопрос дальше).

SD карты выпускаются в двух форм-факторах: microSD и SD. Подключение, программа, структура и т.п. Для них одинакова. Единственное отличие – размер. Micro SD карты значительно меньше по габаритам.

Третье. SD карты представляют из себя чип с отдельными секторами. То есть, определенной структуры, которую вы обязаны использовать нет. Это значит, что карту можно отформатировать под файловую систему Linux, GFAT (DOS) или Mac.

На ней вообще может отсутствовать файловая система! При этом 99% компьютеров, камер, MP-3 плееров, GPS-навигаторов для использования требуют формат файловой системы FAT16 или FAT32.

Загвоздка заключается в том, что в микроконтроллерах вроде Arduino выделяется относительно большой процент памяти при работе со сложными файловыми системами.

Форматирование SD карты

В принципе, вы можете использовать SD карту без файловой системы, но это не очень удобно. Для работы с Arduino лучше использовать формат FAT16 или FAT32. В основном это связано с наличием соответствующих библиотек. Некоторые поддерживают один формат, некоторые – другой. Библиотека Arduino SD поддерживает оба формата.

При покупке новой SE карты высока вероятность, что она уже будет форматирована под файловую систему FAT. Проблемы все равно могут появиться. Неизвестно, как именно ее форматировал производитель. Если карта старая, ее желательно тоже проверить.

Библиотека Arduino SD, которую мы будем использовать поддерживает оба формата: FAT16 и FAT32. Если у вас небольшая карта, например, 8-32 мегабайта, она может быть форматирована под FAT12, которая не поддерживается. Придется ее форматнуть под 16 или 32.

В общем, рекомендуем в любом случае отформатировать карту перед ее использованием.

Для форматирования можно использовать например эту программу: SD Card Formatter

На странице загрузки есть инструкция по использованию программы. Проблем у вас возникнуть не должно.

Ссылки для заказа оборудования, которое использовалось в проекте из Китая

  • КУПИТЬ Arduino Uno R3;
  • КУПИТЬ Breadboard;
  • КУПИТЬ модуль модуля SD карты;

Подключение модуля SD-card к Arduino

После предварительной подготовки SD карты, можем приступить к подключению платы расширения microSD и Arduino. Плата расширения значительно облегчает подключение.

На ней установлен регулятор, который преобразовывает напряжение 3.3 – 6 В в 3.3 В (I2C). Есть регулятор уровня, который преобразует питание логики из 3.3-5 В в 3.3 В.

Это значит, что плату расширения можно использовать с микроконтроллерами 3.3 В и 5 В.

В нашем примере использован микроконтроллер Arduino. Если вы используете другой микроконтроллер, схема подключения и код могут отличаться.

Лучше всего подключать SD карту к пинам hardware SPI, потому-что при ее использовании происходит передача большого количества данных. На “классических платах Arduino (Duemilanove/Diecimila/Uno) это цифровой пин 13 (SCK), 12 (MISO) и 11 (MOSI). Вам также понадобится четвертый пин для цепи 'chip/slave select' (SS).

Традиционно используют 10 пин, но можно и другой. Обратите внимание, что если у вас плата Arduino Mega, пины будут отличаться! В этом случае используйте 50 (MISO), 51 (MOSI), 52 (SCK) и 53 (SS) для цепи CS. Опять таки, вы можете изменить пин SS (10 или 53).

Но для первого раза рекомендуем подключать именно так для корректной отработки кода, который будет приведен ниже.

  • Подключите пин 5V к пину 5V на Arduino
  • Подключите пин GND к пину GND на Arduino
  • Подключите Пин CLK к пину 13 или 52
  • Подключите DO к пину 12 или 50
  • Подключите DI к пину 11 или 51
  • Подключите CS к пину 10 или 53

Есть еще один коннектор – CD – это пин для инициализации SD карты. Он замыкается на землю, когда карта установлена. Если вы хотите его задействовать, подключите подтягивающий резистор (около 10 кОм) и дальше к другому пину. В данном примере рассматривать эту опцию мы не будем.

Все! Мы готовы отжигать!

Загрузка библиотеки и первый запуск SD карты

Передача данных на SD карту – это большой кусок кода, но к счастью для нас есть интегрированная в Arduino IDE библиотека под названием SD (название в точку, не правда ли? :)). Найти эту библиотеку можно в подменю Examples. В подменю Examples выберите скетч CardInfo.

С помощью этого скетча вы не сможете передавать данные, а просто получите ответ, опознана ли подключенная SD-карта. Очень полезный скетч, если необходимо узнать, поддерживается ли работа именно с вашей картой. Перед работой с новой картой обязательно проводите эту проверку!

В начале скетча проверьте переменную chipSelect. В данным примере мы подключаемся к 10 пину, соответственно переменная принимает значение 10.

Теперь устанавливаем SD карту в плату расширения и загружаем скетч.

Откройте окно серийного монитора в Arduino IDE, наберите какой-то символ и нажмите Send. Скорее всего у вас отобразится нечто подобное:

Обратите внимание, выдалась информация, что тип файловой системы – FAT16, размер карты (около 2 Гб, что в данном случае соответствует действительности) и т.п.

Если вам попалась плохая карта (в первую очередь, это карты от неизвестных производителей), отобразится примерно следующее:

В данном примере карта отвечает на запросы, но некорректно. Обратите внимание, рядом с Product ID выводится “N/A”, отсутствуют Manufacturer ID и OEM ID. Кроме того, карта возвращает ошибки SD errors. В общем, карта неработоспособна. Можно попробовать ее форматировать. Если после форматирования ошибки не исчезли, использовать ее не получится.

Попробуйте извлечь SD карту и вновь запустить программу. В окне серийного монитора появится следующее:

Это ошибки появляются, если не получилось даже инициализировать карту. Первая возможная причина: карта повреждена. Вторая: неправильное подключение модуля SD карты к Arduino.

Запись данных на SD карту через Arduino

В приведенном скетче продемонстрированы базовые возможности для записи данных на карту. По сути это основа для работы с модулем SD карты.

#include<\p>

File myFile;

void setup()

{

Serial.begin(9600);

Serial.print(“Initializing SD card…”);

// на Ethernet шилде CS соответствует 4 пину. По умолчанию он установлен в режим output

// обратите внимание, что если он не используется в качестве CS пина, SS пин на оборудовании

// (10 на большинстве плат Arduino, 53 на Arduino Mega) надо оставить в режиме output.

// иначе функции библиотеки SD library не будут работать.

pinMode(10, OUTPUT);

if (!SD.begin(10)) {

Serial.println(“initialization failed!”);

return;

}

Serial.println(“initialization done.”);

// открываем файл. Обратите внимание, что открывать несколько файлов параллельно нельзя.

// перед открытием нового файла, старый надо закрыть

myFile = SD.open(“test.txt”, FILE_WRITE);

// если удалось открыть файл, записываем в него:

if (myFile) {

Serial.print(“Writing to test.txt…”);

myFile.println(“testing 1, 2, 3.”);

// закрываем файл:

myFile.close();

Serial.println(“done.”);

} else {

// если файл не открылся, выводим сообщение об ошибке:

Serial.println(“error opening test.txt”);

}

}

void loop()

{

// после setup ничего не происходит

}

Запустив скетч на выполнение, вы увидите следующее:

После отработки скетча, можете открыть сформированный файл на персональном компьютере. Каждая строка соответствует одному циклу работы программы. То есть, данные добавляются, а не переписываются.

Стоит отметить несколько вещей:

  • Можно одновременно открывать несколько файлов и записывать в тот, который вы выберете.
  • Для записи строк, переменных и т.п. Используются функции print и println()
  • Вы должны закрыть (close()) файл(ы) после завершения, чтобы данные точно записались!
  • Вы можете открывать файлы из подпапок. Например, если вы хотите открыть файл, который находится по адрес /MyFiles/example.txt, вы можете вызвать SD.open(“/myfiles/example.txt”) и все отлично отработает.

Библиотека SD card не поддерживает 'длинные названия', так что имена файлов должны быть короткими! Например, IMAGE.JPG – отличное название, datalog.txt – тоже подходит. А вот что-то вроде “My GPS log file.text” не подойдет! Также учтите, названия не чувствительны к регистру. То есть, datalog.txt – это то же самое, что и DataLog.Txt или DATALOG.TXT

Считывание данных с SD карту через Arduino

Теперь разберемся как можно считывать информацию из файла, который хранится на карте. Процесс очень похож на запись. Будем использовать функцию SD.open() с указанием имени файла. Можно вызвать функцию available() (которая сообщит вам, есть ли на карте информация для считывания) и read() из файла, которая вернет следующий байт.

#include<\p>

File myFile;

void setup()

{

Serial.begin(9600);

Serial.print(“Initializing SD card…”);

// на Ethernet шилде CS соответствует 4 пину. По умолчанию он установлен в режим output

// обратите внимание, что если он не используется в качестве CS пина, SS пин на оборудовании

// (10 на большинстве плат Arduino, 53 на Arduino Mega) надо оставить в режиме output.

// иначе функции библиотеки SD library не будут работать.

pinMode(10, OUTPUT);

if (!SD.begin(10)) {

Serial.println(“initialization failed!”);

return;

}

Serial.println(“initialization done.”);

// открываем файл для считывания данных:

myFile = SD.open(“test.txt”);

if (myFile) {

Serial.println(“test.txt:”);

// считываем все данные из файла:

while (myFile.available()) {

Serial.write(myFile.read());

}

// закрываем файл:

myFile.close();

} else {

// если файл не открылся, отображаем сообщение об ошибке:

Serial.println(“error opening test.txt”);

}

}

void loop()

{

// после setup ничего не происходит

}

Некоторые важные примечания:

  • Вы можете держать одновременно открытыми несколько файлов и считывать информацию из нужного вам.
  • Read() возвращает байт за единицу времени. Функция не считывает всю строку!
  • В конце надо использовать функцию close() для закрытия файлов, чтобы сократить объем используемой RAM памяти.

Рекурсивная запись/считывание информации из файлов

В этой части мы рассмотрим пример более “продвинутого” использования SD карты. Например, подождем, пока не будут прочитаны все файлы с SD карты или будет воспроизводить с бесконечным повтором музыкальный файл.

В последних версиях библиотеки SD library вы можете перемещаться по папкам и вызывать следующий доступный файл с помощью функции openNextFile().

Файлы открываются не в алфавитном порядке, а в соответствии со временем их создания!

Запустите пример скетча SD→listfiles.

Там вы обнаружите подпапку ANIM (в ней находятся файлы с анимацией). Числа после названия файла характеризуют размер файла в байтах. Очень полезная программа, если вы хотите проверить какие именно файлы вызываются с вашей карты.

Стоит отметить несколько вещей:

Другие полезные функции

Есть и другие полезные функции для работы с SD картой. Некоторые из них мы приведем ниже:

  • Если вы хотите проверить наличие файла на носителе, используйте функцию SD.exists(“имя_файла.txt”), которая вернет значение true или false.
  • Удалить файл можно с помощью функции SD.remove(“имя_файла.txt”). Но будьте аккуратны! Файл удалиться полностью. Никакой “корзины” или резервной копии для восстановления не останется.
  • Создать подпапку можно с помощью функции SD.mkdir(“/имя_новой_папки”). Очень удобно для структуризации ваших данных на начальном уровне. Если папка с таким именем уже существует, ничего не произойдет. Не забывайте, что вы можете воспользоваться функцией SD.exists() перед созданием папки для проверки.

Несколько полезных функций для работы с файлами:

  • Для перемещения указателя при считывании/записи файла, используется функция seek(). Например, запись функции в виде seek(0) переместит вас в начало файла.
  • Функция position() позволит вам узнать, где именно вы находитесь в пределах файла на данный момент.
  • Функция size() выведет вам информацию о размере файла в байтах.
  • Узнать, является ли файл на карте директорией можно вызвав функцию isDirectory().
  • Последовательная работа с файлами, которые находятся в папке реализуется с помощью вызова функции openNextFile().
  • Возможно, вам понадобится имя файла. Например, если вы вызвали следующий файл в папке с помощью openNextFile(). В этом случае можно воспользоваться функцией name(), которая вернет массив символьных данных, которые можно отобразить непосредственно в серийном мониторе Arduino IDE с помощью Serial.print().

Загрузки

  • Даташит на microSD карту: Transcend.
  • Последняя версия библиотеки SD card library: Github.

Источник: http://arduino-diy.com/arduino-SD-karta

Ссылка на основную публикацию
Adblock
detector
",css:{backgroundColor:"#000",opacity:.6}},container:{block:void 0,tpl:"
"},wrap:void 0,body:void 0,errors:{tpl:"
",autoclose_delay:2e3,ajax_unsuccessful_load:"Error"},openEffect:{type:"fade",speed:400},closeEffect:{type:"fade",speed:400},beforeOpen:n.noop,afterOpen:n.noop,beforeClose:n.noop,afterClose:n.noop,afterLoading:n.noop,afterLoadingOnShow:n.noop,errorLoading:n.noop},o=0,p=n([]),h={isEventOut:function(a,b){var c=!0;return n(a).each(function(){n(b.target).get(0)==n(this).get(0)&&(c=!1),0==n(b.target).closest("HTML",n(this).get(0)).length&&(c=!1)}),c}},q={getParentEl:function(a){var b=n(a);return b.data("arcticmodal")?b:(b=n(a).closest(".arcticmodal-container").data("arcticmodalParentEl"),!!b&&b)},transition:function(a,b,c,d){switch(d=null==d?n.noop:d,c.type){case"fade":"show"==b?a.fadeIn(c.speed,d):a.fadeOut(c.speed,d);break;case"none":"show"==b?a.show():a.hide(),d();}},prepare_body:function(a,b){n(".arcticmodal-close",a.body).unbind("click.arcticmodal").bind("click.arcticmodal",function(){return b.arcticmodal("close"),!1})},init_el:function(d,a){var b=d.data("arcticmodal");if(!b){if(b=a,o++,b.modalID=o,b.overlay.block=n(b.overlay.tpl),b.overlay.block.css(b.overlay.css),b.container.block=n(b.container.tpl),b.body=n(".arcticmodal-container_i2",b.container.block),a.clone?b.body.html(d.clone(!0)):(d.before("
"),b.body.html(d)),q.prepare_body(b,d),b.closeOnOverlayClick&&b.overlay.block.add(b.container.block).click(function(a){h.isEventOut(n(">*",b.body),a)&&d.arcticmodal("close")}),b.container.block.data("arcticmodalParentEl",d),d.data("arcticmodal",b),p=n.merge(p,d),n.proxy(e.show,d)(),"html"==b.type)return d;if(null!=b.ajax.beforeSend){var c=b.ajax.beforeSend;delete b.ajax.beforeSend}if(null!=b.ajax.success){var f=b.ajax.success;delete b.ajax.success}if(null!=b.ajax.error){var g=b.ajax.error;delete b.ajax.error}var j=n.extend(!0,{url:b.url,beforeSend:function(){null==c?b.body.html("
"):c(b,d)},success:function(c){d.trigger("afterLoading"),b.afterLoading(b,d,c),null==f?b.body.html(c):f(b,d,c),q.prepare_body(b,d),d.trigger("afterLoadingOnShow"),b.afterLoadingOnShow(b,d,c)},error:function(){d.trigger("errorLoading"),b.errorLoading(b,d),null==g?(b.body.html(b.errors.tpl),n(".arcticmodal-error",b.body).html(b.errors.ajax_unsuccessful_load),n(".arcticmodal-close",b.body).click(function(){return d.arcticmodal("close"),!1}),b.errors.autoclose_delay&&setTimeout(function(){d.arcticmodal("close")},b.errors.autoclose_delay)):g(b,d)}},b.ajax);b.ajax_request=n.ajax(j),d.data("arcticmodal",b)}},init:function(b){if(b=n.extend(!0,{},a,b),!n.isFunction(this))return this.each(function(){q.init_el(n(this),n.extend(!0,{},b))});if(null==b)return void n.error("jquery.arcticmodal: Uncorrect parameters");if(""==b.type)return void n.error("jquery.arcticmodal: Don't set parameter \"type\"");switch(b.type){case"html":if(""==b.content)return void n.error("jquery.arcticmodal: Don't set parameter \"content\"");var e=b.content;return b.content="",q.init_el(n(e),b);case"ajax":return""==b.url?void n.error("jquery.arcticmodal: Don't set parameter \"url\""):q.init_el(n("
"),b);}}},e={show:function(){var a=q.getParentEl(this);if(!1===a)return void n.error("jquery.arcticmodal: Uncorrect call");var b=a.data("arcticmodal");if(b.overlay.block.hide(),b.container.block.hide(),n("BODY").append(b.overlay.block),n("BODY").append(b.container.block),b.beforeOpen(b,a),a.trigger("beforeOpen"),"hidden"!=b.wrap.css("overflow")){b.wrap.data("arcticmodalOverflow",b.wrap.css("overflow"));var c=b.wrap.outerWidth(!0);b.wrap.css("overflow","hidden");var d=b.wrap.outerWidth(!0);d!=c&&b.wrap.css("marginRight",d-c+"px")}return p.not(a).each(function(){var a=n(this).data("arcticmodal");a.overlay.block.hide()}),q.transition(b.overlay.block,"show",1*")),b.overlay.block.remove(),b.container.block.remove(),a.data("arcticmodal",null),n(".arcticmodal-container").length||(b.wrap.data("arcticmodalOverflow")&&b.wrap.css("overflow",b.wrap.data("arcticmodalOverflow")),b.wrap.css("marginRight",0))}),"ajax"==b.type&&b.ajax_request.abort(),p=p.not(a))})},setDefault:function(b){n.extend(!0,a,b)}};n(function(){a.wrap=n(document.all&&!document.querySelector?"html":"body")}),n(document).bind("keyup.arcticmodal",function(d){var a=p.last();if(a.length){var b=a.data("arcticmodal");b.closeOnEsc&&27===d.keyCode&&a.arcticmodal("close")}}),n.arcticmodal=n.fn.arcticmodal=function(a){return e[a]?e[a].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof a&&a?void n.error("jquery.arcticmodal: Method "+a+" does not exist"):q.init.apply(this,arguments)}}(jQuery)}var debugMode="undefined"!=typeof debugFlatPM&&debugFlatPM,duplicateMode="undefined"!=typeof duplicateFlatPM&&duplicateFlatPM,countMode="undefined"!=typeof countFlatPM&&countFlatPM;document["wri"+"te"]=function(a){let b=document.createElement("div");jQuery(document.currentScript).after(b),flatPM_setHTML(b,a),jQuery(b).contents().unwrap()};function flatPM_sticky(c,d,e=0){function f(){if(null==a){let b=getComputedStyle(g,""),c="";for(let a=0;a=b.top-h?b.top-h{const d=c.split("=");return d[0]===a?decodeURIComponent(d[1]):b},""),c=""==b?void 0:b;return c}function flatPM_testCookie(){let a="test_56445";try{return localStorage.setItem(a,a),localStorage.removeItem(a),!0}catch(a){return!1}}function flatPM_grep(a,b,c){return jQuery.grep(a,(a,d)=>c?d==b:0==(d+1)%b)}function flatPM_random(a,b){return Math.floor(Math.random()*(b-a+1))+a}