Случайное моргание с millis()
я пытаюсь сделать скетч, в котором мой светодиод мигает со случайной задержкой. У меня есть 2 функции: ledBlink() и randomBlink(). вторые функции получают в качестве параметра задержки случайное число "r", сгенерированное от 1 до 499, и передают это значение функции ledBlink, чтобы светодиод мигал с задержкой в соответствии с сгенерированным случайным числом. Но проблема в том, что светодиод мигает очень быстро и, похоже, не учитывает значение blinkDelay. Любая помощь приветствуется, большое вам спасибо!
#include <JC_Button.h>
int ledPin = 11;
int ledState = LOW;
unsigned long blinkDelay;
unsigned long lastBlinkMillis = 0;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}
void ledBlink()
{
unsigned long currentMillis = millis();
if (currentMillis - lastBlinkMillis >= blinkDelay)
{
// save the last time you blinked the LED
lastBlinkMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
ledState = !ledState;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
void randomBlink()
{
unsigned long r = random(500);
blinkDelay = r;
ledBlink();
}
void loop() {
randomBlink();
}
@tommy, 👍1
Обсуждение1 ответ
Лучший ответ:
Описание вашей проблемы немного неясно, хотя я думаю, что вижу вашу проблему.
На каждой итерации цикла()
вы вызываете функцию randomBlink()
, которая генерирует новое значение случайной задержки, а затем вызывает функцию ledBlink ()
, которая, в свою очередь, проверяет millis()
на время переключения светодиода и быстро завершает работу. Таким образом, вы мигаете только тогда, когда текущий blinkDelay
прошел, но вы генерируете новые случайные значения для blinkDelay
на каждой итерации цикла ()
- так что действительно очень быстро. За время, необходимое даже для небольших задержек, вы, возможно, сгенерировали тысячи новых случайных значений, так что весьма вероятно, что некоторые из них являются довольно малыми значениями. Вы сверяетесь с ними, чтобы получить только короткие задержки.
Подумайте, как бы вы поступили так в реальной жизни. Допустим, вы используете кости, чтобы определить количество минут ожидания. Вы бросаете кости каждые несколько секунд, наблюдая за часами. Скорее всего, в какой-то момент вы получите 1 или 2 после ожидания 1 или 2 минут. Маловероятно, что вы не получите 6 баллов в течение 6 минут подряд. Вместо этого вы хотели бы пройти через кости только один раз за период ожидания.
Для кода это означает, что вам нужно его реструктурировать. Рассчитайте новое значение задержки только при переключении светодиода. Итак, что-то вроде этого:
void ledBlink()
{
unsigned long currentMillis = millis();
if (currentMillis - lastBlinkMillis >= blinkDelay)
{
// save the last time you blinked the LED
lastBlinkMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
ledState = !ledState;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
// generate new random delay
randomBlink();
}
}
void randomBlink()
{
unsigned long r = random(500);
blinkDelay = r;
}
void loop() {
ledBlink();
}
Вызов функции ledBlink()
в каждой итерации цикла()
гарантирует, что переключение светодиода действительно происходит. Новое случайное значение задержки вызывается только после того, как индикатор только что включился. Теперь диапазон задержки составит полные 499 мс.
о, хорошо, попался! Спасибо!, @tommy
- Как справиться с rollover millis()?
- Использование millis() и micros() внутри процедуры прерывания
- ардуино - миллисекунды ()
- Кнопка с таймером переключения и функцией сброса времени + светодиод обратной связи
- Использовать timer0, не влияя на millis() и micros().
- Торговый автомат Arduino для мониторинга ввода монет в слот во время ожидания ввода пользователя
- Влияет ли `millis()` на длинные ISR?
- nodeMCU — Millis() — Простой счетчик — Как долго горит светодиод?
вам может понравиться это https://github.com/jandrassy/SunriseClock/blob/6ad596040e6a87d569ffaacddd7988803fc5d376/SunriseClock/SunriseClock.ino#L687, @Juraj
установите флаг "занято
в начале" ledBlink()
... очистите его внутри блока " если`... вызовите функцию "randomBlink ()" только в том случае, если она не занята, @jsotola