Комбинация матричной клавиатуры и 7-сегментного дисплея обратного отсчета
Я работаю над квестом для своего университета с помощью Arduino Mega. Последняя часть состоит из 7-сегментного дисплея, представляющего обратный отсчет времени, и участники должны ввести правильное число на матричной клавиатуре, прежде чем оно достигнет нуля.
Моя проблема возникает, когда для представления секунд обратного отсчета мне приходится использовать задержку, и это не позволяет матричной клавиатуре получать числа.
Код, который у меня есть:
char keys[4][4] =
{
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[4] = { 5, 4, 3, 2 };
byte colPins[4] = { 9, 8, 7, 6 };
int pinA = 26; //2
int pinB = 34; //3
int pinC = 31; //4
int pinD = 27; //5
int pinE = 25; //6
int pinF = 28; //7
int pinG = 33; //8
int D1 = 24; //9
int D2 = 30; //10
int D3 = 32; //11
int D4 = 35; //12
Keypad mykeypad = Keypad( makeKeymap(keys), colPins, rowPins, 4, 4);
void setup()
{
Serial.begin(9600);
pinMode(pinA, OUTPUT);
pinMode(pinB, OUTPUT);
pinMode(pinC, OUTPUT);
pinMode(pinD, OUTPUT);
pinMode(pinE, OUTPUT);
pinMode(pinF, OUTPUT);
pinMode(pinG, OUTPUT);
pinMode(D1, OUTPUT); //Включаем первую цифру.
pinMode(D2, OUTPUT); //Включаем вторую цифру.
pinMode(D3, OUTPUT); //Включаем третью цифру.
pinMode(D4, OUTPUT); //Включаем четвертую цифру.
}
//
void showTime(){
digitalWrite(D1, LOW);
digitalWrite(D2, LOW);
digitalWrite(D3, LOW);
digitalWrite(D4, LOW);
//3
digitalWrite(pinA, HIGH);
digitalWrite(pinB, HIGH);
digitalWrite(pinC, HIGH);
digitalWrite(pinD, HIGH);
digitalWrite(pinE, LOW);
digitalWrite(pinF, LOW);
digitalWrite(pinG, HIGH);
delay(1000);
//2
digitalWrite(pinA, HIGH);
digitalWrite(pinB, HIGH);
digitalWrite(pinC, LOW);
digitalWrite(pinD, HIGH);
digitalWrite(pinE, HIGH);
digitalWrite(pinF, LOW);
digitalWrite(pinG, HIGH);
delay(1000);
//1
digitalWrite(pinA, LOW);
digitalWrite(pinB, HIGH);
digitalWrite(pinC, HIGH);
digitalWrite(pinD, LOW);
digitalWrite(pinE, LOW);
digitalWrite(pinF, LOW);
digitalWrite(pinG, LOW);
delay(1000);
//0
digitalWrite(pinA, HIGH);
digitalWrite(pinB, HIGH);
digitalWrite(pinC, HIGH);
digitalWrite(pinD, HIGH);
digitalWrite(pinE, HIGH);
digitalWrite(pinF, HIGH);
digitalWrite(pinG, LOW);
delay(1000);
}
//Получает символы с матричной клавиатуры.
void getCode(){
char key = mykeypad.getKey();
if(key){
Serial.print(key);
}
}
void loop()
{
showTime();
}
Есть идеи, как мне получить эту комбинацию? Пытался найти что-то похожее на Thread, но Arduino его не поддерживает.
Заранее спасибо.
@Javier Romero., 👍1
Обсуждение2 ответа
Используйте примеры «мигания без задержки» в IDE, в которых вы выполняете действие, а затем просто наблюдаете за часами, а остальная часть кода выполняется до тех пор, пока не истечет время. Например, это включает и выключает встроенный светодиод, вы можете добавить к нему показания для чтения с клавиатуры и вывода времени.
unsigned long currentTime;
unsigned long previousTime;
unsigned long elapsedTime;
const byte ledPin = 13;
byte ledState = 0;
void setup(){
pinMode (ledPin, OUTPUT);
previousTime = millis();
}
void loop(){
currentTime = millis(); // фиксируем «время» сейчас
elapsedTme = currentTime - previousTime; // сколько «времени» прошло
if (elapsedTime >= 1000){ // хотя бы одну секунду?
ledState = 1 - ledState; // результат 1,0,1,0,1,0 ...
digitalWrite (ledPin, ledState); // переключение светодиода L
previousTime = currentTime; // настройка для следующего цикла прохождения
// обновляем для отображения и выводим его
}
// теперь добавляем возможность чтения с клавиатуры
}
Попробуйте использовать millis()
, он возвращает количество миллисекунд, прошедших с тех пор, как плата Arduino начала выполнять текущую программу.
Когда вы запускаете обратный отсчет, вы устанавливаете переменную для времени начала
int millisBegin = millis(); //поместите это в конец вашего setup() {
.
Вам также понадобится «граница», чтобы знать, когда прошла одна секунда, поэтому
int millisBorder = 1000; //граница в одну секунду
Каждый раз, когда ваш loop() {
запускается заново, вы можете проверить, прошла ли уже одна секунда
int millisNow = millis();
if(millisNow - millisBegin >= millisBorder){} //если прошла одна секунда, выполните {}
Теперь я бы поработал над сегментом, показывающим штуковину. В {}
я бы поместил новую переменную, назовем ее counter = 4; //4, потому что я нашел в вашем скетче 3 числа
. Каждый раз, когда выполняется if() {}
, вы выполняете дополнительные инструкции if () {}
, проверяя, какое число отображать следующим.
if (counter == 3)
{
//показываем номер 3
}
if (counter == 2)
{
//показываем номер 2
}
if (counter == 1)
{
//показываем номер 1
}
if (counter == 0)
{
//показываем номер 0
}
counter = counter - 1;
В конце мы снимаем одну единицу со счетчика, поэтому в следующий раз, когда мы введем if(одна секунда больше)
отображаемое число станет меньше
И теперь есть несколько способов использовать клавиатуру. Вы можете продолжать проверять, доступен ли ключ, и если да, то можете сохранить его как строку (большинство людей ненавидят строки, но, честно говоря, у меня никогда не было с ними проблем).
После того, как вы сохранили ключ в виде строки, вы можете использовать метод strcmp();
для сравнения строки с решением/ответом strcmp(key,answer);
strcmp(key,answer); код>. Если ключ и ответ совпадают, возвращается 1.
if(strcmp(key,answer) == 1)
{
Serial.println("you made it");
}
- Arduino nano как клавиатура HID
- Keyboard.h не найден
- Нажать клавишу Windows, используя «keyboard.press();»
- Отправка мультимедийных клавиш клавиатуры с помощью библиотеки клавиатур
- Какие диоды использовать в матричном вводе кнопок/клавиш? (Изготовление игровой клавиатуры)
- NodeMCU поддерживает внедрение ключей?
- Ввод текста в ESP8266 с помощью USB-клавиатуры
- 74HC595 к 4 значному 7 сегменту с использованием библиотеки SevSegShift
Однако вам не обязательно использовать
delay()
. Взгляните на несколько примеров того, как настроить действия по времени без использования delay() https://learn.adafruit.com/multi-tasking-the-arduino-part-1/using-millis-for-timing., @jose can u c