+1 голос

Добрый день.

Есть схема 4 светодиода и 1 кнопка

Есть функций проверки кнопки на дребезг и кол-во нажатий. Все классически, с ней проблем никаких нет.

В функции loop узнаю номер нажатий (0-2). И в зависимости от номера хочу вызывать 3 функции, банально

1ая что все 4 светодиода одновременно зажигаются и гаснут

2ая зажигаются по очереди слева направо

3ая зажигаются по очереди справа налево

Выходит следующее, тоже все классически

void reg2(){
for (int i  = 0; i < 4; i++){
digitalWrite(leds[i], HIGH);
delay(100);
}
delay(500);
for (int i  = 0; i < 4; i++){
digitalWrite(leds[i], LOW);
}
delay(500);
}

Но из-за того что в моих функциях есть delay все идет не по плану*(

Вот на примере этого кусочка как избавиться от delay который делают паузу между включением/выключением соседа и пауза между циклами.

Насколько это сложно?

Спасибо.

(6 баллов) 1 3
А каков план то? И что именно идет не так? Что вижу я в программе: 4 светодиода зажигаются последовательно  через 0.1с, потом горят 0.5с, потом все резко гаснут, потом ... а нафига нужен последний delay(500)? Он по плану?
кнопки опрашивать по таймеру. Тогда не нужен никакой антидребезг. Светодиоды тоже зажигать по таймеру. Для этого создать структуру, внутри которой будет счетчик времени и задатчик периода горения/не горения.

2 Ответы

+2 голосов
 
Лучший ответ

Добавить функцию вместо delay:

bool timer(int period){
unsigned long timer1=millis()+period;
bool changed =0;
while(millis<timer1)
  {
  //опрос кнопок
//если нажата другая кнопка 
//меняем режим 
    cnanged=1;
break;
  }
return changed;
}

в нужном месте кода. функцию.

Вместо 

void reg2(){
for (int i  = 0; i < 4; i++){
digitalWrite(leds[i], HIGH);
delay(100);
}
delay(500);
for (int i  = 0; i < 4; i++){
digitalWrite(leds[i], LOW);
}
delay(500);
}

Вот такую конструкцию:

void reg2(){
for (int i  = 0; i < 4; i++){
digitalWrite(leds[i], HIGH);
if(timer(100)) break;
}
timer(500);
for (int i  = 0; i < 4; i++){
digitalWrite(leds[i], LOW);
}
timer(500);
}

Таким образом вы сможете не пропускать нажатия кнопок. Если в функциях проверки на антидребезг тоже delay , то их надо менять на глобальные таймеры с флагами. 

// где-то до setup
 bool ispres=0;
unsigned long ad_per=0;


//в функции антидребеза 
bool isClick()
{if(digitalRead(pin){

if(ispres&&(ad_per<millis())){
ispres=0;
ad_per=millis+per_antidreb;
return 1;
} else if(!ispres){
ispres=1;
ad_per=millis+per_antidreb;
return 0;
}else{
return 0;
}
}

(2.7 тыс. баллов) 6 17 38
выбран
0 голосов
uint32_t timer;

void reg2(){

for (int i = 0; i < 4; i++){

while(millis()-timer<100) {

digitalWrite(leds[i], HIGH);

}

timer=millis();

}

while(millis()-timer<500) {}

timer=millis();

for (int i = 0; i < 4; i++){

while(millis()-timer<500) {

digitalWrite(leds[i], LOW);

}

timer=millis();

}

}

(51 баллов) 3 10
исправил
Оформите код как код.
uint32_t timer;

void reg2(){

    for (int i = 0; i < 4; i++){

        while(millis()-timer<100) {

            digitalWrite(leds[i], HIGH);

        }

        timer=millis();

    }

    while(millis()-timer<500) {}

    timer=millis();

    for (int i = 0; i < 4; i++){

        while(millis()-timer<500) {

            digitalWrite(leds[i], LOW);

        }

        timer=millis();

    }

}
Добро пожаловать на Бредборд! Сайт вопросов и ответов на тему Arduino, Raspberry Pi и хоббийной электроники в целом. Цель Бредборда — быть максимально полезным. Поэтому мы строго следим за соблюдением правил, боремся с холиворами и оффтопиком.
  1. Aromik

    75 балл(ов)

  2. Un_ka

    54 балл(ов)

  3. parovoZZ

    12 балл(ов)

  4. sser

    6 балл(ов)

  5. Тёмик

    5 балл(ов)

  6. NesteruS

    5 балл(ов)

Награды месяца
1-е место: OLED-дисплей (Troyka-модуль)
2-е место: Графический экран 128×64
3-е место: Текстовый дисплей 16×2 (Troyka-модуль)

...