Arduino: работа с microSD (29.01.2026). Печать
2026 - Январь
29.01.2026 00:00
Save & Share
После того, как RAM подорожала в 2-4 раза, - начало дорожать всё, что её содержит. Наверно, ноутбуки теперь - как автомобили (утильсбор же ещё на 20% подняли с 2026): стали роскошью, а не техническим средством улучшения качества жизни. Итак, еле-еле удалось урвать ноутбучную память DDR3L 4ГБ 1600МГц за 631руб - а вместе с ней: microSD-карту 256МБ попугай-едишн за 111руб и модуль чтения microSD за 33руб.

Естественно, на алиэкспрессе, - а не у магазинов-перекупов в РФ: за 1340руб и 184руб минимум бы получилось - они вообще с катушек слетели по ценообразованию. А сколько сейчас поддельных флешек, SD-карт и прочих носителей на маркетплейсах стало. При попытке найти цену 256МБ: десятки страниц подделок по "256ГБ", десятки объявлений подряд с подделками (среди которых скромно размещаются объявления с реальными объёмами и соответствующими ценами).

Итак, всё куплено - можно записать и считать данные. Но заранее знал, что будет трудно, - вышло труднее; и все опыты проходили примерно вот в таком стиле эмоций.


Модули работы с microSD не имеют ни фирмы, ни марки, ни модели - но точно поддерживают карты до 2ГБ, а также называются почему-то как модули для SD (имея в себе разъём именно microSD). MicroSD-карты малого объёма - вероятность подделки объёма ничтожная. Если учесть скорость процессора Arduino Nano 16МГц: скорость записи по интерфейсу SPI разъёма ICSP составит не более 2МБ/с - нет смысла заморачиваться с классом скорости носителя. И вот именно когда вскрылось, что управление осуществляется по SPI, - пришло понимание ещё до прихода модуля: всплыли в памяти "MOSI", "MISO" - будет жопа, как была ранее.

Как выглядела жопа:
- на модуле 1x6pin расположены в 1 ряд, на платформе - 2x3pin ICSP. Разъём на платформе - создан с вполне добрым умыслом и сильными мозгами: дублирование боковых контактов именно вверх - подошло именно сейчас, когда на платформе с датчиком пульса (продолжающей обрастать всяким хламом) начинаются проблемы с мешающимися проводами. Одновременно существует 2 варианта распиновки ICSP, даже если платформа совершенно одинаковая, - необходимо прозванивать все пины разъёма: с целью найти коротыш с 5V платформы;
- существует миниатюрный модуль microSD за ту же цену. Но ранее это было неизвестно - была куплена огромная дура в 4 раза больше. К тому же, в миниатюрном модуле железка для карты выступает перед модулем (удобно вставлять в корпуса), а на дуре - наоборот, утоплена в текстолит;
- не видел ни 1 модуля SD, имеющего разъём ICSP. Из этого следует, что покупка кабеля IDC 2x3pin 2.54мм мама-мама (для соединения без пайки и создания разъёмного соединения), - ровно наполовину невозможна. В итоге, был куплен кабель 1м за 100руб на алиэкспрессе: с целью разрезать на 5см и 95см - и напаиваться к модулю: с интересом, выдержит ли почти метр длины, - а потом перепаяться на короткий огрызок;
- присоединение 6 проводов вручную - корректно возможно только в случае, если провода разных цветов. Место, где можно найти такое разнообразие, - только потрошение БП ПК. В свою очередь, провода БП очень толстые - мало гибкости. В свою очередь, отрезаемая длина от БП не может превысить условных 30-50см - если потребуется метровая длина, будет весёлое соединение огрызков друг с другом пайкой и термоусадками (также, метровый кабель с 6 проводами будет толстым, и потребуется больше кусочков термоусадки для их фиксации). Также длина как минимум 1 провода точно будет выбрана неверно, об этом пойдёт речь ниже;
- о длине и толщине проводов. Дело в том, что SPI позволяет подключить к себе несколько устройств (к платформе параллельно присоединяются), - очень похоже на I2C. А в нём очень жёсткие требования к уменьшению сечения провода, требуется вычисляемый по формулам талмудного даташита обвес, требуется подключение обвеса прямо в конкретные места, нужен I2C-сканер - даже если устройство подключается всего одно, возня ещё та;
- на разъёме ICSP есть RST - но нет CS с модуля SD. Создаётся иллюзия, что CS не нужен, - но он участвует с определением ID подсоединяемого устройства по SPI (даже если оно одно). Подключается к любому цифровому каналу (с оглядкой на D0 и D1: не универсальные - могут пойти глюки), прописывается в исходниках. В итоге, провод CS от модуля должен быть сильно длиннее, чем остальные 5.



