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

Я проектирую безопасный замок из 4 цифр, но пароль указан в цветах, у меня 3 цвета. мы вынуждены использовать датчик оттенков серого (SKU: SEN0147).

Задание следующее:

Напишите на Arduino программу, которая будет использоваться в качестве безопасного замка. Рассмотрите возможность использования трех цветов: черного, белого и серого. Черный = 0, Красный = 1 и Белый = 2.

• При включении микроконтроллера сейф блокируется. Последовательный монитор должен отображать: «Система онлайн».

• Кодовый замок должен быть сохранен в массиве целых чисел с именем arr_code.

• У пользователя есть 3 попытки открыть сейф.

• Система будет ждать, пока пользователь введет 4 цвета. Чтобы ввести цвет, датчик оттенков серого следует поместить поверх нужного цвета. Когда все будет готово, нажимается кнопка. После освобождения цвет сохраняется в другом массиве под названием arr_user_code.

• После ввода 4 цветов система должна автоматически проверить, введен ли код
пользователь равен коду, сохраненному в arr_code.

• Если введен неверный код, на мониторе последовательного порта отображается: «Неправильный код. Попробуйте еще раз».

• Если пользователь вводит неверный код 3 раза подряд, система блокируется и появляется сообщение
отображается: «Система заблокирована».

• Если введен правильный код, светодиод на контакте 13 включается.

• Комбинации, введенные пользователем, должны отображаться на последовательном мониторе. Программа Arduino должна быть понятной, разделенной на функции и документированной.

Я написал следующую программу:

char led_pin = 13;
char pb_pin = 2;
int gs_pin = A0;
//яркость используемой мной вспышки дает значение 894, поэтому я использую ее для тестирования
int arr_code[4] = { 894, 894, 894, 894 };
int arr_user_code[4];

int counter;
int Lock_Interval = 2500;

char trigger = false;
bool equal = true;
char led_state = false;

int Array_Compare(int *a, int *b) {
  for (int i = 0; i < 4; i++) {
    if (a[i] != b[i]) return 0;
    else return 1;
  }
}

void Button_Wait(int buttonPin) {//функция для определения нажатия кнопки
  int curr_state;
  int prev_state;

  while (1) {
    prev_state = curr_state;
    curr_state = digitalRead(buttonPin);
    if (curr_state != prev_state) {
      if (curr_state == false) {
        delay(10);
        return;
      }
    }
  }
}

int GS_Value(int gsPin) {
  int gs_value = analogRead(gs_pin);
  return gs_value;
}

void setup() {
  // поместите сюда свой код установки для однократного запуска:
  pinMode(led_pin, OUTPUT);
  pinMode(pb_pin, INPUT);
  Serial.begin(9600);
  digitalWrite(led_pin, false);
}

void loop() {
  // поместите сюда свой основной код для многократного запуска:

  Serial.println("System Online");
  Serial.println("Please Enter Passcode:");

  for (counter = 0; counter < 3; counter++) {
    for (int i = 0; i < 4; i++) {//загрузка пользовательского массива со значениями gs
      Button_Wait(pb_pin);
      arr_user_code[i] = analogRead(gs_pin);
      Serial.print(analogRead(gs_pin));//печать значений на мониторе
      Serial.print(" ");
    }

    Serial.println(" ");

    for (int i = 0; i < 4 && equal; i++) {//проверка истинности пароля
      if (arr_user_code[i] != arr_code[i]) {
        equal = false;
      }
      else equal = true;
    }
    if (equal == true) {
      Serial.println("System Unlocked");
      digitalWrite(led_pin, true);
    }

    else if (equal == false) {
      Serial.println("Wrong Passcode. Try Again");
    }
  }

  /*Array_Compare( arr_user_code, arr_code);
  if (Array_Compare) Serial.println("System UNLOCKED");
  else Serial.println("Wrong Passcode. Try Again");
  */
  if (trigger == false) {// для блокировки системы
    Serial.println("System LOCKED!");
    while (1) {
      Lock_Interval = Lock_Interval * 2;// ИЗМЕНИТЬ НА МИНУТЫ СПУСТЯ!!
      delay(Lock_Interval);
      return;
    }
  }
  delay(100);
}

Мне жаль, что многие функции не используются и множество отмененных алгоритмов из-за замечаний, но это моя царапина. проблема в том, что моя программа всегда выдает мне неправильный пароль, даже если он правильный. Можете ли вы помочь мне найти проблему, пожалуйста? Заранее спасибо.

