Сравнение двух массивов

Sammael
Offline
Зарегистрирован: 17.10.2016

Есть rc522 и мега 2560. Хочу реализовать однократное считывание поднесенной метки. пытаюсь выяснить где ошибка. После поднесения метки переменная isEqual всегда принимает значение true, даже после обнуления массива с поднесенной меткой currentCard

//Тестировалось на Arduino IDE 1.0.1

#include <SPI.h>
#include <RFID.h> //рфид библиотека
#define SS_PIN 10 //SS RC522
#define RST_PIN 9 //RST RC522
RFID rfid(SS_PIN, RST_PIN); //хуйня из стандартной библиотеки RC522
unsigned char cardUID [5]; //массив со считанным значением карты
unsigned char i; //хрень, чтобы работало??
unsigned char cardMassiv [5] = {136, 4, 9, 145, 20}; //массив со значением валидной карты
unsigned char currentCard[5];
unsigned char nocurrentCard[5] = {0, 0, 0, 0, 0};
bool readUID () {         // читаем UID если карта поднесена. если поднесена функция readUID возвращает true иначе false
  if (!rfid.isCard())
    return false;
  if (!rfid.readCardSerial())
    return false;
  for (int i = 0; i < 5; i++) {
    cardUID[i] = rfid.serNum[i];
  }
  rfid.isCard();
  return true;
}
bool validCard (byte * cardMassiv) { // сверка cardUID с заданным массивом 1 - совпало, 0 - не совпало, ага а функция validCard(cardMassiv) - метод подбора
  byte valNum = 0;
  for (byte i = 0; i < 5; i++) {
    if (*(cardMassiv + i) == cardUID[i]) valNum++;
  }
  if (valNum == 5) {
    return true;
  } else {
    return false;
  }
}
int calibrationTime = 1; //Время калибровки датчика (10-60 сек. по даташиту)
//Время, в которое был принят сигнал отсутствия движения(LOW)
long unsigned int lowIn;
boolean   isEqual;
long unsigned int dooropened;
//Пауза, после которой движение считается оконченным
int valNum = 0;
long unsigned int pause = 1000;
long unsigned int doorpause = 5000;
long unsigned int timecard;
long unsigned int waitcard = 5000;
//Флаг. false = значит движение уже обнаружено, true - уже известно, что движения нет
boolean lockLow = true;
//Флаг. Сигнализирует о необходимости запомнить время начала отсутствия движения
boolean takeLowTime;
boolean take;
boolean db;
boolean bb;
//boolean timecard;
boolean tp = true;
const int buttonPin = 6;
int buttonState = 0;
int relay = 7;
int pin = 3; //реле замок
int pirPin = 2;    //вывод подключения PIR датчика
int ledPin = 13;   //вывод сигнального диода
int relayPin = 4;  //реле свет
void setup()
{ Serial.begin(9600); //старт сериала
  SPI.begin();  //  инициализация SPI
  rfid.init(); //инициализация RFID
  pinMode(buttonPin, INPUT);
  pinMode(relay, OUTPUT); //реле замок
  pinMode(pin, OUTPUT); //реле замок
  pinMode(pirPin, INPUT);//пир
  pinMode(ledPin, OUTPUT);//лед 13 контакт
  pinMode(relayPin, OUTPUT);//реле свет

  //!ВНИМАНИЕ! При использовании n-p-n реле необходимо в след. строчке поменять HIGH на LOW
  digitalWrite(relayPin, LOW);
  delay(4000);
  digitalWrite(pirPin, LOW);

  //дадим датчику время на калибровку
  for (int i = 0; i < calibrationTime; i++)
  {
    //Во время калибровки будет мигать сигнальный диод
    i % 2 ? digitalWrite(ledPin, HIGH) : digitalWrite(ledPin, LOW);
    delay(1000);
  }
  //По окончанию калибровки зажжем сигнальный диод
  digitalWrite(ledPin, HIGH);
  delay(50);
}




