снова про "без delay"
- Войдите на сайт для отправки комментариев
Здравствуйте. Я все понимаю - тема жеванная пережеванная. Но поиском по сайту и гуглу на нашел решение.
Как моргать без делай понятно. Функция blink1sec () работает нормально. Проблема возникает когда надо выполнить функцию blink500mills () - функция выполняется только пока нажата кнопка, не смотря на содержащийся цикл со счетчиком. С одной стороны логично - кнопку отпустили и состояние переменной изменлось и выполнение вернулось функции blink1sec (). Но тогда почему выолняется blinkDelay () при разовом нажатии кнопки и почему она не прекращает работу в момент прохождения через for (почему она работает в действии которое гоняет цикл for понятно).
Собственно основной вопрос как сделать так чтобы blink500mills () выполнился заданное количество раз даже при отпускании кнопки?
Заранее спасибо
/* Blink without Delay
2005
by David A. Mellis
modified 8 Feb 2010
by Paul Stoffregen
*/
const int ledPin = 12; // номер выхода, подключенного к светодиоду
// Variables will change:
int ledState = LOW; // этой переменной устанавливаем состояние светодиода
long previousMillis = 0; // храним время последнего переключения светодиода
const int buttonPin = 7; //из скетча с кнопкой
int buttonState = 0; //из скетча с кнопкой
long interval = 3000; // интервал между включение/выключением светодиода (1 секунда)
void setup() {
// задаем режим выхода для порта, подключенного к светодиоду
pinMode(ledPin, OUTPUT);
// инициализируем пин, подключенный к светодиоду, как выход
pinMode(ledPin, OUTPUT);
// инициализируем пин, подключенный к кнопке, как вход
pinMode(buttonPin, INPUT);
Serial.begin(9600);
}
void blink1sec ()
{
// здесь будет код, который будет работать постоянно
// и который не должен останавливаться на время между переключениями свето
unsigned long currentMillis = millis();
//проверяем не прошел ли нужный интервал, если прошел то
if(currentMillis - previousMillis > 1000) {
// сохраняем время последнего переключения
previousMillis = currentMillis;
// если светодиод не горит, то зажигаем, и наоборот
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// устанавливаем состояния выхода, чтобы включить или выключить светодиод
digitalWrite(ledPin, ledState);
}
}
void blink500mills ()
{
// здесь будет код, который будет работать постоянно
// и который не должен останавливаться на время между переключениями свето
unsigned long currentMillis = millis();
//проверяем не прошел ли нужный интервал, если прошел то
for (int counter = 0; counter <=20; counter++)
{
if(currentMillis - previousMillis > 100)
{
// сохраняем время последнего переключения
previousMillis = currentMillis;
// если светодиод не горит, то зажигаем, и наоборот
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// устанавливаем состояния выхода, чтобы включить или выключить светодиод
digitalWrite(ledPin, ledState);
}
}
}
void blinkDelay ()
{
for (int counter = 0; counter <=20; counter++)
{
digitalWrite (ledPin, HIGH);
delay (500);
digitalWrite (ledPin, LOW);
delay (500);
}
}
void loop()
{
buttonState = digitalRead(buttonPin); // считываем значения с входа кнопки
Serial.println (buttonState);
// проверяем нажата ли кнопка
// если нажата, то buttonState будет HIGH:
if (buttonState == LOW) {
// выпоняет текущую программу
blink1sec ();
}
else {
// выполняем аварийную программу
blink500mills ();
//blinkDelay();
}
}
Сравните две функции, они отличаются принципиально, во второй используется цикл, который сделан неправильно. Потому что как только current достигнет previous, то все кончится, сравнение их всегда будет возвращать true.
И вообще, цикл там не правильный. В цикле проверяется, прошло ли 100 мс от начала цикла. И почему проверка производится только 20 раз? Вы считаете, что один цикл длится 100 мс? Вы ошибаетесь.
Чтобы не зависеть от кнопки, проверьте функции без проверки нажатия кнопки. Раздельно
void setup() { pinMode(13, OUTPUT); } void loop() { int x = millis()%1000; digitalWrite(13, !(x-x%500)); }Параллельные условия для ног
афтар dimax .Красиво, понравилось . Где-то и maksim использовал подобную красоту. Спасибо ребята .Жжете.
Бесстындо стырил, разобрался и пользуюсь .
Мож не в тему? Ну сорри тоды...
Можно и еще проще
void setup() { pinMode(13, OUTPUT); } void loop() { digitalWrite(13, millis()%1000 < 500); }nikolaki, а я эту идею позаимствовал у нашего форумчанина KVADIK :) Сам активно пользуюсь оператором "%" но до такой комбинации не додумался-бы..
Процентный остаток очень удобно использовать при раздроблении числа, например есть
int a , b, c, d, num; num = 5836; // далее дробление
if (num > 999) {a = (num - (num % 1000)) / 1000; num = num % 1000;} else { a = 0;} if (num > 99) { b = (num - (num % 100)) / 100; num = num % 100;} else {b = 0;} if (num > 9) {c = (num - (num % 10)) / 10; num = num % 10;} else {c = 0;} d = num;в итоге a = 5 , b = 8 , c = 3 , d = 6 , так дробится четырёхзначное число.