Нужна помощь по работе с sd,rfid,nano

Тема в разделе "Закажу проект", создана пользователем ANTISPAM, 8 окт 2021.

Метки:
  1. ANTISPAM

    ANTISPAM Нуб

    Всем привет, делаю дипломный проект в котором нужно реализовать пропуск по номеру телефона и RFID меткам, с записью лог файла на флешку. Исходя из того, что памяти маловато, решено было GSM номера и RFID хранить в файлах на флешке. Логика работы GSM такая: если приходит звонок, берем номер, сравниваем с номерами из файла, если есть, то открываем и пишем в лог, если нет, то тупо сброс вызова. Логика работы RFID: при запуске из файла в переменную записывается ID мастер-карты, далее если подносится метка, происходит чтение ID и сравнение с имеющимися в файле. Но при окончательном тесте столкнулся с проблемой, если подносить метки (не мастер), то как у меня происходит после 13-ого раза ID карты считывается, но проверка в файле не происходит. Мастер метку если подносить, то все работает замечательно( я так понимаю это из-за того, что она в переменной висит). Кто с таким сталкивался или имеет какие-то мысли в какую сторону капать.
    Код прилагается.
     

    Вложения:

  2. ANTISPAM

    ANTISPAM Нуб

    Код прилагается.
    Код (C++):
    #include <SoftwareSerial.h>
    #include <SPI.h>
    #include <MFRC522.h>
    #include <SD.h>
    #include<iarduino_RTC.h>
    #define PIN_RELEY 6                         //порт реле1 D6
    #define PIN_RELEY2 7                        //порт реле2 D7
    #define RST_PIN 9                           //RST RFID
    #define SS1_PIN 10                          //SS1 RFID
    #define SS2_PIN 8                           //SS2 SD
    #define ERR_PIN 5                           //LED ERROR D5
    int LED_OK = A1;                            //LED OK
    SoftwareSerial mySerial(2, 3);              //RX D3, TX D2 для GSM
    uint8_t tonePin = 4;                        //порт пищалки D4
    String num = "";                            //переменная для номера при вызове
    String MASTER = "";                         //мастер RFID
    String st = "";                             //RFID метка из файла, GSM номер из файла
    String ID = "";                             //считаная RFID
    iarduino_RTC time(RTC_DS1302, A0, A2, A3);  //RST,CLK,DAT порты для модуля времени
    File LIST;
    MFRC522 mfrc522(SS1_PIN, RST_PIN);          //Create MFRC522 instance
    void setup() {                              //настройка портов
      Serial.begin(9600);
      pinMode(tonePin, OUTPUT);
      pinMode(PIN_RELEY, OUTPUT);
      pinMode(PIN_RELEY2, OUTPUT);
      pinMode(ERR_PIN, OUTPUT);
      pinMode(13, OUTPUT);
      pinMode(LED_OK, OUTPUT);
      pinMode(A4, INPUT_PULLUP);
      pinMode(SS1_PIN, OUTPUT);
      pinMode(SS2_PIN, OUTPUT);
      digitalWrite(SS1_PIN, HIGH);
      digitalWrite(SS2_PIN, HIGH);
      digitalWrite(PIN_RELEY, HIGH);
      digitalWrite(PIN_RELEY2, HIGH);
      time.begin();                             //инициализация модуля времени
      mySerial.begin(19200);                    //подключаем порт модема (при других скоростях не отвечает)
      mySerial.println(F("AT+CLIP=1"));            //включаем АОН
      delay(600);
      Serial.println(F("SD_RFID_R_FIL_DIPLOM_V4.r1"));
      Serial.println(time.gettime(F("d-m-Y H:i:s;")));
      delay(30);
      Start();
      delay(800);
      InitSD();                                 //инициализация SD
      R_MASTER();                               //чтение файла SET
    }
    void ERROR_BEEP() {                         //сигнал ошибки
      tone(tonePin, 600);
      delay(500);
      noTone(tonePin);
    }
    void Start() {                              //сигнал старта модуля
      tone(tonePin, 630);
      delay(100);
      noTone(tonePin);
    }
    void rele() {                               //реле для открытия 1
      digitalWrite(PIN_RELEY, LOW);
      delay(800);
      digitalWrite(PIN_RELEY, HIGH);
      delay(100);
    }
    void rele2() {                              //реле для открытия 2
      digitalWrite(PIN_RELEY2, LOW);
      delay(800);
      digitalWrite(PIN_RELEY2, HIGH);
      delay(100);
    }
    void open_beep() {                          //сигнал открытия замка
      tone(tonePin, 630);
      delay(100);
      noTone(tonePin);
      delay(100);
      tone(tonePin, 630);
      delay(100);
      noTone(tonePin);
    }
    void R_MASTER() {                           //чтение SET
      digitalWrite(SS1_PIN, HIGH);
      digitalWrite(SS2_PIN, LOW);
      String st = F("");                          //переменная для строки
      char ch = "";                            //переменная для символа
      LIST = SD.open(F("SET.txt"));               //читаем файл
      if (LIST) {
        while (LIST.available()) {
          ch = (char)LIST.read();
          if (ch == ';') {
            MASTER = st;                       //вносим собранную строку в массив
          } else {
            st = st + ch;                      //собираем строку
            ch = "";                           //очищаем для дальнейшей работы
          }
        }
      }
      LIST.close();
      digitalWrite(SS1_PIN, HIGH);
      digitalWrite(SS2_PIN, HIGH);
    }
    void InitSD() {                             //инициализация SD
    initsd:;
      digitalWrite(SS1_PIN, HIGH);
      digitalWrite(SS2_PIN, LOW);
      if (!SD.begin(SS2_PIN)) {
        digitalWrite(ERR_PIN, HIGH);
        analogWrite(LED_OK, 0);
        ERROR_BEEP();
        goto initsd;
      } else {
        digitalWrite(SS1_PIN, HIGH);
        digitalWrite(SS2_PIN, HIGH);
        digitalWrite(ERR_PIN, LOW);
        analogWrite(LED_OK, 255);
      }
    }
    void IDRFID() {                             //чтение RFID метки
      digitalWrite(SS1_PIN, LOW);
      digitalWrite(SS2_PIN, HIGH);
      digitalWrite(RST_PIN, LOW);         //костыль
      SPI.begin();
      mfrc522.PCD_Init();
      if ( ! mfrc522.PICC_IsNewCardPresent())  //ожидание метки
        return;
      if (! mfrc522.PICC_ReadCardSerial())     //считывание ID
        return;
      for (byte i = 0; i < mfrc522.uid.size; i++) {
        ID = ID + String(mfrc522.uid.uidByte[i], HEX);
      }
      digitalWrite(SS1_PIN, HIGH);
      digitalWrite(SS2_PIN, HIGH);
      digitalWrite(RST_PIN, HIGH);         //костыль
      DETECTED();
      delay(2000);
    }
    void DETECTED () {                          //проверка меток
      Serial.println(ID);
      st = "";
      if (MASTER.equals(ID) == true) {         //если мастер KEY
        if (analogRead(4) < 500) {
          Start();
          analogWrite(LED_OK, 0);
          delay(300);
          //   Serial.println(F("Запись новой RFID"));    //для теста
          ADD_KEY();
          goto br;
        }
        W_LOG();
        open_beep();
        rele();
        delay(10);
        ID = "";
        goto br;
      } else {                                 //если не мастер KEY
        digitalWrite(SS1_PIN, HIGH);
        digitalWrite(SS2_PIN, LOW);
        char ch = "";
        LIST = SD.open(F("RFID.txt"), FILE_READ);
        if (LIST) {
          while (LIST.available()) {
            ch = (char)LIST.read();
            if (ch == ';') {
              if (ID.equals(st) == true) {
                Serial.println(st);
                W_LOG();
                open_beep();
                rele();
                delay(10);
                ID = "";
                st = "";
                goto br;
              }
              st = "";
            } else {
              st = st + ch;
              ch = "";
            }
          }
          LIST.close();
        }
        else {
          Serial.println("ERROR OPEN FILES");
          LIST.close();
        }
      }
    br:;
      ID = "";
      st = "";
      digitalWrite(SS1_PIN, HIGH);
      digitalWrite(SS2_PIN, HIGH);
    }
    void ADD_KEY() {                            //добавление метки
      ID = "" ;
      delay(5000);                               //задержка для поднесения новой метки
      if ( ! mfrc522.PICC_IsNewCardPresent()) {  //ожидание метки
        goto au;
      } else {
        if (! mfrc522.PICC_ReadCardSerial())      //считывание ID
          return;
        for (byte i = 0; i < mfrc522.uid.size; i++) {
          ID = ID + String(mfrc522.uid.uidByte[i], HEX);
        }
        Start();
        digitalWrite(SS1_PIN, HIGH);
        digitalWrite(SS2_PIN, LOW);
        LIST = SD.open(F("RFID.txt"), FILE_WRITE);
        if (LIST) {
          LIST.print(ID);
          LIST.print(F(";"));
        }
        LIST.close();
        ID = "" ;
      }
    au:;
      digitalWrite(SS1_PIN, HIGH);
      digitalWrite(SS2_PIN, HIGH);
      delay(50);
      open_beep();
      analogWrite(LED_OK, 255);
    }
    void W_LOG() {                              //запись лога
      digitalWrite(SS1_PIN, HIGH);
      digitalWrite(SS2_PIN, LOW);
      LIST = SD.open(F("LOG.txt"), FILE_WRITE);
      if (LIST) {
        LIST.print(time.gettime(F("d/m/Y; H:i:s")));
        LIST.print(F(" "));
        LIST.println(ID);
      }
      LIST.close();
    }
    void GSM_PING() {                           //ожидание и проверка данных от GSM
      uint8_t ch = 0;                          //переменная для GSM
      String val = F("");                         //переменная для данных GSM
      st = "";
      if (mySerial.available()) {              //есть данные от GSM модуля
        delay(500);                            //выждем, чтобы строка успела попасть в порт целиком раньше чем будет считана
        while (mySerial.available()) {         //сохраняем входную строку в переменную val
          ch = mySerial.read();
          val += char(ch);
          delay(10);
        }
        if (val.indexOf(F("RING")) > -1) {        //если обнаружен звонк "RING"
          num = val.substring(18, 30);
          digitalWrite(SS1_PIN, HIGH);
          digitalWrite(SS2_PIN, LOW);
          LIST = SD.open(F("REG_NUM.txt"));       //проверка записей в REG_NUM.txt
          if (LIST) {
            while (LIST.available()) {
              ch = (char)LIST.read();
              if (ch == ';') {
                if (ID.equals(num) == true) {
                  W_LOG();
                  rele2();
                  open_beep();
                  delay(10);
                  num = "";
                  st = "";
                  goto brg;
                }
                st = "";
              } else {
                st = st + ch;
                ch = "";
              }
            }
          }
          LIST.close();
    brg:;
          mySerial.println(F("ATH0"));
          delay(50);
          val = "";
          num = "";
          digitalWrite(SS1_PIN, HIGH);
          digitalWrite(SS2_PIN, HIGH);
        }
      }
    }
    void loop() {
      if (Serial.available() > 0) {
        byte pas;                               //переменная для работы серийным портом
        char cp = "";
        int sek, minut, chas, den, mes, god, den_ned;
        pas = Serial.read();
        String port = F("");
        if (pas == '9') {
          if (Serial.available() > 0) {
            port = Serial.readStringUntil(';');         //переменная для установки даты и времени
            sek = port.substring(0, 2).toInt();
            minut = port.substring(2, 4).toInt();
            chas = port.substring(4, 6).toInt();
            den = port.substring(6, 8).toInt();
            mes = port.substring(8, 10).toInt();
            god = port.substring(10, 12).toInt();
            den_ned = port.substring(12, 13).toInt();
            time.settime(sek, minut, chas, den, mes, god, den_ned);  //настройка времени и даты
            //(сек,мин,час, день, мес, год, номер дня недели)
            Serial.println(F("Время и дата установлены!"));
            Serial.print(F("Текущее время и дата: "));
            Serial.println(time.gettime(F("d-m-Y, H:i:s, D;")));
          }
          goto ext;
        }
      }
    ext:;
      IDRFID();
      delay(10);
      GSM_PING();
      delay(50);
      InitSD();
    }
     
  3. Kakmyc

    Kakmyc Нерд

    В смысле мало места ?
    Вам сколько записей то надо ?
    Во флеш 328ой можно тысяч пять напихать номеров телефона, и останется ещё под программу 12кб.
    Если этого мало , возьмите 2560, туда влезет тысяч 60, номеров.
    А вот скорость проверки базы, хранящейся на sd будет унылая.
    В качестве хранилища логов ещё подойдёт, но не в качестве хранения базы номеров.
     
    Последнее редактирование: 10 окт 2021
  4. ANTISPAM

    ANTISPAM Нуб

    У меня программа занимает 26500 и 830 динамической, скорость не сильно важна, эта прошивка будет работать как система пропуска на территорию.
    Дело в том, что номера записываешь на флешку, вот и всё обновление, а так каждый раз прошиваться нужно.
     
  5. b707

    b707 Гуру

    код просто кровь из глаз. Куча повторов, невероятное число делеев, переходы по метке. Есди бы этот г-код работал, я бы очень удивился.
    Вы сами-то в нем хоть что-то понимаете?

    Вот такую инициализацию строки вам кто показал?
    Код (C++):
    String port = F("");
    Можете своими словами прокомментировать, к чему тут F() ?
     
    DetSimen нравится это.
  6. ANTISPAM

    ANTISPAM Нуб

    На форуме наткнулся, когда искал как сэкономить динамическую память.
    F() это для того что бы переменная записывалась в постоянную память при компиляции , а не в динамическую. Код писал сам, поэтому такой и «корявый», я не великий спец в ардуино. Да, код я этот замечательно, читаю, у меня проблема при обращении к флешке при проверке меток из файла (функция DETECTED), при многократном циклическом обращении к файлу, перестаёт видеть файл, но флешку при этом замечательно видит, после перезагрузки всё повторяется.
     
  7. b707

    b707 Гуру

    вы в этой фразе противоречия не замечаете?
    Если _переменную_ записать в _постоянную_ память - она перестанет быть переменной, а станет константой - то есть ее нельзя будет изменить.
    А запись F(""); - это бред вдвойне, потому что двойными кавычками обозначается пустая строка. Что вы собрались сохранять в "постоянной памяти" - пустое место? И еще и заботитесь, чтобы это пустое место поменьше места занимало :)))
    Поэтому я и спрашиваю, много ли вы в этом коде понимаете, когда вижу в нем такие строки

    .
    рад за вас. Не могу сказать того же про себя., я в этом коде ничего не понимаю. Так что помочь вам не смогу.
     
    issaom нравится это.
  8. ANTISPAM

    ANTISPAM Нуб

    Прошу прощения я не правильно выразился, и вот нашёл, где я это подсмотрел https://alexgyver.ru/lessons/code-optimisation/#Использовать_F_макро
     
  9. ANTISPAM

    ANTISPAM Нуб

    И мне интересно как вы из файла напихаете столько намеров?
     
  10. SergeiL

    SergeiL Оракул Модератор

    Ну там то говорится не о пустой строке. А у вас пустая строка. Смысл?
    Да и дальше ошибка:
    Код (C++):
    char ch = "";
    char сh - переменная байтовая.
    Зачем вы в нее адрес пустой строки записываете?
    Вы включите Compiler warnings: ALL, и вас завалит варнингами от вашего кода.
    Включается здесь:

    upload_2021-10-15_22-11-47.png

    А каждый варнинг - звоночек, что-то тут не так.
    После метки <;> ставить не нужно, но оптимизатор это выкидывает.
     
  11. parovoZZ

    parovoZZ Гуру

    был случай, когда из-за варнинга компилятором выкидывался целый кусок кода и программа в целом работала криво.
     
    SergeiL нравится это.
  12. SergeiL

    SergeiL Оракул Модератор

    Нужно разбираться с каждым варнингом, не зря он появляется.
    Я обычно их внимательно смотрю, и убираю прямым преобразованием, если так и задумано.
     
    DetSimen нравится это.
  13. ANTISPAM

    ANTISPAM Нуб

    Этот код у меня работает, при компиляции проблем нет, проблема только при работе, несколько раз файл для работы открывается, но через несколько циклов перестаёт открываться…
     
  14. SergeiL

    SergeiL Оракул Модератор

    Так и будет, если есть ошибки с размерами буферов, некорректными типами и т.д.

    Вы возьмите пример с ардуино.сс там записывается текст в файл на SD карту, потом один раз читается и кидается в монитор порта.
    В loop() там ничего нет, а я скопировал чтение из файла в loop() и добавил delay(2000); в конце.
    SS пин указал как у вас.

    Вот код:
    Код (C++):
    /*
      SD card read/write

      This example shows how to read and write data to and from an SD card file
      The circuit:
       SD card attached to SPI bus as follows:
    ** MOSI - pin 11
    ** MISO - pin 12
    ** CLK - pin 13
    ** CS - pin 8

      created   Nov 2010
      by David A. Mellis
      modified 9 Apr 2012
      by Tom Igoe

      This example code is in the public domain.

    */


    #include <SPI.h>
    #include <SD.h>

    File myFile;

    void setup() {
      // Open serial communications and wait for port to open:
      Serial.begin(9600);
      while (!Serial) {
        ; // wait for serial port to connect. Needed for native USB port only
      }


      Serial.print("Initializing SD card...");

      if (!SD.begin(8)) {
        Serial.println("initialization failed!");
        while (1);
      }
      Serial.println("initialization done.");

      // open the file. note that only one file can be open at a time,
      // so you have to close this one before opening another.
      myFile = SD.open("test.txt", FILE_WRITE);

      // if the file opened okay, write to it:
      if (myFile) {
        Serial.print("Writing to test.txt...");
        myFile.println("testing 1, 2, 3.");
        // close the file:
        myFile.close();
        Serial.println("done.");
      } else {
        // if the file didn't open, print an error:
        Serial.println("error opening test.txt");
      }

      // re-open the file for reading:
      myFile = SD.open("test.txt");
      if (myFile) {
        Serial.println("Setup test.txt:");

        // read from the file until there's nothing else in it:
        while (myFile.available()) {
          Serial.write(myFile.read());
        }
        // close the file:
        myFile.close();
      } else {
        // if the file didn't open, print an error:
        Serial.println("error opening test.txt");
      }
    }

    void loop() {

      // re-open the file for reading:
      myFile = SD.open("test.txt");
      if (myFile) {
        Serial.println("Loop  test.txt:");

        // read from the file until there's nothing else in it:
        while (myFile.available()) {
          Serial.write(myFile.read());
        }
        // close the file:
        myFile.close();
      } else {
        // if the file didn't open, print an error:
        Serial.println("error opening test.txt");
      }
        delay(2000);
    }
    Попробуйте его скомпилировать и загрузить.
    И понаблюдайте, в мониторе порта будут ли проблемы с чтением из файла.
    Если не будет проблем и будет читаться без ошибок - проблема в вашем коде.
     
  15. ANTISPAM

    ANTISPAM Нуб

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