Программа плохо читает память

Моя программа не читает содержимое карты памяти, в данном случае файл "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);
}

, 👍0

Обсуждение

Вы никогда не используете содержимое файла 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


1 ответ


1

Я бы сказал, что вы не можете добавить кнопку, которая перезапускает/продолжает программу. Из-за всех delay(...) в вашем коде. Чип Arduino не может прочитать ваш ввод и вашу кнопку, пока он находится в режиме задержки и, следовательно, не считывает данные с кнопки. Подробнее о неблокирующей задержке

Вам необходимо поддерживать работу основного метода loop, чтобы процессор-микроконтроллер мог выполнять свою работу. Вместо того, чтобы ждать в цикле delay и ничего не делать.

Поэтому не используйте никаких delay, они хороши для новичков, желающих сразу начать работу с Arduino.

Без задержки

,