Парсинг текстового файла с SD карты

alexval2007
Offline
Зарегистрирован: 10.11.2012

Добрый день товарищи.

Стоит задача разобрать текстовый файл на переменные. Файл лежит на SD карте.

Удалось считать файл с карты в строку и вывести содержимое строки в монитор для теста.

теперь некоторый затык с разбором.

вот содержимое файла:

F:\MUZON.mp3
№ Модуля;№ Канала;Начало;Задержка
1;1;00:09.207;00:10.207;00:01.000;01.000;;;

1;2;00:12.207;00:15.207;00:01.000;03.000;;;

1;3;00:19.142;00:20.142;00:01.000;01.000;;;

1;4;00:25.108;00:25.108;00:01.000;00.000;;;

1;5;00:30.000;00:30.000;00:01.000;00.000;;;

1;6;00:35.000;00:35.000;00:01.000;00.000;;;

1;7;00:40.000;00:40.000;00:01.000;00.000;;;

1;8;00:45.000;00:45.000;00:00.000;00.000;;;

1;9;00:50.000;00:50.000;00:00.000;00.000;;;

1;10;00:55.000;00:55.000;00:00.000;00.000;;;

1;11;01:00.000;01:00.000;00:00.000;00.000;;;

1;12;01:05.000;01:05.000;00:00.000;00.000;;;

1;13;01:10.000;01:10.000;00:00.000;00.000;;;

1;14;01:15.000;01:15.000;00:00.000;00.000;;;

1;15;01:20.000;01:20.000;00:00.000;00.000;;;

1;16;01:25.000;01:25.000;00:00.000;00.000;;;

1;17;01:30.000;01:30.000;00:00.000;00.000;;;

1;18;01:35.000;01:35.000;00:00.000;00.000;;;

1;19;01:40.000;01:40.000;00:00.000;00.000;;;

1;20;01:45.000;01:45.000;00:00.000;00.000;;;

1;21;01:50.000;01:50.000;00:00.000;00.000;;;

1;22;01:55.000;01:55.000;00:00.000;00.000;;;

1;23;02:00.000;02:00.000;00:00.000;00.000;;;

1;24;02:05.000;02:05.000;00:00.000;00.000;;;

1;25;02:10.000;02:10.000;00:00.000;00.000;;;

1;26;02:15.000;02:15.000;00:00.000;00.000;;;

1;27;02:20.000;02:20.000;00:00.000;00.000;;;

1;28;02:25.000;02:25.000;00:00.000;00.000;;;

1;29;02:30.000;02:30.000;00:00.000;00.000;;;

1;30;02:35.000;02:35.000;00:00.000;00.000;;;

1;31;02:40.000;02:40.000;00:00.000;00.000;;;

1;32;02:45.000;02:45.000;00:00.000;00.000;;;

Строки под номерами 1 и 3 нужно пропустить и начать брать данные начиная с 5й строки файла.
переменные разделеные символом ";" группа параметров оканчивается символами ";;;" и переходом на следующую строку.
вот код что я уже написал 
//----------------------------------------------------------------------------------------
#include <SD.h>
#include <SPI.h>
//----------------------------------------------------------------------------------------
const int chipSelect = 53;  // Номер пина для CD карты для MEGA CS
File dataFile;
String buffer;//тут хранится прочитанный из карты текст
boolean SDfound;
//----------------------------------------------------------------------------------------
void setup() 
{
  Serial.begin(9600);         // Инициализируем UART.
  Serial.println("Initializing SD card..."); // Инициализация SD-карты...
  
  pinMode(chipSelect, OUTPUT);// Настроим выход выбора микросхемы на вывод.
                      
  if (SDfound == 0) 
  {
    if (!SD.begin(chipSelect)) 
    {
      Serial.print("The SD card cannot be found");
      while(1);
    }
  }
  
  SDfound = 1;
  dataFile = SD.open("TEST.zpl");//Откроем файл
  Serial.println("SD card ok.");

  if (!dataFile) 
  {
    Serial.print("text fail eror"); // Текстовый файл не открывается
    while(1);
  }

  while (dataFile.available()) //Читаем содержимое файла
  {
    buffer = dataFile.readStringUntil('\n');//Считываем с карты весь дотекст в строку до символа окончания.
    Serial.println(buffer); // для отладки отправляем по UART все что прочитали с карты.
  }
  dataFile.close(); //закроем файл
}

