Отображение случайного числа для отображения в течение T секунд с помощью Millis() для Dice Roller
Я пишу код для электронного игрального автомата. При нажатии кнопки (A2) код должен отображать случайное число на двухразрядном семисегментном дисплее в течение 20 секунд, а затем отображать пустое изображение.
В настоящее время мой код будет отображать случайное число каждые t секунд, пока кнопка постоянно удерживается. Я хотел бы, чтобы пользователь мог нажать кнопку и отпустить, чтобы код делал свое дело.
На какие примеры мне следует обратить внимание, чтобы добиться этого? Я совсем новичок в коде ардуино.
#include "SevSeg.h"
SevSeg sevseg; //Создаем экземпляр семисегментного объекта
int displayPeriod = 1000; //задержка нажатия кнопки
unsigned long time_now = 0;
long randNumber;
void setup() {
pinMode(A2,INPUT);
randomSeed(analogRead(3));
byte numDigits = 2;
byte digitPins[] = {2, 3};
byte segmentPins[] = {4,5,6,7,8,9,10};
bool resistorsOnSegments = false; // 'false' означает, что резисторы находятся на цифровых выводах
byte hardwareConfig = COMMON_CATHODE; // См. README.md для опций
bool updateWithDelays = false; // Рекомендуется значение по умолчанию false
bool leadingZeros = false; // Используйте 'true', если хотите сохранить ведущие нули
bool disableDecPoint = true; // Используйте 'true', если ваша десятичная точка не существует или не связана. Затем вам нужно указать только 7 segmentPins[]
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
updateWithDelays, leadingZeros, disableDecPoint);
}
void loop() {
if(digitalRead(A2) == HIGH){
rollD20();
}
else{
sevseg.setChars("");
sevseg.refreshDisplay();
}
}
void rollD20(){
if(millis() >= time_now + displayPeriod){
time_now += displayPeriod;
time_now = millis();
randNumber = random(21);
}
sevseg.setNumber(randNumber);
sevseg.refreshDisplay();
}
void testInput(){
sevseg.setNumber(0);
sevseg.refreshDisplay();
}
@BobaJFET, 👍-1
Обсуждение2 ответа
Лучший ответ:
Я бы рекомендовал не изобретать велосипед, и правильное управление кнопками может быть не таким уж тривиальным. Я бы предложил эту библиотеку для решения вашей проблемы.
Проблема в том, что ваша функция rollD20 вызывается только при нажатии кнопки. Поэтому, как только вы отпустите кнопку, он никогда не вернется к этой процедуре для завершения. Вам нужно отделить вызов функции от обнаружения кнопки.
bool rollingDice = false;
void loop() {
if(digitalRead(A2) == HIGH){
rollingDice = true;
}
if(rollingDice){
rollD20();
}
else{
sevseg.setChars("");
sevseg.refreshDisplay();
}
А затем в методе rollD20 вам нужно снова установить значение false, когда придет время остановиться:
void rollD20(){
if(millis() >= time_now + displayPeriod){
time_now += displayPeriod;
time_now = millis();
randNumber = random(21);
rollingDice = false;
}
sevseg.setNumber(randNumber);
sevseg.refreshDisplay();
}
- Кнопка с таймером переключения и функцией сброса времени + светодиод обратной связи
- Как использовать millis вместо delay на Arduino для независимых интервалов времени для двух выходных контактов
- Кнопка, которая дает ввод, имеет небольшую задержку - затем дает другой
- avrdude ser_open() can't set com-state
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Как справиться с rollover millis()?
- Какое максимальное энергопотребление Arduino Nano 3.0?
- Как навсегда изменить скорость передачи данных ESP8266 (12e)?
Обратите внимание, что «analogRead(3)» — очень плохой источник энтропии. Время нажатия кнопки с
micros()
было бы намного лучше., @Edgar BonetПочему это плохой источник? Из справочника arduino для функции random(): «Если важно, чтобы последовательность значений, сгенерированных random(), отличалась, при последующих выполнениях скетча используйте randomSeed() для инициализации генератора случайных чисел довольно случайным ввода, например, AnalogRead() для неподключенного вывода». Редактировать: Nvm Я понимаю, почему это плохо., @BobaJFET
ваш код обрабатывает нажатие кнопки, но ничего не делает с отпусканием кнопки... не кодируйте состояние "кнопка нажата", потому что это состояние длится до тех пор, пока кнопка удерживается... код для "перехода между кнопкой отпущена и нажата кнопка`, потому что переход происходит только один раз и может повториться, только если вы отпустите кнопку, @jsotola
@jsotola Да, сейчас я читаю, как это сделать. Я бы хотел, чтобы функция полностью завершила свой код, прежде чем вернуться к основному циклу. С момента написания этого поста в коде появился цикл for, предназначенный для отображения 29 случайных чисел подряд, а затем отображения 30-го числа на дисплее. Кажется, я не понимаю. Какой тип примера я должен искать?, @BobaJFET