текстовый файл на флэшке имеет такой формат: 21.06.2015 10:00 54 21.06.2015 11:25 4 21.06.2015 12:00 19 21.06.2015 13:09 48 21.06.2015 14:50 54 и постоянно дописывается строка в конце. Не знаю как вывести строки на дисплей и что б по нажатию двух кнопок можно было вверх вниз по строчкам бегать
С нажатием кнопок достаточно просто. По нажатию кнопок увеличивать или уменьшать номер отображаемой строки или устанавливать номера первых символов отображаемых строк в тексте и выполнять отрисовку строк с установленными номерами или начинающихся с установленных первых символов. Если файл достаточно мал, то его можно вгрузить в setup() в массив строк. В этом случае при отрисовке достаточно выводить элементы из массива с соответствующими номерами (начиная с 0). При добавлении строки можно сразу после дописывания новой строки добавлять в конец массива свежезаписанную строку (тогда не придется каждый раз перечитывать файл). Если файл слишком велик для ОЗУ, то в массив можно записывать не сами строки, а номера их первых символов в файле (для чего в setup() придется пройтись по всему файлу и сохранить в массиве номера символов, следующих за парой символов перевода строки и возврата каретки). Тогда при дописывании новой строки в конец массива нужно добавлять длину файла (она же номер символа, начинающего новую строку). А при отображении строки с заданным номером придется выполнять file.seek (file - имя переменной типаFile) по позиции, хранящейся в массиве под соответствующим номером, считывать из файла до символа конца строки, отображать считанное, после чего выполнять file.seek по позиции file.size, чтобы при дописывании новой строки писать в конец файла. Можно, конечно, не мучиться с дополнительным позиционированием после считывания, а файл открывать перед началом каждой операции записи и считывания строки и закрывать сразу после операции. Но это увеличит нагрузку на карту и увеличит время считывания. Если файл слишком велик даже для массива номеров строк, то лучше использовать для позиционирования не номера строк, а номера первых символов строк. При этом придется каждый раз при нажатии кнопок пробегать по файлу в поисках начала предыдущей строки (со следующей проще, плюс длина текущей строки плюс еще 2 - символы перевода строки и возврата каретки). Для ускорения процесса можно ввести буферизацию, т.е. считывать фрагмент файла вокруг текущей позиции в нем, чтобы часть работы по поиску проводилась в памяти.
так, как проставить нумерацию понял Код (Text): if(outoffbt == HIGH){ while(var < 365){ myFile = SD.open("test.txt", FILE_WRITE); if (myFile) { Serial.print("Writing to test.txt..."); myFile.print(var); myFile.print(rtc.getDateStr()); myFile.print(" "); myFile.print(rtc.getTimeStr()); myFile.print(" "); myFile.println(obsh_nastrel); myFile.close(); Serial.println("done."); } else { // if the file didn't open, print an error: Serial.println("Error writing"); } var++; } не могли бы подсказать дольше как бегать по строчкам при помощи кнопок
Набросаю примерную схему программы для второго случая. Даже не схему, а что-то вроде отдаленно похожего на наброски к написанному. Код (Text): // объявление массива начал строк #define MAX_STRS 365 int filestrs [MAX_STRS]; // резервируем целых 730 байт. Нужно смотреть за расходом ОЗУ. int firststr=0; // номер первой строки на дисплее int lastfilestr=0 // количество строк в файле ...... // Заимствовано, заполнение файла. // Что такое obsh_nastrel? Почему не меняется? // Предполагается, что файл при этом создается, а не дописывается. if(outoffbt == HIGH){ while(var < MAX_STRS){ myFile = SD.open("test.txt", FILE_WRITE); if (myFile) { Serial.print("Writing to test.txt..."); filestrs[lastfilestr]=myFile.position(); myFile.print(rtc.getDateStr()); myFile.print(" "); myFile.print(rtc.getTimeStr()); myFile.print(" "); myFile.println(obsh_nastrel); lastfilestr++; myFile.close(); Serial.println("done."); } else { // if the file didn't open, print an error: Serial.println("Error writing"); } var++; } } // где-то в loop() // отображаем две строки файла myFile = SD.open("test.txt"); if (myfile) { myfile.seek(filestrs[firststr]); char tmpstr[20]; char tmpstrlen=0; while (myfile.available()) { // читаем первую строку tmpstr[tmpstrlen]=myfile.read(); if ((tmpstr[tmpstrlen]=='\n')||(tmpstr[tmpstrlen]=='\r')) break; tmpstrlen++; } lcd.setCursor(0,0); lcd.print(tmpstr); tmpstrlen[tmpstrlen]=0; while (myfile.available()) { // гоним до следующей строки, пока не пропустим все переводы строки char ch=myfile.read(); if ((ch!='\n')&&(ch!='\r')) break; } tmpstrlen=0; while (myfile.available()) {// читаем вторую строку tmpstr[tmpstrlen]=myfile.read(); if ((tmpstr[tmpstrlen]=='\n')||(tmpstr[tmpstrlen]=='\r')) break; tmpstrlen++; } tmpstrlen[tmpstrlen]=0; lcd.setCursor(0,1); lcd.print(tmpstr); myFile.close(); } // обрабатываем кнопки if (нажата кнопка вверх) { if (firststr>0) firststr--; } if (нажата кнопка вниз) { if (firststr<MAX_STRS-1) firststr++; // если уже стоим на предпоследней строке, дальше двигаться нельзя. }
Немного подогнал под себя Код (Text): #include <Wire.h> #include <LiquidCrystal.h> #include <SD.h> LiquidCrystal lcd(12, 11, 5, 4, 3, 2); File myFile; int podacha10bt1 = 36; int podacha1bt1 = 37; int output; int output2; #define MAX_STRS 365 int filestrs [MAX_STRS]; // резервируем целых 730 байт. Нужно смотреть за расходом ОЗУ. int firststr=0; // номер первой строки на дисплее int lastfilestr=0; // количество строк в файле void setup() { Serial.begin(9600); pinMode(podacha10bt1, INPUT); pinMode(podacha1bt1, INPUT); pinMode(10, OUTPUT); lcd.begin(20, 4); delay(100); if (!SD.begin(10)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); } void loop() { output = digitalRead(podacha10bt1); output2 = digitalRead(podacha1bt1); delay(10); myFile = SD.open("test.txt"); if (myFile) { myFile.seek(filestrs[firststr]); char tmpstr[20]; char tmpstrlen=0; while (myFile.available()) { // читаем первую строку tmpstr[tmpstrlen]=myFile.read(); if ((tmpstr[tmpstrlen]=='\n')||(tmpstr[tmpstrlen]=='\r')) break; tmpstrlen++; } lcd.setCursor(0,0); lcd.print(tmpstr); tmpstr[tmpstrlen]=0; while (myFile.available()) { // гоним до следующей строки, пока не пропустим все переводы строки char ch=myFile.read(); if ((ch!='\n')&&(ch!='\r')) break; } tmpstrlen=0; while (myFile.available()) {// читаем вторую строку tmpstr[tmpstrlen]=myFile.read(); if ((tmpstr[tmpstrlen]=='\n')||(tmpstr[tmpstrlen]=='\r')) break; tmpstrlen++; } tmpstr[tmpstrlen]=0; lcd.setCursor(0,1); lcd.print(tmpstr); lcd.setCursor(0,2); lcd.print(tmpstr); tmpstr[tmpstrlen]=0; while (myFile.available()) { // гоним до следующей строки, пока не пропустим все переводы строки char ch=myFile.read(); if ((ch!='\n')&&(ch!='\r')) break; } tmpstrlen=0; while (myFile.available()) {// читаем вторую строку tmpstr[tmpstrlen]=myFile.read(); if ((tmpstr[tmpstrlen]=='\n')||(tmpstr[tmpstrlen]=='\r')) break; tmpstrlen++; } tmpstr[tmpstrlen]=0; lcd.setCursor(0,3); lcd.print(tmpstr); myFile.close(); } // обрабатываем кнопки if (output == HIGH) { if (firststr>0) firststr--; } if (output2 == HIGH) { if (firststr<MAX_STRS-1) firststr++; // если уже стоим на предпоследней строке, дальше двигаться нельзя. } } На всех четырех строчках дисплея отображается только первая строка из текстового файла, кнопки не работают. Что нужно подправить???? Помогите пожалуйста
всем спасибо за помощь. Вроде разобрался. Возможно комуто потом понадобится, вот код: Код (Text): #include <DS1302.h> #include <Wire.h> #include <LiquidCrystal.h> #include <SD.h> DS1302 rtc(22, 24, 26); // (RST, DAT, CLK) LiquidCrystal lcd(12, 11, 5, 4, 3, 2); Time t; File myFile; int podacha10bt1 = 36; int podacha1bt1 = 37; int kurok1 = 38; int readbt1 = 39; int Recflag=0; int output; int output2; int output3; int readbtstate; #define MAX_STRS 100 int filestrs [MAX_STRS]; // резервируем целых 730 байт. Нужно смотреть за расходом ОЗУ. int firststr=0; // номер первой строки на дисплее int lastfilestr=0; // количество строк в файле int var = 0; void setup() { Serial.begin(9600); pinMode(podacha10bt1, INPUT); pinMode(podacha1bt1, INPUT); pinMode(kurok1, INPUT); pinMode(readbt1, INPUT); pinMode(10, OUTPUT); lcd.begin(20, 4); delay(100); if (!SD.begin(10)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); } void loop() { output = digitalRead(podacha10bt1); output2 = digitalRead(podacha1bt1); output3 = digitalRead(kurok1); readbtstate = digitalRead(readbt1); delay(10); t = rtc.getTime(); if(output3 == LOW && var < MAX_STRS && Recflag==0) { Recflag=1; } if(output3 == HIGH && var < MAX_STRS && Recflag==1){ lcd.setCursor(0,1); lcd.print("Record........"); myFile = SD.open("test6.txt", FILE_WRITE); if (myFile) { Serial.print("Writing to test3.txt..."); filestrs[var]=myFile.position(); myFile.print(var); myFile.print(" "); // myFile.print(rtc.getDateStr()); myFile.println(rtc.getTimeStr()); //delay (2000); var++; myFile.close(); Serial.println("done."); lcd.clear(); Recflag=0; } else { // if the file didn't open, print an error: Serial.println("Error writing"); } } if(readbtstate == HIGH){ myFile = SD.open("test6.txt"); if (myFile) { myFile.seek(filestrs[firststr]); char tmpstr[20]; char tmpstrlen=0; while (myFile.available()) { // читаем первую строку tmpstr[tmpstrlen]=myFile.read(); if ((tmpstr[tmpstrlen]=='\n')||(tmpstr[tmpstrlen]=='\r')) break; tmpstrlen++; } lcd.setCursor(0,0); lcd.print(tmpstr); lcd.print(" "); tmpstr[tmpstrlen]=0; while (myFile.available()) { // гоним до следующей строки, пока не пропустим все переводы строки char ch=myFile.read(); if ((ch!='\n')&&(ch!='\r')) break; } tmpstrlen=0; while (myFile.available()) {// читаем вторую строку tmpstr[tmpstrlen]=myFile.read(); if ((tmpstr[tmpstrlen]=='\n')||(tmpstr[tmpstrlen]=='\r')) break; tmpstrlen++; } tmpstr[tmpstrlen]=0; lcd.setCursor(0,1); lcd.print(tmpstr); lcd.print(" "); myFile.close(); } // обрабатываем кнопки if (output == HIGH) { if (firststr>0) firststr--; } if (output2 == HIGH) { if (firststr<MAX_STRS-1) firststr++; // если уже стоим на предпоследней строке, дальше двигаться нельзя. } } else{ lcd.clear(); lcd.setCursor(0,1); lcd.print("WAITING........"); } }