Итак, когда всё было получено и спаяно - выглядело примерно так.



Теперь остаётся только программировать (представьте постоянную беготню SD-карты между модулем SD и кард-ридером - мою беготню):
- карта вставляется цветной стороной вверх, контактами вниз;
- настройка модуля: pinMode(iCS_pin, OUTPUT). Хотя предпочитаю сразу DDR и PORT: VCC - 1 и 1, CS - 1 и 1 - понятно. MISO, MOSI, SCK - напишу позже;
- подключение сразу готового объекта SD по работе с картами: #include "SD.h". Вот отсюда и пошло, наверно, "модуль SD";
- проверка наличия карты: if (!SD.begin(iCS_pin)). Нет карты, не та файловая система, неправильно спаяли - false. FAT32 работает - необязательно FAT16 подавать;
- проверка типа карты, если хочется: #include "SPI.h" Sd2Card oCard; oCard.init(SPI_HALF_SPEED, 2); oCard.type(). Вернёт SD_CARD_TYPE_SD1 (1) в случае SD-карты Secure Digital (поколения 1), SD_CARD_TYPE_SD1 (2) в случае обычной SD-карты (поколения 1.1), SD_CARD_TYPE_SDHC (3) в случае карты Secure Digital High Capacity (поколения 2). Смущает то, что библиотека SPI ничего не знает о поколении 3 (SDXC, 2009) и поколении 4 (SDUC, 2018). Попугайная карта возвращает 2, что соответствует цене и номиналу объёма;
- открыть файл для манипуляций: File File_SD = SD.open("1___1.txt", FILE_READ/FILE_APPEND/FILE_WRITE). За 1 раз можно открывать 1 файл. Не умеет работать с русскоязычными файлами и пробелами. Не умеет создавать файлы с именем больше 12 символов. Был замечен баг: FILE_WRITE не затирает файл - и работает как FILE_APPEND;
- манипулировать: File_SD.readln() и File_SD.println() построчно, File_SD.read() и File_SD.print() посимвольно. Можно использовать SD.seek() и SD.peek(). Вообще, описание библиотеки крайне полезно для изучения: там же работа с файлами и директориями, преобразование данных в разные системы счисления;
- манипулировать бинарно: File_SD.read(), File_SD.write() - недостаточно для бинарной записи. double dNumber = 5: при write(dNumber) - записывает 1 байт с банальным чаром 05. Надо: File_SD.write((uint8_t*)&dNumber, sizeof(dNumber)). При этом, прикол (как же они зае...): double в Arduino Nano - 4-байтный, равный float - и по точности, и по бинарным записываемым числам: float 7 = double 7 = E0-40 (забыл, с какой стороны 4 нуля ещё). А если 2 поставить - перетипирует в int и запишет 07-00;
- закрыть: File_SD.close();
- если использовать объект oCard от SPI дальше - можно, например, получить весь список файлов на карте, тип её файловой системы и т.д.
- отмечается высокая нагрузка на платформу Arduino Nano по памяти. Один инклуд SD.h - жрёт 17% памяти и 38% динамической памяти. А тестовый код с Serial - уже 37% и 45% получилось.

