Объединение двух эскизов, которые оба работают сами по себе, но не работают вместе.

У меня есть программа для дверного замка, защищенного паролем, и я ее заставил работать.

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

Оба кода работают сами по себе и служат своей цели, но когда я пытаюсь объединить их в один скетч, кнопка со светодиодом работает, но остальная часть моей конструкции перестаёт работать. Я больше не могу ввести пароль для активации мотора.

Как мне объединить два кода и заставить их оба работать?

Вот рабочий код клавиатуры/блокировки

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>

#define Password_Length 5 

int signalPin = 10;
int greenLedPin = 11;
int redLedPin = 12;
char Data[Password_Length] = "4";
char Master[Password_Length] = "1234"; 
byte data_count = 0, master_count = 0;
bool Pass_is_good;
char customKey;

const byte ROWS = 4;
const byte COLS = 3;
bool ledState = 0;

char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3};

Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS,     COLS);

LiquidCrystal_I2C lcd(0x3f, 16, 2);   



void setup()
{
  lcd.init(); 
  lcd.backlight();
  Serial.begin(9600);
  lcd.clear();

  pinMode(redLedPin, OUTPUT);
  pinMode(greenLedPin, OUTPUT);
  digitalWrite(redLedPin, LOW);
  digitalWrite(greenLedPin, LOW);  
}



void loop()
{
  lcd.setCursor(0,0);
  lcd.print("Enter Password:");

  customKey = customKeypad.getKey();
  if (customKey){
    Data[data_count] = customKey; 
    lcd.setCursor(data_count,1); 
    lcd.print(Data[data_count]); 
    data_count++; 
    }

if(data_count == Password_Length-1){
    lcd.clear();

    if(!strcmp(Data, Master)){
      lcd.print("Correct");
      pinMode(signalPin, OUTPUT);
      digitalWrite(signalPin, LOW); //включает мотор
      digitalWrite(greenLedPin, HIGH); //включает светодиод
      delay(2000);
      digitalWrite(signalPin, HIGH); //выключает мотор
      digitalWrite(greenLedPin, LOW); //выключает светодиод
      }
    else{
      lcd.print("Incorrect");
      digitalWrite(redLedPin, HIGH); //включает светодиод
      delay(2000);
      digitalWrite(redLedPin, LOW); //выключает светодиод
      }

    lcd.clear();
    clearData();  
  }
}



void clearData(){
  while(data_count !=0){
    Data[data_count--] = 0; 
  }
  return;
}

А вот код, который я использую для кнопки включения/выключения светодиода

int button = 2;
int led = 13; 
int status = false;

void setup(){ 
pinMode(led, OUTPUT); 
pinMode(button, INPUT_PULLUP); // устанавливаем внутренний подтягивающий резистор,
unpressed button is HIGH 
}

void loop()
{ 
//a) если кнопка не нажата, ложный статус отменяется !status
and the LED turns on 
//б) если кнопка нажата, истинный статус меняется на противоположный с помощью !status и
the LED turns off 

if (digitalRead(button) == true) { 
status = !status; 
digitalWrite(led, status); 
} while(digitalRead(button) == true); 
delay(50); // сохраняет небольшую задержку
}

, 👍0

Обсуждение

Я только что понял, что исходный код-пароль все равно будет работать, но только если я буду удерживать кнопку переключения светодиода., @nick g

Кстати, digitalRead возвращает не true или false, а HIGH или LOW. По совпадению, это одни и те же числа, но лучше проверить, что функция возвращает в документации. См.: https://www.arduino.cc/reference/en/language/functions/digital-io/digitalread/, @Nick Gammon


1 ответ


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

2

Давайте на минуту отвлечемся от Arduino и спросим: предположим, вы знаете, как готовить бекон, а также как варить яйца, как бы вы одновременно приготовили бекон и яйца?

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

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

Я сделал пост об этом: http://www.gammon.com.au/blink

Я только что понял, что исходный код-пароль все еще будет работать, но только если я буду удерживать кнопку переключения светодиода.

Что ж, вам нужно удалить все блокирующие циклы из любой части кода.

Ваш код здесь блокирует:

if (digitalRead(button) == true) { 
status = !status; 
digitalWrite(led, status); 
} while(digitalRead(button) == true); 

Это как (по моей аналогии) думать: «О, вода закипела, придётся смотреть на яйца, пока они не сварятся». Вместо этого можно проверить бекон, проверить яйца, снова проверить бекон и так далее.

Я даю вам эти аналогии, чтобы помочь вам решить общую проблему, а не этот конкретный фрагмент кода.


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

Замените код светодиода на что-то вроде этого (не скомпилировано и не протестировано):

void loop ()
  {
  static int oldReading = LOW;
  int newReading = digitalRead (button);
  if (newReading != oldReading)  // изменилось!
    {
    oldReading = newReading;  // запомнить новое состояние чтения
    if (newReading == HIGH)
      {
      status = !status; 
      digitalWrite(led, status);
      }  // конец ВЫСОКОГО показания
    }  // конец измененного состояния

   // пароль здесь

   }  // конец цикла

Теперь, что бы вы ни делали с кнопкой, код не останавливается (не блокируется), поэтому работа с паролем продолжается.

,

Спасибо, это понятно, но я слишком новичок в этом деле, чтобы знать, как это исправить., @nick g

Я понимаю, что код блокирует, но этот код также заставляет светодиод включаться и выключаться, как мне нужно. Как мне интегрировать это так, чтобы это не блокировало остальное?, @nick g