Невозможно сохранить данные RFID в следующих 5 байтах массива.

Я работаю над проектом RFID для обработки нескольких карт.

Большую часть вещей я сделал нормально. Но теперь у меня есть одна проблема. А именно:

  1. Код RFID имеет длину 5 байт, поэтому мне нужен массив из 5 байт. Если карт больше, то размер массива = количество карт * 5.
  2. В моем примере я работаю с двумя карточками. Таким образом, размер массива составляет 10 байт.
  3. Я могу сохранить первую карточку в первых 5 байтах.

Проблема: Я не могу сохранить вторую карту в следующих 5 байтах массива. Я не знаю почему.

Это мой единственный тестовый код:

/****************************** LIBRARIES ******************************/
#include <SPI.h>
#include <RFID.h>

/****************************** DEFINITIONS ******************************/
// определения выводов
#define SS_PIN          10
#define RST_PIN         9

// определения настроек
#define CARDS           2
#define MXCD            CARDS*5

/****************************** VARIABLES ******************************/
// переменные RFID:
byte crd_buf[MXCD],card_no;
byte register_lock,check_lock,print_lock;

/****************************** FUNCTIONES ******************************/
// функции RFID
void register_accepted_card(void);
void record_new_cards(void);
void check_card(void);
void print_registered_cards(void);


// объекты
RFID rfid(SS_PIN, RST_PIN); 

/////////////////////////////////////////////////// /////////////////////
void setup(){ 
  Serial.begin(9600);
  SPI.begin(); 
  rfid.init();
}

void loop(){
    register_accepted_card(); // применяем только один раз
}


void register_accepted_card(void){
  if (!register_lock) {
    if (rfid.isCard()) {
      if(rfid.readCardSerial()){
        if(card_no>0){
          for(byte i = 0; i<card_no; i++){
            if(!memcmp((crd_buf+(i*5)),rfid.serNum,5)){

              Serial.println("already card is");
              for(byte p = i*5; p<(i*5)+5; p++){
                Serial.print(crd_buf[p],HEX);Serial.print(", ");}
                Serial.println();

              lcd_state = ALREADY_MSG;
              register_lock = 1;
            }
          }
        }

        //////////////////////////
        // проблема в этой части
        //////////////////////////

        if(!register_lock){

          for(byte i=card_no*5;i<(card_no*5)+5;i++){
            crd_buf[i] = rfid.serNum[i];}

          Serial.print("loop#"); Serial.println(card_no);
          Serial.print("start index ");Serial.println(card_no*5);
          Serial.print("end index ");Serial.println((card_no*5)+5);
          Serial.println();


          Serial.print("card#"); Serial.println(card_no+1);
          for(byte i=card_no*5;i<(card_no*5)+5;i++){
            Serial.print(crd_buf[i],HEX);Serial.print(", ");}
          Serial.println();Serial.println("///////////////////////////");

          card_no++;
          if(card_no >= CARDS){lcd_state = FINISH_MSG;}
          else{lcd_state = REGISTER_MSG;}
          register_lock = 1;          
        }
      }
    }
    rfid.halt();
  }
}

/////////////////////////////////////////////// /////////////////////////////////////////////////// /////////////////////////////////////////////////// /////////// /////////////////////////////////////////////////// /////////////////////////////////////////////////// /////////////////////////////////////////////////// ////////

Мой второй вопрос по поводу проверки карт после окончания регистрации карт на прием.

Я выполнил цикл for для количества карт, чтобы получить карту, зарегистрированную в массиве, и отправить сообщение о том, что карта сохранена и принята, в противном случае возвращается сообщение об отказе в том, что карта не сохранена. массив с звуковым сигналом.

Проблема заключается в том, что цикл for проверяет карту на наличие всех индексов в массиве, чего я и хочу, но результат смешивается с принятым и отклоненным.

Вопрос в том, как выйти из цикла for?

void check_card(void){
  if (check_lock){
    if (rfid.isCard()){
      if (rfid.readCardSerial()){
        for(byte i=0;i<card_no;i++){

          // начало цикла for
          Serial.print("check# ");Serial.println(i);
          if(!memcmp(crd_buf+(i*5),rfid.serNum,5)){
            Serial.println("card accepted");
            digitalWrite(ACCEPT_LED,HIGH);
            digitalWrite(DENIED_LED,LOW);
            digitalWrite(BUZZER,LOW);
            check_lock = 0;
            sys_state = 1;
            lcd_state = ACCEPTED_MSG;
          }
          else{
            Serial.println("card denied");
            digitalWrite(ACCEPT_LED,LOW);
            digitalWrite(DENIED_LED,HIGH);
            digitalWrite(BUZZER,HIGH);
            check_lock = 0;
            sys_state = 1;
            lcd_state = DENIED_MSG;
          }          
        }   
            // конец цикла for

      }
      rfid.halt();
    }
  }
}

, 👍0

Обсуждение

Почему бы не использовать двумерный массив crd_buf[CARDS][5];? Так гораздо проще иметь дело., @Majenko

ОК, надо попробовать твой метод. Но я действительно не понимаю, почему он не работает, поскольку я тестировал его в кодовых блоках, и он работает нормально! Есть ли что-то, чего я не знаю о компиляторе Arduino? Возможно ли, что компилятор не предназначен для обработки этих операций с массивами? на мой взгляд, я так не думаю, компилятор Arduino действительно профессиональный. Может я что-то не так делаю.. Но надо бы попробовать 2D версию, спасибо чувак :), @R1S8K


1 ответ


Лучший ответ:

1

Ваша проблема вот в чем:

      for(byte i=card_no*5;i<(card_no*5)+5;i++){
        crd_buf[i] = rfid.serNum[i];}

Для первой карты вы копируете байты 0–4 serNum в байты 0–4 crd_buf.

Однако для второй карты вы копируете байты 5–9 serNum в байты 5–9 crd_buf. Это верно для crd_buf, но неверно для serNum.

Правильнее всего было бы добавить card_no*5 к i при создании индекса:

      for(byte i=0; i<5; i++){
        crd_buf[(card_no*5) + i] = rfid.serNum[i];}

Или лучше определить буфер карты как 2D-массив, чтобы вам не приходилось выполнять эти вычисления:

byte crd_buf[CARDS][5];

for (i = 0; i < 5; i++) {
    crd_buf[card_no][i] = rfid.serNum[i];
}

Или проще:

memcpy(crd_buf[card_no], rfid.serNum, 5);

Что касается второго вопроса: вообще не печатайте сообщение в цикле.

Вместо этого начните с предположения, что доступ запрещен. Затем, если карта совпадает, предоставьте доступ. Самый простой способ — с помощью флага.

if (rfid.readCardSerial()){

    bool accessGranted = false;  // Флаг для хранения состояния — начало запрещено.

    for(byte i=0;i<card_no;i++){
        if(!memcmp(crd_buf+(i*5),rfid.serNum,5)){
            accessGranted = true;
        }
    }

    // замените их своими собственными процедурами обработки сообщений.
    if (accessGranted) {
        Serial.println("Access Granted");
    } else {
        Serial.println("Access Denied");
    }
}
,

Комментарии не предназначены для расширенного обсуждения; этот разговор [перенесен в чат](https://chat.stackexchange.com/rooms/92103/discussion-on-answer-by-majko-cant-store-rfid-data-in-the-next-5- байты Arr)., @Majenko