//----------------------------------------------------------------------------------------
void loop()
{
  
}
//----------------------------------------------------------------------------------------

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

 
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А никак нельзя вместо ;;; использовать тот же перевод строки? Или хотя бы люой одиночный символ? Или протокол не Вами задаётся?

alexval2007
Offline
Зарегистрирован: 10.11.2012

Добрый день евгений неполучится файл создаёт программа для PC а ардуинка его использует с флешки

Но по идее символ перевода строки там всеравно должен быть если судить по структуре файла

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Тогда Ваша тема - функция strtok

Пример раздербанивания строки на параметры по разделителю я двавал вот здесь - http://arduino.ru/forum/programmirovanie/eshche-raz-pro-strtok#comment-279523

Вот был ещё пример, на этот раз с признаком начала и признаком конца, там по точкам разбивается - http://arduino.ru/forum/programmirovanie/parsing#comment-312218

Logik
Offline
Зарегистрирован: 05.08.2014

Это формат - CSV. Гугл по этому поводу выдаем гору вариантов для всех мыслимых языков, и для Си тоже. Но честно говоря эта задача настолько тривиальная, что если Вам в голову не пришло ни одной идеи - програмирование не для Вас. Да, ;;; - это не конец группы, это три опциональных параметра. Конец группы -  символ перевода строки.

alexval2007
Offline
Зарегистрирован: 10.11.2012

вот что получается

//----------------------------------------------------------------------------------------
#include <SD.h>
#include <SPI.h>
#include <string.h>
template <typename T> inline Print & operator << (Print &s, T n) { s.print(n); return s; }
//----------------------------------------------------------------------------------------
const int chipSelect = 53;  // Номер пина для CD карты для MEGA CS
File dataFile;
String buffer;//тут хранится прочитанный из карты текст
boolean SDfound;
//char charBuf[64]; 
//----------------------------------------------------------------------------------------
void setup() 
{
  Serial.begin(9600);         // Инициализируем UART.
  Serial.println("Initializing SD card..."); // Инициализация SD-карты...
  
  pinMode(chipSelect, OUTPUT);// Настроим выход выбора микросхемы на вывод.
                      
  if (SDfound == 0) 
  {
    if (!SD.begin(chipSelect)) 
    {
      Serial.print("The SD card cannot be found");
      while(1);
    }
  }
  
  SDfound = 1;
  dataFile = SD.open("TEST.zpl");//Откроем файл
  Serial.println("SD card ok.");

  if (!dataFile) 
  {
    Serial.print("text fail eror"); // Текстовый файл не открывается
    while(1);
  }

  while (dataFile.available()) //Читаем содержимое файла
  {
    buffer = dataFile.readStringUntil('\n');//Считываем с карты весь дотекст в строку до символа окончания.
    Serial.println(buffer); // для отладки отправляем по UART все что прочитали с карты.
  }
  dataFile.close(); //закроем файл
  Serial.println("Test");
  
  char charBuf[buffer.length()+1]; 
  buffer.toCharArray(charBuf, buffer.length());
 // Serial.println (charBuf);
  char * pch;
  pch = strtok (charBuf,";");
  
  while (pch != NULL)
  {
    Serial.println (pch);
    pch = strtok (NULL, ";");
  }


}
//----------------------------------------------------------------------------------------
void loop()
{
  
}
//----------------------------------------------------------------------------------------

на выходе имеем 

F:\MUZON.mp3

№ Модуля;№ Канала;Начало;Задержка

1;1;00:09.207;00:10.207;00:01.000;01.000;;;

1;2;00:12.207;00:15.207;00:01.000;03.000;;;

1;3;00:19.142;00:20.142;00:01.000;01.000;;;