void loop() {
  // buttonState = digitalRead(buttonPin);
  //  for (i = 0; i < 5; i++) {
  //    if (currentCard[i] = cardMassiv[i]) {
  //      isEqual = true;
  //      Serial.println (isEqual);
  //   }
  //  }

  for (int i = 0; i < 5; i++) {
    if (*(cardMassiv + i) == currentCard[i]) valNum++;
  }
  if (valNum == 5) {
    isEqual = true;
  }


  // Serial.println(validCard(cardMassiv));
  // Serial.println("cardmassiv");
  Serial.println(isEqual);
  Serial.println("isEqual");
  if (validCard(cardMassiv) && !isEqual)  {
    for (i = 0; i < 5; i++) {
      currentCard[i] = cardMassiv[i];
    }


    Serial.println("Cardnumber:");
    for (i = 0; i < 5; i++)
    {
      Serial.print(rfid.serNum[i]);
      Serial.print(" ");
      cardUID[i] = rfid.serNum[i];
    }
    tone(5, 200, 500); // Делаем звуковой сигнал, Открытие
    digitalWrite(pin, HIGH); // реле
    take = true;
    db = true;
    bb = true;
  }



  //if (readUID()) {
  //Serial.println("allCardnumber:");
  //for (i = 0; i < 5; i++)
  // {
  // Serial.print(rfid.serNum[i]);
  //   Serial.print(" ");
  //   cardUID[i] = rfid.serNum[i];
  //  }
  // }
  if (!readUID()) {
    for (i = 0; i < 5; i++) {
      cardUID [i] = 0;
    }
  }
  if (buttonState == LOW && !readUID()) {
    if (take) {
      dooropened = millis();
      take = false;
    }
    if (db && millis() - dooropened > doorpause) {
      digitalWrite(pin, LOW); tone(5, 500, 500); // Делаем звуковой сигнал,  Закрытие
      db = false;
    }
  }




  if (digitalRead(pirPin) == HIGH)

  {
    //Если до этого момента еще не включили реле
    if (lockLow)
    {
      lockLow = false;
      //Включаем реле.
      //!ВНИМАНИЕ! При использовании n-p-n реле необходимо в след. строчке поменять LOW на HIGH
      digitalWrite(relayPin, HIGH);
      delay(50);
    }
    takeLowTime = true;
  }

  //Ели движения нет
  if (digitalRead(pirPin) == LOW)
  {
    //Если время окончания движения еще не записано
    if (takeLowTime)
    {
      lowIn = millis();          //Сохраним время окончания движения
      takeLowTime = false;       //Изменим значения флага, чтобы больше не брать время, пока не будет нового движения
    }
    //Если время без движение превышает паузу => движение окончено
    if (!lockLow && millis() - lowIn > pause)
    { for (i = 0; i < 5; i++) { //ОБНУЛЯЕМ МАССИВ С ТЕКУЩЕЙ МЕТКОЙ
        currentCard[i] = 0;
      }
      //Изменяем значение флага, чтобы эта часть кода исполнилась лишь раз, до нового движения
      lockLow = true;
      //!ВНИМАНИЕ! При использовании n-p-n реле необходимо в след. строчке поменять HIGH на LOW
      digitalWrite(relayPin, LOW);
      delay(50);
    }
  }
  //  for (i = 0; i < 5; i++){
  //  Serial.println (currentCard[i]);}

}

 

Logik
Offline
Зарегистрирован: 05.08.2014

Sammael пишет:

 После поднесения метки переменная isEqual всегда принимает значение true, даже после обнуления массива с поднесенной меткой currentCard

ОК. Спасибо, прийму к сведеню, может когда пригодится.

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

а почему бы не сравнить их так?

memcmp(cardMassiv,currentCard,5) == 0

 

Logik
Offline
Зарегистрирован: 05.08.2014

Неее.. к чему стереотипы и шаблоны ;)

Sammael
Offline
Зарегистрирован: 17.10.2016

NeiroN пишет:

а почему бы не сравнить их так?

memcmp(cardMassiv,currentCard,5) == 0

 

спасибо, не знал про функцию memcmp, но проблема осталась возвращает значение true, а не false после обнуления массива

{ for (i = 0; i < 5; i++) { 
        currentCard[i] = 0;
      }

как так?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Sammael пишет:

спасибо, не знал про функцию memcmp, но проблема осталась возвращает значение true, а не false после обнуления массива

{ for (i = 0; i < 5; i++) { 
        currentCard[i] = 0;
      }

как так?

Ну, Вы же не показали как именно Вы используете memcmp. Скорее всего неправильно.

И ещё, меня тут кое-кто на этом форуме обзывает "мозго@ом"Б, так вот - не пытайтесь перехватить это почётное звание и трахайте мозги себе и людям, запутывая программу. Вот зачем Вы написали глубокомысленную конструкцию:

  if (valNum == 5) {
      return true;
  } else {
     return false;
  }

Вам не кажется, что она в точности эквивалентна вот такой:

 return valNum == 5;

Ну, и зачем пять строк вместо одной?

Sammael
Offline
Зарегистрирован: 17.10.2016

спасибо, действительно использовал не правильно.

int isEqual = memcmp(cardMassiv,currentCard,5);

рабочий вариант

Sammael
Offline
Зарегистрирован: 17.10.2016

ЕвгенийП пишет:

И ещё, меня тут кое-кто на этом форуме обзывает "мозго@ом"Б, так вот - не пытайтесь перехватить это почётное звание и трахайте мозги себе и людям, запутывая программу. Вот зачем Вы написали глубокомысленную конструкцию:

  if (valNum == 5) {
      return true;
  } else {
     return false;
  }

Вам не кажется, что она в точности эквивалентна вот такой:

 return valNum == 5;

Ну, и зачем пять строк вместо одной?

действительно эквивалентно, я учту)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

.

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

дело былое уже, как я понял, но без memcmp я бы написал

bool validCard (byte * cardMassiv) { // сверка cardUID с заданным массивом 1 - совпало, 0 - не совпало, ага а функция validCard(cardMassiv) - метод подбора
  for (byte i = 0; i < 5; i++) {
    if (*(cardMassiv + i) != cardUID[i]) return false;
  }
  return true;
}

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Sammael пишет:

спасибо, действительно использовал не правильно.

int isEqual = memcmp(cardMassiv,currentCard,5);

рабочий вариант

Тебе уже показывали пример, там было правильно, что массивы эквивалентны, когда memcmp возвращает... та дааааа НОЛЬ!

Если не веришь, смотри гугл что говорит: http://www.cplusplus.com/reference/cstring/memcmp/