Сколько жрёт мА при записи - потом напишу. Надо остыть. Особенно если учесть, что меня сбила машина, пока я был в трамвае. Нет времени как в фильмах: ни на покричать, ни отпрыгнуть - только глаза успеваешь округлить, и в тебя бочиной влетает автомобиль. Потом машинист даёт по тормозам, люди складываются по аналогии в фильме "Метро" 2013 года - но китайская куртка скользкая, и все проскальзывали по ней, не унося мою тушку за собой. Ну, мы ж люди умные: людей высадили в сугробы - надо подождать, пока толпа из трамвая проделает в них тропу, и только потом идти.


(добавлено 30.01.2026) Замеры по GND: ~4.5мА в состоянии покоя, постоянно меняющиеся 11-22мА (преимущественно 13мА) в состоянии записи в while (true).

Очень странно: значения PORTD, DDRD, PORTB, DDRB - не сказываются на работоспособности, не играют никакой роли. Предполагается, что во время SD.begin(2)) - всё само настраивается (потому что проверил на A0: настроечные регистры - работоспособны). А значит pinMode для CS - не требуется при единичном экземпляре устройства в SPI.

(добавлено 09.02.2026) Пришёл кабель IDC. Легко режется, гибкий, хорошо лудится и разделяется на отдельные проводки. В продаже на али появился и за 83руб с бесплатной доставкой - ещё и переплатил в итоге. Имеет красную направляющую - если подкрасить разъём ICSP, точно не ошибёшься при подсоединении.  Похоже, нельзя путать подсоединение: иначе на Reset пойдут 5В без подстроечного резистора.

(добавлено 14.02.2026) Торопился в пайке и допустил ошибку: не припаял CS. К удивлению, всё заработало, - теперь сомнения вообще в необходимости CS в случае единичного устройства в SPI.

(добавлено 16.02.2026) Второй модуль для microSD (маленький) - оказался под напряжение 3.3В. Вскоре рискну и тупо подключу последовательно через резистор - примерно понимая номиналы рабочих токов.

(добавлено 27.02.2026) Второй модуль оказался с другими токами. В итоге, на резисторе упало всего 0.13В - и 5В хлынули в рассчитанный на 3.3В модуль. В итоге - всё работает, но есть нюанс: почему-то CS оказался необходим. Как только припаялся к D9 и написал SD.begin(9) - всё заработало.

Кабель IDC длиной 0.9м - успешная работа.

Второй модуль не имеет светодиода.

(добавлено 12.03.2026) Исправил: 12 символов в имени файла можно, а не 8.

(добавлено 17.03.2026) SD.h жрёт очень много ресурсов - остаётся, реально, только на присоединение 1 датчика с самоконтролем работы с ним и с microSD. Попытка сделать свою переименованную библиотеку (в т.ч. библиотек, которые она тащит за собой) - успехом не увенчалась (undefined reference - и ничего с этим не сделать).

(добавлено 02.04.2026) Можно купить 1 IDC-кабель 2x7pin с каждой стороны и потом разломать посередине - получится 2 кабеля 2x3 дешевле почти в 2 раза, чем брать их 2шт.

А можно купить просто разъёмы 120руб/20шт - и при избытке проводов спаять свои кабели (самый выгодный вариант).

Ещё одно слово для поиска IDC-кабелей - JTag.

(добавлено 18.04.2026) Модуль прекрасно узко возвышается, если крепить его на штыри 90-градусные. Разъём для microSD при этом смотрит вверх.

Часами работал от напряжения 5В при указанном 3.3В - полёт нормальный.

(добавлено 27.04.2026) А вот хрен. Если модуль 3.3В питать от 5В всю ночь, прямо с вечера раннего, - microSD отваливается с 2 вариантами: просто отвалился модуль (и телеметрия сохранилась) или файловая система карты рушится (переформатирование решает проблему - но ночные данные потеряны).

На других купленных модулях - SCK, почему-то, называется CLK.

(добавлено 29.04.2026) Карта microSD стала с повреждённой поверхностью, вот почему файловая система слетала. И вот дилемма: просто карта бракованная была, или она от подаваемых 5В сыпаться начала? Чует жопа, придётся рискнуть и... засунуть туда другую, на максимальные 2ГБ уже, - будет весело.