1;4;00:25.108;00:25.108;00:01.000;00.000;;;

1;5;00:30.000;00:30.000;00:01.000;00.000;;;

1;6;00:35.000;00:35.000;00:01.000;00.000;;;

1;7;00:40.000;00:40.000;00:01.000;00.000;;;

1;8;00:45.000;00:45.000;00:00.000;00.000;;;

1;9;00:50.000;00:50.000;00:00.000;00.000;;;

1;10;00:55.000;00:55.000;00:00.000;00.000;;;

1;11;01:00.000;01:00.000;00:00.000;00.000;;;

1;12;01:05.000;01:05.000;00:00.000;00.000;;;

1;13;01:10.000;01:10.000;00:00.000;00.000;;;

1;14;01:15.000;01:15.000;00:00.000;00.000;;;

1;15;01:20.000;01:20.000;00:00.000;00.000;;;

1;16;01:25.000;01:25.000;00:00.000;00.000;;;

1;17;01:30.000;01:30.000;00:00.000;00.000;;;

1;18;01:35.000;01:35.000;00:00.000;00.000;;;

1;19;01:40.000;01:40.000;00:00.000;00.000;;;

1;20;01:45.000;01:45.000;00:00.000;00.000;;;

1;21;01:50.000;01:50.000;00:00.000;00.000;;;

1;22;01:55.000;01:55.000;00:00.000;00.000;;;

1;23;02:00.000;02:00.000;00:00.000;00.000;;;

1;24;02:05.000;02:05.000;00:00.000;00.000;;;

1;25;02:10.000;02:10.000;00:00.000;00.000;;;

1;26;02:15.000;02:15.000;00:00.000;00.000;;;

1;27;02:20.000;02:20.000;00:00.000;00.000;;;

1;28;02:25.000;02:25.000;00:00.000;00.000;;;

1;29;02:30.000;02:30.000;00:00.000;00.000;;;

1;30;02:35.000;02:35.000;00:00.000;00.000;;;

1;31;02:40.000;02:40.000;00:00.000;00.000;;;

1;32;02:45.000;02:45.000;00:00.000;00.000;;;

Test
1
32
02:45.000
02:45.000
00:00.000
00.000





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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вы бы убрали чтение с карты, а текст забили бы просто в константу char * - сразу код бы стал короче и суть виднее. Да и ошибки чтения исключили бы - так сказать решали бы проблему в чистом виде.

alexval2007
Offline
Зарегистрирован: 10.11.2012

Евгений суть в том что читать нужно именно скарты потому что значения настроек в этом тексте будут менятся с помощью программы редактора на ПК. Убрать чтение с карты и вынести содержание текста в константы допускается разве что для тестирования.

sadman41
Offline
Зарегистрирован: 19.10.2016

Для тестирования вам и предлагают вынести...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

alexval2007 пишет:

разве что для тестирования.

А я что говорю? Чтобы при отладке strtok ничто другое внимание не отвлекало.

Вот запустите такой код


void setup(void) {
	Serial.begin(57600);

	char *s = (char *)
		"1;2;00:12.207;00:15.207;00:01.000;03.000;;;\n"
		"1;3;00:19.142;00:20.142;00:01.000;01.000;;;\n"
		"1;4;00:25.108;00:25.108;00:01.000;00.000;;;\n"
		"1;5;00:30.000;00:30.000;00:01.000;00.000;;;\n"
		"1;6;00:35.000;00:35.000;00:01.000;00.000;;;\n"
		"1;7;00:40.000;00:40.000;00:01.000;00.000;;;\n"
		"1;8;00:45.000;00:45.000;00:00.000;00.000;;;\n";

	for (char *p = strtok(s, ";"); p; p = strtok(NULL, ";\n")) {
		Serial.println(p);
	}
}

void loop (void) {}

У меня получился вот такой результат

1
2
00:12.207
00:15.207
00:01.000
03.000
1
3
00:19.142
00:20.142
00:01.000
01.000
1
4
00:25.108
00:25.108
00:01.000
00.000
1
5
00:30.000
00:30.000
00:01.000
00.000
1
6
00:35.000
00:35.000
00:01.000
00.000
1
7
00:40.000
00:40.000
00:01.000
00.000
1
8
00:45.000
00:45.000
00:00.000
00.000

