Построчное чтение данных с SD карты
- Войдите на сайт для отправки комментариев
Ср, 27/05/2020 - 18:38
Добрый день!
Рисую один проект, где на карте есть файл, в файле построчно данные.
Желаю в общем цикле считывать строчки по мере необходимости.
Между чтением разумеется выполняется остальной код, где строчки будут разбираться и обрабатываться.
Но вот незадача,
Если файл открыть, сразу прочитать весь и закрыть, то при следующем вызове файл снова можно открыть и прочитать, но естественно не работает основной цикл.
Но вот если файл открыть, прочитать часть, выйти из функции, то при следующем вызове функции данные для чтения не доступны.
Не могу понять как работает этот механизм.
Подготовил пробник для проверки:
//-------НАСТРОЙКИ--------- const int PIN_CHIP_S_SD = 7; //-------НАСТРОЙКИ--------- String fString, fStringFileName, rwBuff; //-------БИБЛИОТЕКИ--------- String buffer;//тут хранится прочитанный из карты текст boolean FileOpen, FileClose, FileReady; #include <SPI.h> #include <SD.h> //File dataFile; //-------БИБЛИОТЕКИ--------- void FileRead() { File dataFile; if (FileOpen != 1) { Serial.print("Initializing SD card..."); // see if the card is present and can be initialized: if (!SD.begin(PIN_CHIP_S_SD)) { Serial.println("Card failed, or not present"); // don't do anything more: while (1); } Serial.println("card initialized."); FileOpen = 1; // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. dataFile = SD.open("test.txt"); Serial.println("File Open"); if (dataFile) { FileReady = 1; } //if (dataFile) // if the file isn't open, pop up an error: else { Serial.println("error opening"); } } // if the file is available, write to it: // это работает, только первую строку, при повторном чтении данных нет if (dataFile.available() > 0) { buffer = dataFile.readStringUntil('\n');//Считываем с карты одну строку. Serial.println(buffer); // для отладки отправляем по UART все что прочитали с карты. // Serial.write(dataFile.read()); delay(500); } else FileClose = 1; /* // это работает, только весь файл за один раз while (dataFile.available()) { buffer = dataFile.readStringUntil('\n');//Считываем с карты одну строку. Serial.println(buffer); // для отладки отправляем по UART все что прочитали с карты. // // Serial.write(dataFile.read()); delay(500); } // while FileClose = 1; */ if (FileClose == 1) { dataFile.close(); FileClose = 0; FileOpen = 0; Serial.println("File Close"); } } void setup() { Serial.begin(115200); // открыть порт для связи с ПК для отладки } void loop() { FileRead(); for (int i = 0; i < 5; i++) { Serial.print(i); delay(1000); } Serial.println(""); }
Что посоветуете для решения?
Что я делаю не так?
если файл открыть, прочитать часть, выйти из функции, то при следующем вызове функции данные для чтения не доступны.
Что я делаю не так?
и что вас удивляет? в строке 13 у вас переменная-файл - локальная для функции. если вы из функции выходите, то при следующем входе, конечно же, этой переменной уже нет.
Сделайте перемнную глобальной
Или статической
или аргументом по ссылке
еще можно (нужно!) закрывать файл при каждом выходе из функции, а заходя снова - открывать опять. тогда будет работать и с локальной переменной, но каждый раз файл нужно будет читать сначала
тут с вами согласен.
Обратите внимание, что эта переменная глобально тоже объявлялась, но сейчас закомментирована, с глобальной компилятор ругается.
Закрывать файл после чтения строки не вариант, так как в файле Gcode его нужно читать построчно по мере готовности станка принять новую посылку. Пока станок трудится, программа должна работать в общем цикле.
Пока вы отвечали, выкинул часть кода в отдельные функции, и почему-то заработало.
//-------НАСТРОЙКИ---------
Думаю еще String readLine() упростить до чтения всей строки целиком.
И еще попутный вопрос, можно с карты читать имена файлов форматом больше 8.3 ????
Пока вы отвечали, выкинул часть кода в отдельные функции, и почему-то заработало.
почему-то? :)
потому и заработало. что переменная теперь глобальная (строка 14)
Учитесь программировать. а то на каждом шагу будете спотыкаться
так постоянно чему-то и приходится учится. Два дня мучаю этот контроллер, уже в тупик зашел, наверно замкнутость мысли.
Что на счет длинны имени файла?
Создавать файлы с учетом длинны имени уже давно люди не заморачиваются.
На 3д принтере читается любая длинна, а в этой библиотеке файл более 8 добивается ~ и крякозяблами.
Возможно ли чтение списка и работа с файлами больше 8 ??? в рамках этой библиотеки?
Что то снова не выходит :(
Конфликт двух
Сначала получаю список файлов
где из примера
только пишем список в массив функцией AddListDir(fString, index_myFileDir);
Далее в меню устройства открываем список, выбираем нужный файл, сохраняем его имя, и можно переходить к открытию этого файла для чтения.
Примером выше у меня получилось построчно выводить файл, тут все хорошо.
Но когда компилируются обе переменных file и root, даже без исполнения кода с переменной file, root почему то не работает.
printDirectory не работает.
Если операции с переменной file выполнять в основном цикле, то компилятор на нее ругался, поэтому и вынес ее в локальную, так хоть что то работало.
А теперь все операции с file выполняются в теле функций, и с успехом компилируются вне основного цикла, но вся конструкция не работает.
Весь код, если интересно:
Если включить при компиляции строки 116 и 122, то код не работает. Хотя условий для запуска 589 строки нет.
Если отключить 589 строку, список файлов формируется.
А ОЗУ то хватает на все эти хотелки ?
пока да. там еще есть лишние вещи, позже оптимизирую. (сейчас 80%). Сейчас много диагностических сообщений и временных переменных. Какие то можно из int в char перевести, константы в ПЗУ переместить.
По сути осталось парсить строчки и по готовности станка отправлять их. Ну и на ходу подменять пакетах скорость перемещения.
Нашел глюк. мешали тестовые Serial.print. Убрал, заработало, видимо ели ресурсы. Сейчас все работает.
Делаю OffLine контроллер для GRBL.
Подскажите пожалуйста, правильно ли я понял - вы реализовали чтение и отправку G-code с SD карты непосредственно на ЧПУ? Если да - напишите пожалуйста на maxgoldmark@gmai.com - интересуют некоторые наработки. Платно конечно же.
Да, это off-line контроллер управления трех координатным ЧПУ станком, лазерным и\или фрезерным.
Я немного занимался с подобным, в принципе работает, но кое-что надо доработать. Сейчас отложил, нужно по быстрому автономный ЧПУ плазморез до ума довести. Исходники есть https://www.cnc-club.ru/forum/viewtopic.php?p=551630#p551630 может что пригодится.