(добавлено 06.05.2026) Не получилось кабель 2x7pin разделить на 2x3pin: чрезвычайно твёрдый пластик разъёма.

(добавлено 12.05.2026) CS - удобно делать 10: тогда D10-D13 в ряд пойдут на модуль SD, если использовать разъём ICSP нельзя.

Если имеется карта >2ГБ - достаточно использовать любую программу разметки диска, чтобы создать раздел FAT32 не более 2.000.000.000Б.

(добавлено 14.05.2026) Была снята длительная телеметрия (10ч) - новая карта с новым модулем при напряжении 3.3В идеально отработали.

(добавлено 15.05.2026) Изучение частоты записи данных на SD, вышла проблема. Вышел на расчётную частоту 11Гц, она идёт несколько секунд - бац, 9Гц. Идёт частота 37-43Гц несколько секунд - бац, единичное значение 19-20Гц. И непонятно: с SD связано, с датчиком, с исходниками или с самой Arduino. Но вывод прост: всегда записывать данные millis/micros при записи телеметрии. Исходя из лога возни с millis, думается, что именно в ней и проблема, - однако замена millis на micros показала, что нет. И с volatile для глобальных часто изменяемых переменных это тоже не связано.

(добавлено 16.05.2026) Чем точнее и чаще нужно снимать телеметрию - тем больше проблем. Выяснилось, что частота съёма телеметрии падает со временем, - и за 10ч может уменьшиться с 27Гц до 7Гц. Выяснилось, что параметр FILE_WRITE вообще использовать нельзя - нужно O_CREAT (без E) | O_WRITE. И, вообще, лучше смотреть в сторону библиотеки SdFat (которая тоже по умолчанию есть в составе Arduino - какого хрена оставили SD.h).

Если выключить ПК при питающейся через USB Arduino разъёмом перепрошивки - по информационному проводу ловится импульс, выглядит примерно так (подтягивающий резистор аналогового канала 82кОм ещё припаян не был).


(добавлено 18.05.2026) Нет кард-ридера: microSD вставляю прямо в включённый телефон - файловая система не разрушается, все файлы открываются (потому что чтение, а не запись).

Удалось выйти на запись данных с частотой 250-333Гц (почему-то чередуется: возможно, глючит millis - между 3 и 4мс застрял). При этом, microSD - самое дно: 2 класс со скоростью записи 3МБ/с. Open+Close файла, независимо от параметров, - жрут до хрена времени. Единственный путь: открывать в setup() и закрывать по нажатию/зажатию кнопки.

После замены millis на micros: частота 279-280Гц. Но точность добавила прикола с ранее выявленным периодическим единичным уменьшением частоты:
- теперь частота падает до 111Гц, а потом выстреливает 844Гц;
- частота может внезапно единично ускориться и стать 328Гц - без предыдущего падения;
- не связано с переполнением micros - точно связана с записью на носитель.

Убрал циклические 2 строки Serial: с 2 строками - 280Гц, с одной - 1839Гц, без строк - 3290Гц. Serial может выступать как искусственный тормоз съёма данных. 3.29кГц - максимум, который с исходниками удалось выжать (всё, действительно, зависит от криворукости исходного кода).

(добавлено 19.05.2026) Пример артефактных файлов, если их открыть и не закрыть при отключении питания. На работоспособность носителя и запись последующих данных - не влияет.


(добавлено 23.05.2026) Встал вопрос контрольной суммы файла: размер может достигать 2ГБ - критично.

(добавлено 25.05.2026) При изучении вопроса корректности записи свыше 2ГБ - обнаружилась библиотека TinyFAT, так наоборот меньше ограничение там - до 1ГБ. Люди пишут, что сама SD.h до 32ГБ, сами модули могут видеть такие карточки как 4ГБ - но никто не делал экспериментов на запись всего объёма.

(добавлено 03.06.2026) Регистратор телеметрии Arduino - вылизанные исходники, в т.ч. и по работе с microSD. А должен был быть самодельный холтер, однако баг с функцией write и нательными датчиками - поставил на разработке крест.
Обновлено ( 03.06.2026 20:07 )