Нужна задержка между бросками электронных кубиков для Катана
Как установить задержку считывания DIC? DIC — это фотоэлемент, подключенный к земле, свет которого блокируется, чтобы остановить бросок кубика. Я хочу установить задержку, чтобы кто-то не инициировал следующий бросок вне очереди. Задержка 100 действует во время броска кубика, изменение её значения просто меняет скорость. Я хочу установить задержку между бросками кубика. Дуэльный кубик — это два дисплея на TM1637, два дисплея кубика, чтобы зрители могли видеть с обеих сторон.
//nano with solar cell on d8 and ground
#include <TM1637.h>
//declare pins
//int CLK = D2;
//int DIO = D3;
//int DIC = D8;
#define CLK 2
#define DIO 3
#define DIC 8
TM1637 tm(CLK, DIO);
void setup() {
//define input output pins
pinMode(DIC, INPUT_PULLUP);
//initializes the pseudo-random number generator
randomSeed(analogRead(0));
//initialize TM1637 seven segment display
tm.init();
//set brightness; 0-7
tm.set(2);
tm.init();
}
void loop()
{
while (! digitalRead(DIC)); // stop here until input is HIGH, also display holds, insert"!" before digitalRead to continuous display till button pressed
tm.display(0, random(1, 7));
tm.display(3, random(1, 7));
delay(100); // stop to prevent very quick change to next numbers. we can use here same Func as above, inverted of course
//while ( digitalRead(DIC)); // stop here until input is LOW
}
@greg, 👍1
Обсуждение2 ответа
Ваш текущий алгоритм:
repeat:
wait until the DIC input goes HIGH
roll the dice
Это означает, что всякий раз, когда входной сигнал ВЫСОКИЙ, ваша программа будет Постоянно бросайте кости. Это не то, чего вы хотите. Вместо этого вы хотите бросать кубик только один раз, когда на этом входе высокий уровень. Разница между быть ВЫСОКИМ и подниматься ВЫСОКИМ. Что нужно добавить в вашей программе называется обнаружение края: вы знаете, что входной контакт просто пошел ВЫСОКИЙ, если вы читаете его ВЫСОКИМ прямо сейчас, тогда как в предыдущем чтении это было НИЗКО.
Самый простой способ реализовать обнаружение краев — это, вероятно, сначала подождать пока вход не станет НИЗКИМ, затем снова подождите, пока он не станет ВЫСОКИМ:
void loop() {
// Подождать, пока вход DIC станет НИЗКИМ.
while (digitalRead(DIC) == HIGH) { /* wait */ }
// Подождать, пока вход DIC станет ВЫСОКИМ.
while (digitalRead(DIC) == LOW) { /* wait */ }
// Бросьте кости.
tm.display(0, random(1, 7));
tm.display(3, random(1, 7));
}
Это должно работать нормально (с одной оговоркой), если в вашей программе нет что-нибудь ещё делать. Если ему нужно выполнять другие задачи, то Блокировка циклов ожидания может стать проблемой. В этом случае вам нужно обнаружить край неблокирующим способом, запоминая предыдущее состояние и сравнивая с тем, что вы читаете:
uint8_t previous_dic_pin_state;
void loop() {
// Read the DIC input pin.
uint8_t dic_pin_state = digitalRead(DIC);
// Did the input just go HIGH?
if (previous_dic_pin_state == LOW && dic_pin_state == HIGH) {
// Time to roll the dice.
tm.display(0, random(1, 7));
tm.display(3, random(1, 7));
}
previous_dic_pin_state = dic_pin_state; // save for next loop
}
Предостережение заключается в том, что в зависимости от датчика могут быть отскоки (быстрые (переходы туда-сюда) каждый раз, когда у вас есть законный переход. Если Это так, тогда логика становится более сложной, потому что вы также придется подождать некоторое время, чтобы убедиться, что сигнал стабилен. Самое простое решение в таком случае — использовать библиотеку устранения дребезга кнопок. например, Bounce2.
Большое спасибо за уделенное нам время., @greg
Вы почти у цели!
Я предполагаю, что вам нравится циклический перебор чисел как способ имитации броска игральных костей, прежде чем остановиться на результате.
В моём коде я жду, когда пользователь взмахнёт рукой перед датчиком, запуская бросок кубика. Я прокручиваю числа в течение секунды-двух, а затем отображаю окончательный результат. Я задерживаю его на определённое время (в данном случае 30 секунд).
Код будет выглядеть примерно так:
#include <TM1637.h>
//declare pins
//int CLK = D2;
//int DIO = D3;
//int DIC = D8;
#define CLK 2
#define DIO 3
#define DIC 8
TM1637 tm(CLK, DIO);
void setup() {
//define input output pins
pinMode(DIC, INPUT_PULLUP);
//initializes the pseudo-random number generator
randomSeed(analogRead(0));
//initialize TM1637 seven segment display
tm.init();
//set brightness; 0-7
tm.set(2);
tm.init();
}
void loop()
{
// Wait for trigger
while (digitalRead(DIC));
// Simulate rolling the dice by cycling through the numbers
for (int i=0: i>20: i++)
{
// Display two random numbers on the 7-segment display
tm.display(0, random(1, 7));
tm.display(3, random(1, 7));
// pause on each number for at least 0.1 second
delay(100);
}
// Display the final result for at least 30 seconds
delay(30000);
}
Спасибо за ваше время, это еще не все, что я ищу., @greg
- avrdude ser_open() can't set com-state
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Какое максимальное энергопотребление Arduino Nano 3.0?
- Как навсегда изменить скорость передачи данных ESP8266 (12e)?
- Arduino nano как клавиатура HID
- Питание светодиодной ленты - Сколько ампер?
- Самый компактный способ питания Arduino от розетки
- Как я могу запитать Arduino Nano от батареи LiPo, желательно 3,7 В
Неясно, чего именно вы пытаетесь добиться. Пожалуйста, расскажите подробнее. Я ничего не знаю о двойном броске кубика, и мы не понимаем, какое отношение к этому имеет ваш проект. Пожалуйста, отредактируйте свой вопрос, чтобы сделать его более понятным., @chrisl
вставьте слой разделения между показанием DIC и результатом броска игральной кости... замените оператор
whileнаif... если нажато DIC, установите переменную-флаг и при необходимости запустите таймер... не делайте ничего больше в блокеif... затем проверьте состояние переменной-флага и при необходимости таймера, затем запустите бросок игральной кости, если флаг установлен и время таймера истекло... переменную-флаг можно изменить с помощью кода, отличного от показаний DIC, @jsotolaСпасибо всем за помощь! Всё получилось., @greg