, 👍0

Обсуждение

Верны ли значения, которые вы видите, напечатанные поверх Serial?, @RamblinRose

да, я установил пароль в соответствии с ними, @Rayan Hamadeh

Поскольку у вас есть else return 1; в Array_Compare, это всегда будет завершаться после первой итерации. return 1; должен быть помещен после цикла for., @Maximilian Gerhardt

@MaximilianGerhardt, вы правы, но код не вызывает функцию., @RamblinRose

@RamblinRose правда. Еще несколько замечаний. В коде arr_user_code[i] = AnalogRead(gs_pin); Serial.print(analogRead(gs_pin)); значение в массиве и распечатанное значение могут отличаться, поскольку вы проводите два разных измерения АЦП (это вообще то, что вам нужно)? Вы должны напечатать arr_user_code[i]. Кроме того, прежде чем сравнивать его с другим массивом, вам следует распечатать его полное содержимое. Тогда вы увидите, есть ли разница в значениях., @Maximilian Gerhardt

@RayanHamadeh, какова цель самого внешнего цикла на «счетчике»?, @RamblinRose

@RamblinRose крайний счетчик — блокировать всю систему, если код введен неправильно 3 раза, @Rayan Hamadeh

@MaximilianGerhardt, в этом случае значение, напечатанное на последовательном мониторе, будет случайным числом 30 тысяч, что наверняка не является значением датчика., @Rayan Hamadeh

@RayanHamadeh analogRead вернул значение, превышающее 30 КБ? Должно быть 0-1023. Можете ли вы отредактировать вопрос, чтобы показать текущий код, который вы используете?, @Maximilian Gerhardt


2 ответа


0

В вашей программе много проблем, но основная проблема заключается в

if (trigger == false) 

Код инициализирует это значение как false, и логика никогда не меняет значение, поэтому программа всегда будет указывать «Система ЗАБЛОКИРОВАНА!»

Похоже, вы перепутали переменные trigger и equal. Избавьтесь от переменной триггера и используйте ее равно.

if (equal == false) {// для блокировки системы
    Serial.println("System LOCKED!");
    while (1) {
      Lock_Interval = Lock_Interval * 2;// ИЗМЕНИТЬ НА МИНУТЫ СПУСТЯ!!
      delay(Lock_Interval);
      return;
    }
  }

Я рекомендую использовать другое имя переменной, например «unlock», поскольку оно поясняет использование переменной. Кроме того, инициализируйте переменные, такие как «равно», в начале цикла(). Удачи.

ИЗМЕНИТЬ

Ваша проверка сравнения в цикле() действительна. Однако если вам нужно использовать Array_Compare, вот решение.

// возвращает 1, если равно, и 0 в противном случае.
int Array_Compare(int *a, int *b) {
   for (int i = 0; i < 4; i++) {
       if (a[i] != b[i])
          return 0;
   }
   return 1;
}

Затем в цикле удалите локальный цикл сравнения с помощью

//for (int i = 0; i < 4 && равно; i++) {//проверка истинности пароля
// if (arr_user_code[i] != arr_code[i]) {
// равно = ложь;
// }
// иначе равно = true;
//}

equal = Array_Compare(arr_user_code, arr_code);

Мне неудобно писать за вас вашу программу, это не сервис кодирования.

,

но это не решает проблему сравнения arr_user_code и arr_code, @Rayan Hamadeh

@RayanHamadeh код сравнивает массивы в функции цикла() и изменяет переменную «равно» в соответствии с произведенными сравнениями., @RamblinRose


1

Поскольку вы пытаетесь различать три цвета, я предполагаю, что вы используете SEN0147 в аналоговом режиме. Это означает, что выходной сигнал датчика находится в диапазоне 0–5 В. Я не верю, что это всегда будет именно значение 894.

Я предлагаю изменить проверку сравнения таким образом, чтобы не проверять идентичность значений, а проверять, находятся ли значения в определенном диапазоне. (в дополнение ко всем ответам, которые уже предложил @RamblinRose)

Вот модификация цикла сравнения @RamblinRose с предложенными мной изменениями. Проверьте различные значения threshold, начиная с высокого и заканчивая меньшим.

// возвращает 1, если равно, и 0 в противном случае.
int Array_Compare(int *a, int *b) {

   int threshold = 500;
   int temp;
   for (int i = 0; i < 4; i++) {
       temp = a[i] - b[i];
       if (abs(temp) > threshold)
       return 0;
   }
   return 1;
}
,