Это то, что нужно? Если "то", то, как видите, делов-то - всего одна строчка. И суть дела намного виднее, чем если код перегружен посторонними операциями.

alexval2007
Offline
Зарегистрирован: 10.11.2012

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

F:\MUZON.mp3

№ Модуля;№ Канала;Начало;Задержка

 

 

alexval2007
Offline
Зарегистрирован: 10.11.2012

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

F:\MUZON.mp3

№ Модуля;№ Канала;Начало;Задержка

 

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, нужно - делайте. Как пользоваться strtok я Вам показал. А проигнорировать первые две строки - как-нибудь сообразите. Ну, и пихайте куда Вам надо. Парсинг-то работает, а с результатом делайте что хотите.

alexval2007
Offline
Зарегистрирован: 10.11.2012

Евгений вот что получилось

Вот так всё работает

//----------------------------------------------------------------------------------------
struct kv { 
char *value; 
char *Slat; 
char *Cue; 
char *Time; 
}; 
//----------------------------------------------------------------------------------------
void setup() 
{ 
   Serial.begin(9600); 
   while (!Serial); 
    
   char S[] = 
   "1;1;00:09.207;00:10.207;00:01.000;01.000;;;\n"
   "1;2;00:12.207;00:15.207;00:01.000;03.000;;;\n"
   "1;3;00:19.142;00:20.142;00:01.000;01.000;;;\n"
   "1;4;00:25.108;00:25.108;00:01.000;00.000;;;\n"
   "1;5;00:30.000;00:30.000;00:01.000;00.000;;;\n"
   "1;6;00:35.000;00:35.000;00:01.000;00.000;;;\n"
   "1;7;00:40.000;00:40.000;00:01.000;00.000;;;\n"
   "1;8;00:45.000;00:45.000;00:00.000;00.000;;;\n"
   "1;9;00:50.000;00:50.000;00:00.000;00.000;;;\n"
   "1;10;00:55.000;00:55.000;00:00.000;00.000;;;\n"
   "1;11;01:00.000;01:00.000;00:00.000;00.000;;;\n"
   "1;12;01:05.000;01:05.000;00:00.000;00.000;;;\n"
   "1;13;01:10.000;01:10.000;00:00.000;00.000;;;\n"
   "1;14;01:15.000;01:15.000;00:00.000;00.000;;;\n"
   "1;15;01:20.000;01:20.000;00:00.000;00.000;;;\n"
   "1;16;01:25.000;01:25.000;00:00.000;00.000;;;\n"
   "1;17;01:30.000;01:30.000;00:00.000;00.000;;;\n"
   "1;18;01:35.000;01:35.000;00:00.000;00.000;;;\n"
   "1;19;01:40.000;01:40.000;00:00.000;00.000;;;\n"
   "1;20;01:45.000;01:45.000;00:00.000;00.000;;;\n"
   "1;21;01:50.000;01:50.000;00:00.000;00.000;;;\n"
   "1;22;01:55.000;01:55.000;00:00.000;00.000;;;\n"
   "1;23;02:00.000;02:00.000;00:00.000;00.000;;;\n"
   "1;24;02:05.000;02:05.000;00:00.000;00.000;;;\n"
   "1;25;02:10.000;02:10.000;00:00.000;00.000;;;\n"
   "1;26;02:15.000;02:15.000;00:00.000;00.000;;;\n"
   "1;27;02:20.000;02:20.000;00:00.000;00.000;;;\n"
   "1;28;02:25.000;02:25.000;00:00.000;00.000;;;\n"
   "1;29;02:30.000;02:30.000;00:00.000;00.000;;;\n"
   "1;30;02:35.000;02:35.000;00:00.000;00.000;;;\n"
   "1;31;02:40.000;02:40.000;00:00.000;00.000;;;\n"
   "1;32;02:45.000;02:45.000;00:00.000;00.000;;;\n";

   Serial.println("test data: ");  

   for(int i = 0; i < sizeof(S); i++) 
   { 
     if(S[i]) 
     { 
        Serial.print(S[i]);
     } 
   } 
   
    Serial.println(); 

    struct kv parsed[192]; // 192 место для ввода для 32 каналов по 6 параметров
    int nparsed = 0; 

    for (char *p = strtok(S, ";"); p; p = strtok(NULL, ";\n")) 
    { 
      parsed[nparsed].value = p; 
      nparsed++; 
    } 

    Serial.print("Pole "); 
    Serial.println(nparsed); 
    Serial.println("value"); 

    for (int i = 0; i < nparsed; i++) 
    { 
       Serial.print(parsed[i].value); 
       Serial.println(); 
    } 
    
     Serial.println();
     Serial.println("test2 ");
     Serial.print("Slat: "); Serial.println(parsed[186].value);
     Serial.print("Cue:  "); Serial.println(parsed[187].value);
     Serial.print("None: "); Serial.println(parsed[188].value);
     Serial.print("Time: "); Serial.println(parsed[189].value);
     Serial.print("None: "); Serial.println(parsed[190].value);
     Serial.print("None: "); Serial.println(parsed[191].value);
} 
//----------------------------------------------------------------------------------------
void loop() 
{ 
  
} 
//----------------------------------------------------------------------------------------
test data: 
1;1;00:09.207;00:10.207;00:01.000;01.000;;;
1;2;00:12.207;00:15.207;00:01.000;03.000;;;
1;3;00:19.142;00:20.142;00:01.000;01.000;;;
1;4;00:25.108;00:25.108;00:01.000;00.000;;;
1;5;00:30.000;00:30.000;00:01.000;00.000;;;
1;6;00:35.000;00:35.000;00:01.000;00.000;;;
1;7;00:40.000;00:40.000;00:01.000;00.000;;;
1;8;00:45.000;00:45.000;00:00.000;00.000;;;
1;9;00:50.000;00:50.000;00:00.000;00.000;;;
1;10;00:55.000;00:55.000;00:00.000;00.000;;;
1;11;01:00.000;01:00.000;00:00.000;00.000;;;
1;12;01:05.000;01:05.000;00:00.000;00.000;;;
1;13;01:10.000;01:10.000;00:00.000;00.000;;;
1;14;01:15.000;01:15.000;00:00.000;00.000;;;
1;15;01:20.000;01:20.000;00:00.000;00.000;;;
1;16;01:25.000;01:25.000;00:00.000;00.000;;;
1;17;01:30.000;01:30.000;00:00.000;00.000;;;
1;18;01:35.000;01:35.000;00:00.000;00.000;;;
1;19;01:40.000;01:40.000;00:00.000;00.000;;;
1;20;01:45.000;01:45.000;00:00.000;00.000;;;
1;21;01:50.000;01:50.000;00:00.000;00.000;;;
1;22;01:55.000;01:55.000;00:00.000;00.000;;;
1;23;02:00.000;02:00.000;00:00.000;00.000;;;
1;24;02:05.000;02:05.000;00:00.000;00.000;;;
1;25;02:10.000;02:10.000;00:00.000;00.000;;;
1;26;02:15.000;02:15.000;00:00.000;00.000;;;
1;27;02:20.000;02:20.000;00:00.000;00.000;;;
1;28;02:25.000;02:25.000;00:00.000;00.000;;;
1;29;02:30.000;02:30.000;00:00.000;00.000;;;
1;30;02:35.000;02:35.000;00:00.000;00.000;;;
1;31;02:40.000;02:40.000;00:00.000;00.000;;;
1;32;02:45.000;02:45.000;00:00.000;00.000;;;

