Считывание данных с SD карты и сохранение их в виде переменных
- Войдите на сайт для отправки комментариев
Вс, 03/02/2013 - 19:28
Здравствуйте.
Есть задача, на Sd карте записан текстовый файл в котором записаны параметры которые используются в программе. Примерной вид текстового файла 10,0,20,20,1.
Код который разбивает эти данные по переменным и сохраняет их:
byte h=0; // считываем массив входящего конфигурвционного файла byte array[]={}; // массив выходящих значений конфигурационного файла configFile = SD.open("config.txt"); if (configFile) { Serial.println("configFile.txt open OK"); while (configFile.available()) { // считываем байт входящего файла symbol = configFile.read(); array[h]=symbol; h=h++; } configFile.close(); byte outputArray [] [5] ={ /// массив с выходящими значениями в который записываются побайтово цифры из конфигурвционного файла {}, {}, {}}; byte t=0; // переменная которая в массиве outputArray [t] [] переключает строки byte z=0; // переменная которая содержит значение i, используется для возвращения намера столца outputArray[t][i-z] в нулевое положение byte x=0; // определяет количество параметров которое мы задаем с SD карты. byte u=0; // количество символов считываемого значения for(int i = 0; i<=h; i++){ symbol = array[i]; if ( symbol == 44 && x == 0 ){ /// Начинаем обрабатывать первое значение из входящего массива данных // Часть кода которая отвечает за сохранение параметров которые мы считываем с SD карты u = i; // если у нас параметр состоит из двух числе if (u == 2){ SolenoidTime = outputArray[0][i-z-1]+ outputArray[0][i-z-2]*10; } // если у нас параметр состоит из трёх чисел else if (u == 3){ SolenoidTime = outputArray[0][i-z-1]+ outputArray[0][i-z-2]*10+outputArray[0][i-z-3]*100; } // если первый пареметр состоит из четырёх символов else if (u == 4){ SolenoidTime = outputArray[0][i-z-1]+ outputArray[0][i-z-2]*10+outputArray[0][i-z-3]*100+outputArray[0][i-z-4]*1000; } t = t + 1; x = 1; z = i + 1; // пееменная z сдвигает номер столбца выходного массива в ноль } else if ( symbol == 44 && x == 1){ /// Начинаем обрабатывать второе значение из входящего массива данных u = i-z; // если у нас параметр состоит из двух числе if (u == 2){ DelayTime = outputArray[1][i-z-1]+ outputArray[1][i-z-2]*10; } // если у нас параметр состоит из трёх чисел else if (u == 3){ DelayTime = outputArray[1][i-z-1]+ outputArray[1][i-z-2]*10+outputArray[1][i-z-3]*100; } // если первый пареметр состоит из четырёх символов else if (u == 4){ DelayTime = outputArray[1][i-z-1]+ outputArray[1][i-z-2]*10+outputArray[1][i-z-3]*100+outputArray[1][i-z-4]*1000; } t = t + 1; z = i + 1; x = 2; } else if ( symbol == 44 && x == 2){ /// Начинаем обрабатывать третье значение из входящего массива данных u = i-z; // если у нас параметр состоит из двух числе if (u == 2){ KerningTime = outputArray[2][i-z-1] + outputArray[2][i-z-2]*10; } // если у нас параметр состоит из трёх чисел else if (u == 3){ KerningTime = outputArray[2][i-z-1] + (outputArray[2][i-z-2]*10) + (outputArray[2][i-z-3]*100); } // если первый пареметр состоит из четырёх символов else if (u == 4){ KerningTime = outputArray[2][i-z-1] + (outputArray[2][i-z-2]*10) + (outputArray[2][i-z-3]*100) + (outputArray[2][i-z-4]*1000); } t=t+1; z=i+1;x=3; } else if ( symbol == 44 && x == 3){ /// Начинаем обрабатывать четвёртое значение из входящего массива данных u = i-z; // если у нас параметр состоит из двух числе if (u == 1){ loopcycle = outputArray[3][i-z-1]; } t=t+1; z=i+1;x=4; } else if ( symbol == 44 && x == 4){ /// Начинаем обрабатывать третье значение из входящего массива данных u = i-z; // если у нас параметр состоит из двух числе if (u == 2){ looptime = outputArray[4][i-z-1] + outputArray[4][i-z-2]*10; } // если у нас параметр состоит из трёх чисел else if (u == 3){ looptime = outputArray[4][i-z-1] + (outputArray[4][i-z-2]*10) + (outputArray[4][i-z-3]*100); } // если первый пареметр состоит из четырёх символов else if (u == 4){ looptime = outputArray[4][i-z-1] + (outputArray[4][i-z-2]*10) + (outputArray[4][i-z-3]*100) + (outputArray[4][i-z-4]*1000); } t=t+1; z=i+1;x=5; } else if ( symbol == 46 && x == 5){ /// Начинаем обрабатывать четвёртое значение из входящего массива данных u = i-z; // если у нас параметр состоит из двух числе if (u == 1){ system = outputArray[5][i-z-1]; Serial.print("sys");Serial.print(system); } t=t+1; z=i+1;x=6; } else if ( symbol == 48){ outputArray[t][i-z] = 0; } // 0 else if ( symbol == 49){ outputArray[t][i-z] = 1; } // 1 else if ( symbol == 50){ outputArray[t][i-z] = 2; } // 2 else if ( symbol == 51){ outputArray[t][i-z] = 3; } // 3 else if ( symbol == 52){ outputArray[t][i-z] = 4; } // 4 else if ( symbol == 53){ outputArray[t][i-z] = 5; } // 5 else if ( symbol == 54){ outputArray[t][i-z] = 6; } // 6 else if ( symbol == 55){ outputArray[t][i-z] = 7; } // 7 else if ( symbol == 56){ outputArray[t][i-z] = 8; } // 8 else if ( symbol == 57){ outputArray[t][i-z] = 9; } // 9 else {} // Если вводиться что-то не преднамеренное } } else { // Если файл не открылся соощаем об ошибке: Serial.println("error configFile.txt"); } Serial.print("Solenoid ");Serial.println(SolenoidTime); Serial.print("Delay "); Serial.println(DelayTime); Serial.print("Kerning "); Serial.println(KerningTime); Serial.print("Loop"); Serial.println(loopcycle); Serial.print("Loop"); Serial.println(looptime); Serial.print("font"); if (system == 0){ Serial.println("ENG"); } else if (system == 1){ Serial.println("RUS"); } else {}
Как вы видите моя программа обрабатывает побайтово входящий массив значений, определяет что за цифра скрывается за ASCII кодом, и знаки препинания разделяющие сами параметры, являются флагами и сообщают о том что один параметр закончился и начался новый.
Вопрос, как можно сделать это ещё лучше?
Возможно я не знаю, чего-то.
Как можно сократить объем используемой памяти?
так понял из кода и ваших пояснений к нему,что у вас львиная доля кода уходит на то что бы расшифровать какое значение вы считали из файла ?
советую почитать про функции strtok(); и atoi();
то есть я предлагаю вместо того что бы определять из скольких цифр состоит число и т.д. и т.п. ...считывать число из файла как массив символов,а затем сразу же переводить его в тип int и сохранять в нужный вам массив
как то примерно так,просто с SD карточками особо не заморачивался
mixail844, спасибо Вам большое за помощь. буду разбираться
Переделал код, он сйечас выглядит так:
При выполнении кода получаем:
извините,но мне ваш код, слегка выносил мозг.переписал ,как мне кажеться, более читабельно.
функция strtok() сама в себе использует фунцию strcpy(),и сама же продвивает указатель по "большому" массиву символов
Михаил, спасибо Вам большое за помощь. Разобрался.
мой финальный код, выглядит так:
Благодара Вам, код сократился в 5 раз!! Ура!
Здравствуйте.
Подскажите, а если задача похожа (есть текстовый файл, но в нем несколько строк - например 48), как считать данные из последней строки -48й, 47й, 46й итд.. или из любой строки и занести эти данные в массив? 48строк - это максимальное количество строк в файле, добавляются по мере поступления данных от датчиков. На самом деле может быть и 10 строк и 1 строка...
Данные будут записываться в массив int p_g[48];
Например: из 48 строки последняя цифра -749 p_g[0]=749;
из 47 строки последняя цифра - 748 p_g[1]=748;
из 46 p_g[2]=748;
из 45 p_g[3]=747;
файл имеет структуру:
............................
0,0,26,35,745
0,30,26,35,745
1,0,26,35,745
1,30,26,35,745
10,0,23,33,747
10,30,24,33,747
11,0,24,32,748 -46 строка
11,30,25,31,748 -47 строка
12,0,25,31,749 -48 строка
есть текстовый файл, но в нем несколько строк - например 48), как считать данные из последней строки -48й, 47й, 46й итд..
Если речь идет о файле и файловой системе - то почти всегда он читается целиком от начала, просто часть данных пропускается по определенному сценарию. Тут надо знать: каким символом заканчивается строка и по нему отсчитывать нужное количество строк, достигнув которое начинаем помещать строчки в массив переменных.
ок, идею я понял, спасибо.
Попробовал ваш код применительно своей задачи. У меня несколько строк, я подумал, что с помощью вашего кода смогу сделать массив всех своих данных, так как считываются все строчки по байтам, однако почему-то максимум что удается занести в массив outarray[t] - 40 значений. Подскажите, как исправить, чтобы заносились все данные из всех строк?
0,0,26,27,756. ----заносятся
7,0,23,30,757. ----заносятся
8,0,14,34,755. ----заносятся
8,30,20,33,755. ----заносятся
9,0,22,29,755. ----заносятся
9,30,22,30,755. ----заносятся
10,0,22,30,755. ----заносятся
10,30,23,30,755. ----заносятся
11,0,23,30,755. ---------уже не заносятся
11,30,23,30,755. ---------уже не заносятся
12,0,23,29,755. ---------уже не заносятся
Попробовал ваш код применительно своей задачи.
То, что в массив попадает всего ВОСЕМЬ строк - ни на какие мысли не наталкивает? "Переменная типа char занимает 1 байт памяти". Скорее всего отсюда и ногти растут... Объявите длину массива с запасом - и посмотрите что получится.
Здравствуйте, подскажите пожалуйста, как реализовать данный алгоритм:
Есть файл на SD-карте следующего вида:
1234567
9999999
3231321
1234123
И так далее. Т.е. набор чисел в столбик. С RFID ридера приходят данные, типа "0000000" необходимо сравнить входящее число со всеми числами из файла на флешке. Если есть совпадение, то сделать определенные действия, если нет - то другие действия.
Вся сложность сводится к тому, что не удается реализовать считывание с карты каждой строки в массив.
С уважением, Евгений. Знающих людей прошу помощи.
написал когд парсинга данных из файла на флешке
Храню данные в следующем формате
Всем привет) Четвертый день мучаюсь с кодом... Подскажите в чем ошибка.
Задача проекта: есть файл ardu.txt на флешке. В нем записи типа:
10;h
20;l
30;h
E
Числа - время в секундах включений/выключений (в данном случае светодиода на ардуино), "h" и "l" - команды (HIGH, LOW), E - символ конца файла.
Нужно включать, или выключать светодиод по времени, прописанному в файле (потом, по аналогии, добавлю еще светодиоды... пока так)
не могли бы вы помочь с моим кодом нужно считать значение из файла( последнее) ли бо же просто всегда после считования стирать, потом добавить к етому значению другое записать, и так повторять.
#include <SD.h>
02
#include <SimpleTimer.h>
03
File myFile;
04
int
timewalkcurrent=0;
05
long
int
globalruntime;
06
SimpleTimer timer2;
07
void
setup
(){
08
timer2.setInterval(1000, timerrunglobal );
09
10
{
11
Serial
.begin(9600);
12
Serial
.println(SD_CHIP_SELECT_PIN);
//53
13
Serial
.println(SPI_MOSI_PIN);
//51
14
Serial
.println(SPI_MISO_PIN);
//50
15
Serial
.println(SPI_SCK_PIN);
//52
16
while
(!
Serial
) {
17
;
18
}
19
20
void
timerrunglobal(){
21
timerrunglobal++;
22
}
23
void
refreshsd(){
24
25
pinMode(53, OUTPUT);
26
myFile = SD.open(
"time.txt"
);
27
if
(myFile) {
28
while
(myFile.available()) {
29
globalruntime=myFile.read();
30
}
31
myFile.close();
32
}
33
long
int
prof=globalruntime;
34
globalruntime=prof+timerrunglobal;
35
timerrunglobal==zero;
36
SD.remove(
"time.txt"
);
37
pinMode(53, OUTPUT);
38
myFile = SD.open(
"time.txt"
, FILE_WRITE);
39
if
(myFile) {
40
41
myFile.write(globalruntime);
42
myFile.close();
43
44
}}
45
void
loop
(
void
)
46
{
47
48
unsigned
long
currentMillis = millis();
49
if
(currentMillis - previousMillis >= interval) {
50
previousMillis = currentMillis;
51
refreshsd();
52
}
53
54
55
const
long
interval = 0; }
56
57
Serial
.println(
""
);
58
Serial
.println(globalruntime);
59
Serial
.println(
""
);
60
}
доброго времени суток...
у мения тоже самое интересуеть... помогите пожалуйста...
в тхт фаиле в ручную записанны строки пример 0123456789... нужно найдти определную строку и делат какието деиствия пример нужно искать 0123456789 и при совпадении выдат сообшения например "Ok".
для тестирования Arduino подключен теминалу и спомошю терминала ввожу 10 цифр и при совпадении выдает сообшение "Ok" при отсувствии "Error"
hard виглидить так SD Card+Arduino+Uart
я мало знаю програмировании а то не беспокоил
заранее благодаоень...