Программа плохо читает память
Моя программа не читает содержимое карты памяти, в данном случае файл "objects.txt". Я хотел сделать следующее: программа считывает объекты, содержащиеся в текстовом файле, и выделяет таблицу, а затем упорядочивает ее в алфавитном порядке.
Что-то ускользает от меня. Другое дело, как поставить функцию, распознающую, что пользователь нажал кнопку и при нажатии программа продолжает работу?
#include <LiquidCrystal.h>
#include <SPI.h>
#include <SD.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
// определяем некоторые значения, используемые панелью и кнопками
int lcd_key = 0;
int adc_key_in = 0;
int x = 0;
String files, memo, memo1;
int sizef = 0;
int sizef1 = 0;
int sizef2 = 0;
int y = 0;
int z = 0;
struct objeto_celeste_s {
char nome[20];
float ar;
float dec;
};
typedef struct objeto_celeste_s objeto_celeste;
char * tab1 [6];
int myCompareFunction (const void * arg1, const void * arg2) {
return strcmp (*(char **) arg1, *(char **) arg2);
}
File root;
File file;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
char * list[] = {"1.Modo Normal ", "2.Modo Teste ", "3.Modo GoTo ", "4.Modo Manual "};
// читаем кнопки
int read_LCD_buttons() {
adc_key_in = analogRead(0);
if (adc_key_in > 1000) return btnNONE;
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 250) return btnUP;
if (adc_key_in < 400) return btnDOWN;
if (adc_key_in < 450) return btnLEFT;
if (adc_key_in < 650) return btnSELECT;
return btnNONE; // когда все остальные терпят неудачу, возвращаем это...
}
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
while (!Serial) {
; // ждем подключения последовательного порта. Требуется только для собственного порта USB
}
Serial.println ("Welcome!");
Serial.println ("Selecione um modo no lcd.");
lcd.begin (16, 2);
lcd.setCursor (0, 0);
lcd.print (" Selecione um");
lcd.setCursor (0, 1);
lcd.print (" modo ");
delay (1000);
lcd.clear ();
lcd.setCursor(0, 0);
lcd.print(">");
lcd.println(list[0]);
lcd.setCursor(0, 1);
lcd.print (" ");
lcd.println(list[1]);
if (!SD.begin(4)) {
Serial.println("initialization failed!");
while (1);
}
}
void loop() {
lcd_key = read_LCD_buttons(); // читаем кнопки
switch (lcd_key) {
// в зависимости от того, какая кнопка была нажата, выполняем действие
case btnRIGHT:
break;
case btnLEFT:
break;
case btnUP:
if (x == 1) {
x--;
lcd.clear ();
lcd.setCursor(0, 0);
lcd.print(">");
lcd.println(list[0]);
lcd.setCursor(0, 1);
lcd.print (" ");
lcd.println(list[1]);
}
break;
if (x == 3) {
x--;
lcd.clear ();
lcd.setCursor(0, 0);
lcd.print(">");
lcd.println(list[2]);
lcd.setCursor(0, 1);
lcd.print (" ");
lcd.println(list[3]);
}
break;
case btnDOWN:
if (x == 0) {
x++;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(">");
lcd.println(list[1]);
lcd.setCursor(0, 1);
lcd.println(" ");
}
break;
if (x == 2) {
x++;
lcd.clear ();
lcd.setCursor(0, 0);
lcd.print(">");
lcd.println(list[3]);
lcd.setCursor(0, 1);
lcd.println(" ");
}
break;
case btnSELECT:
if (x == 0) {
lcd.clear ();
lcd.print ("Modo Normal");
Serial.println ("Selecionou o modo normal!");
delay (1000);
if (SD.exists("objectos.txt")) {
Serial.println("O ficheiro 'objetos' foi encontrado!");
lcd.clear ();
lcd.setCursor (0, 0);
lcd.print ("Modo Normal");
delay (1000);
file = SD.open("objectos.txt", FILE_READ);
if (file) {
while (file.available()) {
String line = file.readStringUntil('\n');
sizef++;
}
} else {
//если произошла ошибка при открытии файла
Serial.println("Erro a abrir o ficheiro 'objectos.txt'.");
}
objeto_celeste *tab = (objeto_celeste *)malloc((sizef) * sizeof(objeto_celeste));
Serial.print ("Contados ");
Serial.print (sizef);
Serial.println (" objetos no ficheiro objectos.txt.");
if (tab == NULL) {
lcd.clear ();
lcd.print ("Erro a alocar memoria");
Serial.println ("Erro a alocar memória");
while (1) { };
} else {
Serial.print ("Memória alocada para ");
Serial.print (sizef);
Serial.println (" objectos.");
lcd.setCursor (0, 1);
lcd.print ("Alocados ");
lcd.print (sizef);
lcd.print (" obj");
}
file.close();
char * line1 = (char*) malloc(15);
file = SD.open("objectos.txt", FILE_READ);
if (file) {
Serial.println ("Carregando informação para a memória:");
while (file.available()) {
if (file.read() == '\n') {
char * justafun = strtok (line1, " "); // разделяем токены
while (justafun != NULL) {
if (y == 0) {
strcpy (tab[sizef2].nome, justafun);
Serial.print ("[");
Serial.print (sizef2);
Serial.print ("] ");
Serial.print(tab[sizef2].nome);
Serial.print (" ");
y++;
}
if (y == 1) {
tab[sizef2].ar = atof (justafun);
Serial.print (tab[sizef2].ar);
Serial.print (" ");
y++;
}
if (y == 2) {
tab[sizef2].dec = atof (justafun);
Serial.println (tab[sizef2].dec);
sizef2++;
y = 0;
}
justafun = strtok (NULL, " ");
}
}
}
}
file.close ();
delay (1500);
lcd.clear ();
Serial.println ("Proceda ao alinhamento manual do telescópio.");
lcd.setCursor (0, 0);
lcd.print ("Proceda ao ");
lcd.setCursor (0, 1);
lcd.print ("Alinhamento man.");
Serial.println ("Depois de o alinhamento estar concluido, pressione o botão Select para prosseguir o programa.");
//поместите сюда функцию, чтобы распознавать нажатие кнопки выбора
if (Serial1.available()) {
int inByte = "V"; //Если выравнивание завершено, 0 — нет, 1 — да
Serial1.write (inByte);
}
while (!Serial1) {
if (Serial1.available()) {
int inByte = "V";
Serial1.write (inByte);
int inByte1 = "e";
Serial1.write (inByte1);
}
}
delay (1000);
Serial.println ("Tabela ordenada alfabeticamente:");
qsort (tab->nome, sizef, sizeof (char *), myCompareFunction);
for (int i = 0; i < sizef; i++)
Serial.println (tab[i].nome);
delay (1000);
lcd.clear ();
lcd.print ("Carregue Select");
lcd.setCursor (0, 1);
lcd.print ("Para modo manual");
Serial.println ("Carregue em Select para ir para o modo manual e assim continuar com o programa.");
} else {
Serial.println ("O ficheiro 'objetos' não existe.");
lcd.clear ();
lcd.print ("Erro nao encontrado");
delay (2000);
while (1) { };
}
}
if (x == 1) {
lcd.clear ();
lcd.print ("Modo Teste");
Serial.println ("Selecionou o modo teste!");
delay (2000);
if (SD.exists("teste.txt")) {
Serial.println("O ficheiro 'teste.txt' foi encontrado!");
lcd.clear ();
lcd.setCursor (0, 0);
lcd.print ("Modo Teste");
lcd.setCursor (0, 1);
lcd.print ("Ficheiro encontrado");
delay (2000);
file = SD.open("teste.txt", FILE_READ);
if (file) {
while (file.available()) {//прочитать файл
String line = file.readStringUntil('\n');
sizef++;
}
files = "Contados " + String (sizef) + " objetos no ficheiro teste.txt.";
Serial.println (files);
objeto_celeste *tab = (objeto_celeste *)malloc((sizef) * sizeof(objeto_celeste));
memo = "Alocados " + String (sizef) + " obj ";
memo1 = "Memória alocada para " + String (sizef) + " objetos.";
if (tab == NULL) {
lcd.clear ();
lcd.print ("Erro alocar memoria");
Serial.println ("Erro a alocar memória");
while (1) { };
} else {
Serial.println (memo1);
lcd.setCursor (0, 1);
lcd.print (memo);
}
file.close();
} else {
//если произошла ошибка при открытии файла
Serial.println("Erro a abrir o ficheiro 'teste.txt'.");
}
} else {
Serial.println ("O ficheiro 'teste.txt' não foi encontrado.");
lcd.clear ();
lcd.print ("Erro nao encontrado");
delay (2000);
while (1) { };
}
}
break;
case btnNONE:
break;
}
delay (200);
}
@1manonearth, 👍0
Обсуждение1 ответ
Я бы сказал, что вы не можете добавить кнопку, которая перезапускает/продолжает программу. Из-за всех delay(...)
в вашем коде. Чип Arduino не может прочитать ваш ввод и вашу кнопку, пока он находится в режиме задержки и, следовательно, не считывает данные с кнопки. Подробнее о неблокирующей задержке
Вам необходимо поддерживать работу основного метода loop
, чтобы процессор-микроконтроллер мог выполнять свою работу. Вместо того, чтобы ждать в цикле delay
и ничего не делать.
Поэтому не используйте никаких delay
, они хороши для новичков, желающих сразу начать работу с Arduino.
- Как объявить массив переменного размера (глобально)
- Программирование Arduino с использованием Python, а не C/C ++
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Как справиться с rollover millis()?
- Является ли использование malloc() и free() действительно плохой идеей для Arduino?
- Можно ли сделать несколько функций loop() с помощью Arduino Uno?
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- устаревшее преобразование из строковой константы в 'char*'
Вы никогда не используете содержимое файла Objects.txt. при первом чтении вы считаете только строки в файле, а во втором цикле чтения вы только что-то делаете, когда читается новая строка, и ничего больше, @chrisl
Спасибо, а что мне делать во втором чтении?, @1manonearth
Как насчет того, чтобы прочитать строки, которые вы посчитали ранее, а затем извлечь из них нужные вам данные?, @chrisl
Как мне это сделать? :/, @1manonearth
Считайте байты в буфер с помощью функции read(), а затем используйте данные. Поскольку вы не описали, какие данные у вас в файле, мы не можем вам помочь в этом., @chrisl
Как получилось, что у вас есть большая программа с двумя циклами чтения из файла, но вы не знаете, как читать файл? Это действительно ваш код?, @chrisl
Да, это мой код. Мои данные: «имя ar координаты dec координаты», например: Alnitak 05ч40м45.5с -01°56'34", @1manonearth
Мой английский недостаточно хорош, Крисл. Но да, я знаю, как читать файл, конечно!, @1manonearth
В первом цикле я хочу знать, сколько строк текста у меня есть, поэтому я делаю цикл и контейнер для цикла увеличения цикла, во втором цикле я хочу разделить строки даты на токены и сохранить этот токен на соответствующей вкладке., @1manonearth
@1manonearth, у твоего кода очень плохие отступы. ... по большей части это просто кусок текста... сложно следить за ходом программы из-за того, как она есть. ... его необходимо переформатировать, прежде чем его можно будет просмотреть.... у большинства людей нет времени форматировать ваш код, чтобы его можно было отлаживать.... вы можете получить хороший ответ, если потратите некоторое время и очистите его. свой код, @jsotola
вот пример правильно отформатированного кода... https://arduinoprosto.ru/q/51944/sending-data-from-webserver-to-arduino, @jsotola