Объединение двух эскизов, которые оба работают сами по себе, но не работают вместе.
У меня есть программа для дверного замка, защищенного паролем, и я ее заставил работать.
Я пытаюсь добавить в код функционал, позволяющий включать и выключать светодиод с помощью кнопки.
Оба кода работают сами по себе и служат своей цели, но когда я пытаюсь объединить их в один скетч, кнопка со светодиодом работает, но остальная часть моей конструкции перестаёт работать. Я больше не могу ввести пароль для активации мотора.
Как мне объединить два кода и заставить их оба работать?
Вот рабочий код клавиатуры/блокировки
#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); // сохраняет небольшую задержку
}
@nick g, 👍0
Обсуждение1 ответ
Лучший ответ:
Давайте на минуту отвлечемся от 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
- Как использовать SPI на Arduino?
- Как решить проблему «avrdude: stk500_recv(): programmer is not responding»?
- Как создать несколько запущенных потоков?
- avrdude ser_open() can't set com-state
- Как подключиться к Arduino с помощью WiFi?
- Mac OSX Yosemite не отображает последовательные порты для Uno R3
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
Я только что понял, что исходный код-пароль все равно будет работать, но только если я буду удерживать кнопку переключения светодиода., @nick g
Кстати, digitalRead возвращает не
trueилиfalse, аHIGHилиLOW. По совпадению, это одни и те же числа, но лучше проверить, что функция возвращает в документации. См.: https://www.arduino.cc/reference/en/language/functions/digital-io/digitalread/, @Nick Gammon