Pole 192
value
1
1
00:09.207
00:10.207
00:01.000
01.000
1
2
00:12.207
00:15.207
00:01.000
03.000
1
3
00:19.142
00:20.142
00:01.000
01.000
1
4
00:25.108
00:25.108
00:01.000
00.000
1
5
00:30.000
00:30.000
00:01.000
00.000
1
6
00:35.000
00:35.000
00:01.000
00.000
1
7
00:40.000
00:40.000
00:01.000
00.000
1
8
00:45.000
00:45.000
00:00.000
00.000
1
9
00:50.000
00:50.000
00:00.000
00.000
1
10
00:55.000
00:55.000
00:00.000
00.000
1
11
01:00.000
01:00.000
00:00.000
00.000
1
12
01:05.000
01:05.000
00:00.000
00.000
1
13
01:10.000
01:10.000
00:00.000
00.000
1
14
01:15.000
01:15.000
00:00.000
00.000
1
15
01:20.000
01:20.000
00:00.000
00.000
1
16
01:25.000
01:25.000
00:00.000
00.000
1
17
01:30.000
01:30.000
00:00.000
00.000
1
18
01:35.000
01:35.000
00:00.000
00.000
1
19
01:40.000
01:40.000
00:00.000
00.000
1
20
01:45.000
01:45.000
00:00.000
00.000
1
21
01:50.000
01:50.000
00:00.000
00.000
1
22
01:55.000
01:55.000
00:00.000
00.000
1
23
02:00.000
02:00.000
00:00.000
00.000
1
24
02:05.000
02:05.000
00:00.000
00.000
1
25
02:10.000
02:10.000
00:00.000
00.000
1
26
02:15.000
02:15.000
00:00.000
00.000
1
27
02:20.000
02:20.000
00:00.000
00.000
1
28
02:25.000
02:25.000
00:00.000
00.000
1
29
02:30.000
02:30.000
00:00.000
00.000
1
30
02:35.000
02:35.000
00:00.000
00.000
1
31
02:40.000
02:40.000
00:00.000
00.000
1
32
02:45.000
02:45.000
00:00.000
00.000

