Ожидание выполнения функции
- Войдите на сайт для отправки комментариев
Пт, 16/03/2018 - 20:17
Вопрос по программе. Есть лента с управляемыми светодиодами. Функция loop ожидает завершение выполнения кода - функции RainbowCycle (радуга). Необходимо по нажатию кнопки немедленно ее прервать и начать другую функцию (ту же RainbowCycle но с задержкой). Оператор break не помогает, условие в цикле функции - тоже.
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == LOW) {
rainbowCycle(); //Функция без задержки
} else {
rainbowCycleDelay(); //Функция с задержкой
}
}
//Функция без задержки
void rainbowCycle() {
uint16_t i, j;
for(j=0; j<256 && buttonState == LOW; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels() && buttonState == LOW; i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
}
}
//Функция с задержкой
void rainbowCycleDelay() {
uint16_t i, j;
for(j=0; j<256 && buttonState == HIGH; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels() && buttonState == HIGH; i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
delay(1);
strip.show();
}
}
Что не так делаю?
покажите код, как вы добавляли "условие в цикле", которое не сработало. Только выложите код как положено http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii
Добавлю просто как текст пока, чтобы было понятно - выделил жирным
for(j=0; j<256 && buttonState == LOW; j++) { // 5 cycles of all colors on wheel
for(j=0; j<256 && buttonState == HIGH; j++) { // 5 cycles of all colors on wheel
1. Переменная buttonState - глобальная?
2. Какая кнопка (тактовая. с фиксацией. сенсор) и как подключена (на Лоу или на Хай. есть ли подтяжка)
Переменная заводилась как глобальная - в самом начале кода. Запись в нее идет в цикле loop - состояние кнопки.
А кнопка на данный момент это просто 2 проводка, которые я замыкаю. Они работают исправно, без наводок - подключены через светодиодный пин - 13. Он загорается когда замыкаю. Пробовал другие программы - реагируют нормально. Подтяжки нет. Но дело ведь не в этом, плата реагирует на контакт. Сам цикл ждет окончания выполнения функции.
Если речь именно об этом скетче, то Вы уверены, что замечаете задержку в одну миллисекунду? Может у Вас вполне всё переключается?
В loop() , проверяйте кнопку. Если она не нажата - просто вызывайте rainbowCycle() с параметром j, который в будет увеличиваться в loop(). Если нажата - делайте то, что называете "прерыванием эффекта". Или делайте в лупе delay(delayTime) после вызова rainbowCycle(). Нажата кнопка - одно значение delayTime, не нажата - другое.
Если этого хватит, то ок. Нет - нужно проводить более серьёзную операцию с миллисами и стейтмашиной.
Да. Я вижу разницу, она просто отрабатывает не сразу. Если ставить задержку в 2 мс, то цикл будет выполнятся медленнее и соответственно ждать придется дольше
Можно пример кода с параметром j?
И не понял насчет Delay. Что это должно мне дать? Задержки мне и так хватает сейчас..
Пример:
Думаю, что цикл с j вы сумеете сами выкинуть из функции. И проверки buttonState тоже.
Далее почитайте статью "blink без delay" и модифицируйте соответсвенно код. Тогда всё будет почти мгновенно работать.
Вроде правильно сделал. Огоньки теперь не бегут вообще. А продвигаются разово на несколько позиций при зажатии контактов. А так стоят на месте.
Про то что делэй лучше не использовать - я знаю. Но в данной программе он практически не останавливает выполнение кода.
Не знаю, что вы там сделали, но если правильно - то должно работать.
А... Вобщем, нужно один только rainbowCycle() оставить - они же только дилеем отличаются. Его, оставленного, и вызывать.
Второй RainbowCycle у меня больше не вызывается. Вот код (название функции другое):
Я же просил вас выкинуть проверки buttonState, а вы оставили. Они и изначально там не нужны были.
должны медленно меняться, пока кнопку держите. Как отпускаете - все остановилось, так?
Ну а что вы хотели - оно так и должно быть. Вам же сказали условие buttonState == HIGH из цикла выкинуть, а вы не послушали.
Ой. Извиняюсь. Забыл убрать. Теперь всё работает, спасибо!
Объясните, почему цикл не останавливался по условию или по break'у?
А, понял. У меня же состояние кнопки только в loop считывается.
В общем сделал я таки по своему. Просто вместо ButtonState прописал digitalRead(buttonPin), чтобы состояние всегда было актуальным. Из второго цикла убрал эту проверку. Моя невнимательность.. Спасибо еще раз.