Что неправильно делаю при работе с SD?
- Войдите на сайт для отправки комментариев
Втр, 30/10/2012 - 19:45
Сабж, не выводит в терминал массив dirFiles[]
//Включение библиотек карты, дисплея, может быть, и клавиатуры #include <SD.h> #include <LiquidCrystalRus.h> //Инициализация переменных Sd2Card card; SdVolume volume; SdFile root; File rootDir; char* dirFiles[] = {}; void setup() { //Инициализация карты, сериалпорта, дисплея, может быть, и клавиатуры Serial.begin(9600); pinMode(53, OUTPUT); //Проверка карты if (!SD.begin(53)) { Serial.println("Initialization SDCard failed!"); return; } Serial.println("Initialization SDCard DONE..."); //Первичная загрузка файлов при запуске МК rootDir = SD.open("/"); listDirectory(rootDir); //Вывод списка файлов в терминал //for(int i; i<sizeof(dirFiles); i++) //{ // Serial.println(dirFiles[i]); //} Serial.println(dirFiles[0]); Serial.println(dirFiles[1]); Serial.println(dirFiles[2]); } void loop() { } //Заводская функция листинга файлов, переделанная мной void listDirectory(File dir) { //Очистка массива "dirFiles[]" //Загрузка списка файлов в массив "dirFiles[]" while(true) { int i = 0; File entry = dir.openNextFile(); if (!entry) break; // no more files if (entry.isDirectory()) { dirFiles[i] = entry.name() + '92'; } else { dirFiles[i] = entry.name(); } i++; } }
void listDirectory(File dir) {
//Загрузка списка файлов в массив "dirFiles[]"
while(true) {
int i = 0;
[...]
i++;
}
}
Не углубляясь в подробное исследование ваших кодов, замечу, что переменная i, значение которой вы усердно пытаетесь увеличивать, никогда не будет больше нуля.
Чтобы убедиться в этом, достаточно откомпилировать вот такой простой скетчик:
и посмотреть на вывод.
точно, спасибо большое. нужно было её объявлять намного выше. всё-таки чужую ошибку легче обнаружить, а свой код примелькался уже
Поменял, но теперь пишет три строчки какой-то несусветной хрени из пары символов в каждой строчке.
типа значения в массиве вроде есть, но, может, кодировка или что-то вроде того..
Попробуйте обявить масив String
Спасибо, помогло, но следующая напасть:
выводит только первый файл с карты
Ребят, выкладывал ранее весь листинг, и чуть выше фрагмент кода, который выводит лишь один файл. Не могу ума дать, ткните, пожалуйста, бестолкового...
Ещё боюсь засирать память дуины этими "стрингами", т.к. если файлов будет, например, 100, то это, мне кажется, сильно нагрузит её.
Столько много двумерных массивов. ни к чему
Прошу внимания к посту - кто знает ответ, помогите, пожалуйста!
сейчас выдает это:
иногда выплевывает имена фалов, которые действительно находятся на флешке.
код на данный момент выглядит так:
Не пробовали скорость SPI подбирать, может SD не успевает? (это так, мысль пришла...)
AlexFisher, все стандартные примеры работают на ура - выборка всей флешки в список из примера listfiles работает. Скорости должно хватать.
А вообще скорость SPI какой функцией меняется?
нашел класс смены скорости
.setClockDivider()
Допустимые параметры:
Может кто-нибудь кинуть напутствие какое? На этом форуме всегда откликались и помогали, что сейчас случилось?
Эххх... Жаль, leshak куда-то пропал, он бы помог.
Короче, вот это:
в терминале возвращает какой-то буферный хлам.
И выяснил, что функция
отрабатывает правильно, а функция
шлет в терминал ХЛАМ.
И ещё: если ли какой-нибудь класс в работе с SD картами, показывающий, что выполнение прекращено? Типа
Или в цикле while как условие всё же использовать "true" ?
Прошу свежим взглядом посмотреть на проблему.
Спасибо.
А у вас какая дуина? Мега? Вывод ридера SS точно к 53 выводу подключен?
Эххх... Жаль, leshak куда-то пропал, он бы помог.
Ну, оно по всякому бывает. Кушать (а значит работать) - тоже хочется ;) Рекламная, хе-хе, пауза: оплачивая работу leshak, по высоким расценкам, - ты помогаешь обществу :) Больше времени на форум можно уделить :)
Не вникая долго, не уверен, но смущает бросается в глаза строчка вида:
Тут мы объявляем массив указателей. А какой размера массив? НУЛЕВОГО! То есть памяти под хранение хоть чего-нибудь мы не выделили. Любая попытка записи в этот массив - должна приводить к порче данных/кода в памяти. Любое чтение - мусор из случаных обсластей памяти.
Вообщем читать про массивы (и то как важно следить за тем, что-бы не выходить за границы массива).
Вот это
Тоже не очень понял "что это" (не хочется хмурить мозг, но есть "настороженность"). Возможно стоит почитать про указатели и строки в C Не объект String, а именно char* . Кстати, imho char* diFiles[] - было лучше (если забыть про размер массива). Все-таки enity.name() возвращает char* .
Я вообще дико не люблю String. Он, вроде, как и "проще в использвании". Но блин, он же не совместим с обычным C/C++ кодом. Куда не кинься везде char* ожидается/возвращается. И как оно будет конвертироватся/приводится к String - еще попробуй разберись.
Вообщем я бы, отложил пока SD и взял какой-нибудь учебничек по C и почитал "массивы, строки (сишные), указатели".
Спасибо за ответ.
По порядку:
>> А у вас какая дуина? Мега? Вывод ридера SS точно к 53 выводу подключен?
У меня подключено всё правильно. Говорю с уверенностью, т.к. стандартные примеры SD отрабатывают, а это для меня - показатель.
>> String (или char*) dirFiles[] = {};
Это у меня (были и чэр* и стринг) считывание списка файлов в массив. Массив, естесственно, неопределенный, т.к. мы не знаем кол-во файлов.
>> dirFiles[i] = entry.name() + '92';
Добавляю символ "\".
>> Вообщем я бы, отложил пока SD и взял какой-нибудь учебничек по C и почитал "массивы, строки (сишные), указатели".
Теперь я понимаю, что именно так и нужно сделать.
Спасибо за ответы.
Конечно
>> String (или char*) dirFiles[] = {};
Это у меня (были и чэр* и стринг) считывание списка файлов в массив. Массив, естесственно, неопределенный, т.к. мы не знаем кол-во файлов.
Причины вашего {} - понятны
Он не "не определен". Он имеет ноль элементов. У нас нет тут динамических массивов. Фишлка dirFileas.add() - не прокатит. Мы не просто объявляем массив, а еще и резервируем память под элементы.
Так что тут либо нужно выделять память сишными средствами (не знаю, будут ли они работать в дуине), либо смотреть в сторону не массивов, а связных списков (и опять-таки выделять память, вообщем "гимор еще тот").
Обычно поступают просто - резервируют какой-то количество (например 50) и надеются что "у нас не будет больше файлов. А если больше - то выкручиватся как-то по частям их загружать в тот размер массива который есть.
Вообщем, пока, сделайте ему какой-нибудь размер заведомо больший чем у вас файлов на карте. И какоую-топ еременную, сколько вы уже положили в него элементов. dirFiles[filesCount]=.... ;filesCount++; if(fielsCount>MAX_FILES)КАРАУЛ
Так что обьявите просто
32 строки по 16 символов. Полкило памяти будет занято, но для Меги это не критично.
В общем, придется, наверное, поступить, как поступал с "Pagination" на PHP+SQL, т.е. "под размер экрана" кэшировать
Спасибо ещё раз
Да.. аналогия с web-овоским pager тут вполне уместна.
Обязательно нужно читать учебник по с++ ! Тут я бы объявил массив указателей, при добавлении элементов (строк) - выделял память под каждую (обращу внимание, что в С и в С++ это делается по-разному) с присваиванием указателю адреса начала соответствующей строки...
Мудрено, наверно... но в качестве самообразовательного процесса разобраться с указателями - крайне полезно.
Я себе написал шаблон, типа Vector<_type>, храню в нем разные структуры, но он еще сырой и недопиленный. Впрочем, если кто то хочет допилить - могу выложить. Тогда делаете Vector<String> и юзаете его.
ПС Конечно это не стантартный Vector, а своя реализация, достаточно тупая, хранит массив указателей на объекты и если массива не хватает расширяет его через realloc. Сколько жрет памяти - не смотрел, допилю, тогда увижу.