test2 
Slat: 1
Cue:  32
None: 02:45.000
Time: 02:45.000
None: 00:00.000
None: 00.000

а вот с картой пока неполучается

 

 
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

По самому первому скетчу: В строках №№ 50-56 что написано? Для чего это?

По второму скетчу: там вообще что-то непонятное. Что Вы читаете в строке 51? Первую строчку файла? зачем?

Я Вам уже об этом говорил, не мешайте всё вместе. Отлаживайте по частям. Не умеете читать с карты - выбросьте из программы всё, кроме чтения с карты и добейтесь чтобы это работало. Вы же опять всвалил всё в кучу.

alexval2007
Offline
Зарегистрирован: 10.11.2012

По самому первому скетчу: В строках №№ 50-56 что написано? Для чего это? 

Это для теста выводит в порт содержание строки без изменений

   for(int i = 0; i < sizeof(S); i++) 
   { 
     if(S[i]) 
     { 
        Serial.print(S[i]);
     } 
   } 

По поводу второго скетча это которого?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

alexval2007 пишет:

Это для теста выводит в порт содержание строки без изменений

   for(int i = 0; i < sizeof(S); i++) 
   { 
     if(S[i]) 
     { 
        Serial.print(S[i]);
     } 
   } 

Фига-се! А чем не угодил вариант:

Serial.println(S);

"Не наш метод"?

alexval2007 пишет:

По поводу второго скетча это которого?

Ну, там был скетч с картой, Вы сейчас его зачем-то удалили.

 

alexval2007
Offline
Зарегистрирован: 10.11.2012

ну по поводу не нашего метода то да он не наш обрезок от чужого кода

а по поводу скетча с картой то вот он тут читает и парсит нормально 

//----------------------------------------------------------------------------------------
#include <SD.h>
#include <SPI.h>
#include <string.h>
//----------------------------------------------------------------------------------------
struct kv { 
char *value; 
char *Slat; 
char *Cue; 
char *Time; 
}; 
//----------------------------------------------------------------------------------------
const int chipSelect = 53;  // Номер пина для CD карты для MEGA CS
File dataFile;
String buffer;//тут хранится прочитанный из карты текст
boolean SDfound;
//----------------------------------------------------------------------------------------
void setup()
{
   Serial.begin(9600); // Инициализируем UART.
   while (!Serial); 
    
  char S[] = " ";
  struct kv parsed[192]; // 192 место для ввода для 32 каналов по 6 параметров
  int nparsed = 0; 

  Serial.println("Initializing SD card..."); // Инициализация SD-карты...
  pinMode(chipSelect, OUTPUT);// Настроим выход выбора микросхемы на вывод.
                    
  if (SDfound == 0)
  {
    if (!SD.begin(chipSelect))
    {
      Serial.print("The SD card cannot be found");
      while(1);
    }
  }
  SDfound = 1;
  dataFile = SD.open("TEST.zpl");//Откроем файл
  Serial.println("SD card ok.");

  if (!dataFile)
  {
    Serial.print("text fail eror"); // Текстовый файл не открывается
    while(1);
  }
  
 Serial.println("Test-1");

 while (dataFile.available()) //Читаем содержимое файла
 {
    buffer = dataFile.readStringUntil('\n');//Считываем с карты весь текст в строку до символа окончания.
    Serial.println(buffer); // для отладки отправляем по UART все что прочитали с карты.
    
    char charBuf[buffer.length()+1];
    buffer.toCharArray(charBuf, buffer.length());

    char *pch;
    pch = strtok (charBuf,";");
    while (pch != NULL)
    {
      parsed[nparsed].value = pch; 
      nparsed++; 
      Serial.println (pch);
      pch = strtok (NULL, ";");
    }
  }

  dataFile.close(); //закроем файл
}
//----------------------------------------------------------------------------------------
void loop()
{

}
//----------------------------------------------------------------------------------------

проблемы возникают при попытке добавить сохранение в массив

//----------------------------------------------------------------------------------------
#include <SD.h>
#include <SPI.h>
#include <string.h>
//----------------------------------------------------------------------------------------
struct kv { 
char *value; 
char *Slat; 
char *Cue; 
char *Time; 
}; 
//----------------------------------------------------------------------------------------
const int chipSelect = 53;  // Номер пина для CD карты для MEGA CS
File dataFile;
String buffer;//тут хранится прочитанный из карты текст
boolean SDfound;
//----------------------------------------------------------------------------------------
void setup()
{
   Serial.begin(9600); // Инициализируем UART.
   while (!Serial); 
    
  char S[] = " ";
  struct kv parsed[192]; // 192 место для ввода для 32 каналов по 6 параметров
  int nparsed = 0; 

  Serial.println("Initializing SD card..."); // Инициализация SD-карты...
  pinMode(chipSelect, OUTPUT);// Настроим выход выбора микросхемы на вывод.
                    
  if (SDfound == 0)
  {
    if (!SD.begin(chipSelect))
    {
      Serial.print("The SD card cannot be found");
      while(1);
    }
  }
  SDfound = 1;
  dataFile = SD.open("TEST.zpl");//Откроем файл
  Serial.println("SD card ok.");

  if (!dataFile)
  {
    Serial.print("text fail eror"); // Текстовый файл не открывается
    while(1);
  }
  
 Serial.println("Test-1");

 while (dataFile.available()) //Читаем содержимое файла
 {
    buffer = dataFile.readStringUntil('\n');//Считываем с карты весь дотекст в строку до символа окончания.
    char charBuf[buffer.length() + 1];
    buffer.toCharArray(charBuf, buffer.length());

    
    for (char *p = strtok(charBuf, ";"); p; p = strtok(NULL, ";\n")) 
    { 
      parsed[nparsed].value = p; 
      nparsed++; 
    } 

    Serial.print("Pole "); 
    Serial.println(nparsed); 
    Serial.println("value"); 

    for (int i = 0; i < nparsed; i++) 
    { 
       Serial.print(parsed[i].value); 
       Serial.println(); 
    } 
 }

  dataFile.close(); //закроем файл
  
     Serial.println();
     Serial.println("test2 ");
     Serial.print("Slat: "); Serial.println(parsed[186].value);
     Serial.print("Cue:  "); Serial.println(parsed[187].value);
     Serial.print("None: "); Serial.println(parsed[188].value);
     Serial.print("Time: "); Serial.println(parsed[189].value);
     Serial.print("None: "); Serial.println(parsed[190].value);
     Serial.print("None: "); Serial.println(parsed[191].value);
}
//----------------------------------------------------------------------------------------
void loop()
{

}
//----------------------------------------------------------------------------------------

если вы имели в виду для чего это

    buffer = dataFile.readStringUntil('\n');//Считываем с карты весь дотекст в строку до символа окончания.
    Serial.println(buffer); // для отладки отправляем по UART все что прочитали с карты.
    
    char charBuf[buffer.length()+1];
    buffer.toCharArray(charBuf, buffer.length());

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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вы не поняли.

У Вас так много скетчей, давайте так: сейчас мы говорим про тот, что идёст сразу после фразы "читает и парсит нормально".

Ни фига не нормально.

В строке №52 Вы не читаете весь файл как думаете, а читаете только первую строку (до '\n').

Затем Вы эту одну строку парсите и печатаете. Но при парсинге Вы не сохраняете значение, которое распарсили, а только запоминаете указатель на него.

Однако, уже при следующем проходе цикла в Вас это указатель устаревает, т.к. Вы заново размещаете массив charbuf.

В результате у Вас в памяти мешанина.

Для того, чтобы убедиться, что там чушь, просто вставьте в строку 68 печато Вашего массива parsed и посмотрите какая в нём красота сидит.

alexval2007
Offline
Зарегистрирован: 10.11.2012

Согласен косяк, но как это исправить?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, не знаю. Там миллион способов. Тем более, что не понимаю задачи.

Начать можно с того, что массив charBuf, не нужен, т.к. он тупо дублирует текст в строке buffer, жрёт память не привнося ничего нового.

Можно полученные значения просто копировать в структу prased, только описать их надо правильно (как массивы, а не как указатели).

Ну, и самое главное. Сейчас Вы дважды держите в памяти весь прочитанный файл (вернее, пытаетесь). Оно Вам точно надо? Точно нужно именно весь файл одновременно иметь в памяти? Или достаточно "прочита строку, обработал, выбросил, прочитал следующую".

Откуда мне всё это знать?

 

alexval2007
Offline
Зарегистрирован: 10.11.2012

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

так как обработка будет тоже объёмная то прямо налету скорее всего неполучится и потому данные прийдется хранить в массиве разве что переввести их сразу в числовой вид.

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

типа многоканального реле времени которое берет настройки с карты.

вот чтото такое наверно нужно сделать как пример

int h=0;        // считываем массив входящего конфигурвционного файла
char buffer[5]; //так как в кажде данное не больше 4 цифр
int num,i=0;
configFile = SD.open("config.txt");
  if (configFile) { 
    Serial.println("configFile.txt open OK");
    char array[ConfigFile.size()];  // массив выходящих значений конфигурационного файла
    while (configFile.available()) {
      // считываем байт входящего файла
      symbol = configFile.read();
      array[h]=symbol;
      h++;  
    }
    array[h]='\0';
    configFile.close();

do
   {
      buffer=strtok(array,",");
      num  =atoi(buffer);
       outputArray[i]=num; //тут особо не обращайте внимание,остюда уже идут операции размещения считанных данных куда вам надо по массивам
       i++;
    }   
  while(buffer!=NULL);

 

b707
Offline
Зарегистрирован: 26.05.2017

alexval2007 - думаю, вам надо внимательно изучить. что такое переменные, а что - указатели. А так же разобрать, как устроены символы и строки в Си. Без этого у вас ничего не выйдет. И не надейтесь решить эту проблему в пару дней.

А то, чем вы занимаетесь сейчас - берете советы с одного форума и тащите на другой, там выдавая за свое творчество, а потом ответы со второго форума на первый - это читерство.

alexval2007
Offline
Зарегистрирован: 10.11.2012

я просто ищу варианты решения не выдавая за свое просто одно подсмотрел там другое здесь