Работа с кнопками. В помощь новичку.

Nec132113
Offline
Зарегистрирован: 17.11.2014

vvadim пишет:

переделал

long previousMillis = 0; 
int val=0; 
int state = 0; 

void setup()    
{       
  pinMode(13, OUTPUT); 
} 

void loop() 
{ 
  if(digitalRead(14) == HIGH && state == 0)     //если кнопка нажата ... 
  { 
    state = 1;
  }
  if (state == 1)
  {
    digitalWrite(13,HIGH);                     // вкл. светодиод   
    if (millis() - previousMillis >500)    
    { 
      previousMillis = millis();     
      val++; 
    } 
    if(val >= 40) 
    { 
      digitalWrite(13,LOW);    // выкл. светодиод
      state = 0;
      val = 0; 
    } 
  }
}

 

Огромное спасибо, что помогли и не отказали все работает вот теперь мне понятен алгоритм, респект и уважение!!!!!

vvadim
Offline
Зарегистрирован: 23.05.2012

только не забываем о дребезге контактов кнопки

KiVor
Offline
Зарегистрирован: 05.10.2015

Всем привет! Изучаю Ардуино и программирование только месяц. 

Дабы не плодить темы, прошу помощи... В предыдущем посту, к примеру, есть скетч работы таймера по принципу: "нажал, светик горит, таймер пошел, отсчитался и выключилось". Отличное применение если делать проходной выключатель. А вот у меня появилась идея применить это к рольставням.

Дано: 2 светодиода, одна кнопка.

Логика: нажимаем, горит первый светик, пошел отсчет к приммеру 10 сек. По истечению гаснит. Но если нажал досрочно, светик потух досрочно. Ещё нажатие, загорается уже второй светик. И так же что бы можно было досрочно выключить. и Циклично все это.

Помогите пожалуйста как можно это сделать?

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

KiVor, вот примено так, кнопка включает и выключает  попеременно то один, то другой светодиод.

#define timer 10000
boolean pin_flag, work;
uint32_t offtime=0;
  
void setup() {
Serial.begin(9600);
pinMode(13,OUTPUT); pinMode(12,OUTPUT);
pinMode(A5,INPUT_PULLUP);
}
void loop(){

if (digitalRead(A5)==LOW){
  if(work){ 
           work=0; digitalWrite(13,LOW); digitalWrite(12,LOW); 
          }
     else { 
           if (pin_flag)  digitalWrite(12,HIGH);
           if (!pin_flag)  digitalWrite(13,HIGH); 
           pin_flag=!pin_flag;
           offtime=millis() + timer; work=1;
           }
    delay(200); //простое от дребезга
   }
if (millis() > offtime){ digitalWrite(13,LOW); digitalWrite(12,LOW);
 }
}
smoke297
Offline
Зарегистрирован: 09.10.2015

 Тоже на ассемблере весом в 60 байт 

Просто для примера как это выглядит на ассемблере ;-)

 .def temp =r17
 
 rjmp init
 
 
 init:
 ldi temp,0b00000110
 out DDRB,temp
 ldi temp,0b00011001
 out PortB,temp
 clr temp
 rjmp start
 
 
 
 start:
 sbic PinB,0   ;проверка кнопки
 rjmp start    ;не нажата? возращаемся
 rjmp butt     ;нажата, переходим
 
 butt:
 
 sbis PinB,0   ;кнопка отпущена?
 rjmp butt     ;нет, ждем
 rjmp Pr       ;да, переходим
  
 Pr:
 inc temp     ; за каждый проход записываем в темп +1  чтобы знать состояние светодиодов
 cpi temp,1  ;
 breq L1       ;       
 cpi temp,2   ;смотрим чему равен темп, туда и переходим
 breq L2       ;
 cpi temp,3   ;
 breq L3       ;
 
 L1:
sbi PortB,1       ;включаем светодиод 1
  rjmp start    ; и возращаемся
 L2:
 sbi PortB,2    ;включаем светодиод 2
 cbi PortB,1     ;выключаем светодиод 1
 rjmp start
L3:
cbi PortB,1     ;выключаем светодиод 1,2
cbi PortB,2
clr temp         ;очищаем темп 
rjmp start
 
 
 
bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

smoke297 пишет:

 Тоже на ассемблере весом в 60 байт 

Получается ассемблер всех уделывает по размеру, самые меленькте hex.

Поморгать светодиодом на тини13

arduini IDE  214байт!((((

#include <avr/delay.h>
void setup() {DDRB |= 1<<4; }
void loop() {
PORTB |= 1 << 4;_delay_ms(100);   
PORTB &= ~(1 << 4);_delay_ms(100);}

Atmel Studio 218байт((

#include <avr/io.h>
#include <avr/delay.h>

int main(void)
{
DDRB |= 1<<4;	
    while(1)
    {
       PORTB |= 1 << 4;
	   _delay_ms(100);
       PORTB &= ~(1 << 4);
	   _delay_ms(100);
    }
}

 

melnibo
Offline
Зарегистрирован: 28.11.2015

ну хорошо кнопка так кнопка, вот на этом примере


int regim=1; 
 int flag=0; 

 void setup()   
 { 
    pinMode(10,OUTPUT);    
 pinMode(9,OUTPUT);    
       
 } 

 void loop() 

 { 
       
     if(digitalRead(14)==HIGH&&flag==0)//если кнопка нажата   
     // и перемення flag равна 0 , то ... 
     { 
       regim++;   
       flag=1; 
         
        //это нужно для того что бы с каждым нажатием кнопки 
        //происходило только одно действие 
        // плюс защита от "дребезга"  100% 
          
        if(regim>4)//ограничим количество режимов 
        { 
          regim=1;//так как мы используем только одну кнопку, 
                    // то переключать режимы будем циклично 
        } 
       
     } 
       
      if(digitalRead(14)==LOW&&flag==1)//если кнопка НЕ нажата 
     //и переменная flag равна - 1 ,то ... 
     { 
          
        flag=0;//обнуляем переменную "knopka" 
     } 
      
       
       
    if(regim==1)//первый режим 
    { 
      digitalWrite(9,LOW);//выключаем все светодиоды 
      digitalWrite(10,LOW); 
        
        
      //здесь может быть любое ваше действие 
    } 
    if(regim==2)//второй режим 
    { 
      digitalWrite(10,HIGH);//включае красный светодиод 
      digitalWrite(9,LOW); 
        
      //здесь может быть любое ваше действие 
    } 
      
    if(regim==3)//третий режим 
    { 
        
      digitalWrite(9,HIGH);//включае зеленый светодиод 
      digitalWrite(10,LOW); 
        
        
      //здесь может быть любое ваше действие 
    } 
      
    if(regim==4)//четвертый режим 
    { 
        
      digitalWrite(9,HIGH);//включаем светодиоды одновременно 
      digitalWrite(10,HIGH); 
      //здесь может быть любое ваше действие 
    } 
      
 } 

 

как его изменить, чтоб однократное нажатие кнопки включало, выключало светодиод, а удержание кнопки выводило в режим меню

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Добрый день!

Требуется помощь в программировании. UNO  и Keypad Shield. Есть автомат подачи воды с внешним прерыванием. Требуется изменять время подачи кнопкой. Но не знаю как остановить программу. В итоге все время выводится 1 секунда.

/**
  * Автомат подачи воды с регулировкой времени
  * Сенсор стеклянный или пластик 
  */
 //Объявляем библиотеки

  #include <LiquidCrystal.h>
 LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
 //декларируем переменные для брызгалки с прерыванием
 #define button 2    // кнопка
 #define relay  6    // реле 2
 volatile byte flag=0;
 unsigned long prevmillis;

  void setup()
 {
  pinMode(12, OUTPUT);
  digitalWrite(12, HIGH);
  //Инициализация LCD
  lcd.begin(16, 2);
 
  // Печать приветствия на  LCD.
  
  lcd.print("    VODOLEY ");
   lcd.setCursor(0, 1);
  lcd.print("podacha vodi");
  delay(5000);
  lcd.clear();
  //режимы pin
    pinMode(button,INPUT_PULLUP);    // кнопка на вход  вкл.подтягивающий резистор. 
    pinMode(relay,OUTPUT);           // реле на брызгалку 
   attachInterrupt(0, my_func, FALLING); //прерывание на изменение логич. уровня
 }

  void loop()
 {
   int x;
    x = analogRead (0);
   int time;
   time=1;  
   lcd.setCursor(0, 0);
   lcd.print ("TIME: ");
   lcd.print (time);
   lcd.print (" sec");
   //Регулировка времени подачи
   if (x < 200) {
        (time++);
        lcd.setCursor(0, 0);
        lcd.print ("TIME: ");
        lcd.print (time);
        lcd.print ("sec");
      }
   else if (time>= 6){
         (time=1);
      }
   
      
   
  if (1 == flag)
  { // если кнопку отпустили
    prevmillis = millis();
    digitalWrite(relay,HIGH); //включаем реле
    flag = 2;
  }
  
  if (2 == flag)
  {
    if ( millis()-prevmillis >=time*1000)
    {   //если счёт time вышел, то
      digitalWrite(relay,LOW);   //отключаем воду
      flag=0; //сбрасываем флаг работы
    }
  }
}

void my_func() { //отжали
flag=1; //ставим флаг что работа идёт..
}

 

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

melnibo 

"как его изменить, чтоб однократное нажатие кнопки включало, выключало светодиод, а удержание кнопки выводило в режим меню"

Ваш код на правильность не проверял но принцып я думаю Вы поймете: При клике - диоды, при удержании более 0.5сек  regim = 0, а там делайте что хотите


int regim=1; 
 int flag=0;
unsigned long x; //Переменная для прошедшего периода 

 void setup()   
 { 
    pinMode(10,OUTPUT);    
 pinMode(9,OUTPUT);    
       
 } 

 void loop() 

 { 
       
     if(digitalRead(14)==HIGH&&flag==0)//если кнопка нажата   
     // и перемення flag равна 0 , то ... 
     { 
         
       flag=1; 
	x = millis();
         
        //это нужно для того что бы с каждым нажатием кнопки 
        //происходило только одно действие 
        // плюс защита от "дребезга"  100% 
     } 
       
      if(digitalRead(14)==LOW&&flag==1)//если кнопка НЕ нажата 
     //и переменная flag равна - 1 ,то ... 
     { 
          
        flag=0;//обнуляем переменную "knopka" 
	regim++; 
	if(regim>4)//ограничим количество режимов 
        { 
          regim=1;//так как мы используем только одну кнопку, 
                    // то переключать режимы будем циклично 
        } 
     } 
      
     if (digitalRead(14)==HIGH&&flag==1) // Здесь проверяем удержание
     {
       if(millis() - x >=500)
	{
	 regim = 0;	
	}
     } 

	if (regim ==0)
	{
	  // Вот здесь входите в ВАШЕ меню
	} 
       
    if(regim==1)//первый режим 
    { 
      digitalWrite(9,LOW);//выключаем все светодиоды 
      digitalWrite(10,LOW); 
        
        
      //здесь может быть любое ваше действие 
    } 
    if(regim==2)//второй режим 
    { 
      digitalWrite(10,HIGH);//включае красный светодиод 
      digitalWrite(9,LOW); 
        
      //здесь может быть любое ваше действие 
    } 
      
    if(regim==3)//третий режим 
    { 
        
      digitalWrite(9,HIGH);//включае зеленый светодиод 
      digitalWrite(10,LOW); 
        
        
      //здесь может быть любое ваше действие 
    } 
      
    if(regim==4)//четвертый режим 
    { 
        
      digitalWrite(9,HIGH);//включаем светодиоды одновременно 
      digitalWrite(10,HIGH); 
      //здесь может быть любое ваше действие 
    } 
      
 } 

 

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Вячеслав151 Зачем Вы строчки 47,54,  time  заключили в скобки () попробуйте убрать их

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Скобки ничего не меняют

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

поставил флаги, все равно крутит loop бесконечно в единицу

 /**
  * Автомат подачи воды с регулировкой времени
  * Сенсор стеклянный или пластик 
  */
 //Объявляем библиотеки

  #include <LiquidCrystal.h>
 LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
 //декларируем переменные для брызгалки с прерыванием
 #define button 2    // кнопка
 #define relay  6    // реле 2
 volatile byte flag=0;
 unsigned long prevmillis;
 int flag1=0; //Для регулировки времени
  void setup()
 {
  pinMode(12, OUTPUT);
  digitalWrite(12, HIGH);
  //Инициализация LCD
  lcd.begin(16, 2);
 
  // Печать приветствия на  LCD.
  
  lcd.print("    VODOLEY ");
   lcd.setCursor(0, 1);
  lcd.print("podacha vodi");
  delay(5000);
  lcd.clear();
  //режимы pin
    pinMode(button,INPUT_PULLUP);    // кнопка на вход  вкл.подтягивающий резистор. 
    pinMode(relay,OUTPUT);           // реле на брызгалку 
   attachInterrupt(0, my_func, FALLING); //прерывание на изменение логич. уровня
 }

  void loop()
 {
   int x;
    x = analogRead (0);
   int time;
   time=1;  
   lcd.setCursor(0, 0);
   lcd.print ("TIME: ");
   lcd.print (time);
   lcd.print (" sec");
   //Регулировка времени подачи
   if (x < 200&&flag1==0) {
       flag1=1; 
       time++ ;
        
        lcd.setCursor(0, 0);
        lcd.print ("TIME: ");
        lcd.print (time);
        lcd.print ("sec");
      }
   else if (time>= 6){
         (time=1);
      }
   
      
   
  if (1 == flag)
  { // если кнопку отпустили
    prevmillis = millis();
    digitalWrite(relay,HIGH); //включаем реле
    flag = 2;
  }
  
  if (2 == flag)
  {
    if ( millis()-prevmillis >=time*1000)
    {   //если счёт time вышел, то
      digitalWrite(relay,LOW);   //отключаем воду
      flag=0; //сбрасываем флаг работы
    }
  }
}

void my_func() { //отжали
flag=1; //ставим флаг что работа идёт..
}

 

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014
Почему 1? вариантов может быть несколько:
1) Неправильно определена кнопка.
2) вот здесь if (x < 200) {
                time++
у Вас плюсование идет без задержки с высокой скоростью в итоге получаем больше 6 а когда отпускаем кнопку вот этот код 
else if (time>= 6){
         time=1
сбрасует time к 1. Вывод проверить кнопку и сделать задержку при додавании приблизительно так
if (x < 200) {
        (time++);
        lcd.setCursor(0, 0);
        lcd.print ("TIME: ");
        lcd.print (time);
        lcd.print ("sec");
        if (time>= 6)time=1;
        delay(200);
      }

 

 

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Там внешнее прерывание, поэтому delay не стал забивать.

Почему на флаги не реагирует?

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Вячеслав 151 Я стараюсь Вам помочь а Вы даже попробовать не хотите чтобы найти причину. Не подходит делай можно поставить милис если ошибка в этом. Нужно пробовать. С флагами я выложу вот такой скетч. Пробуйте

 #include <LiquidCrystal.h>
 LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
 //декларируем переменные для брызгалки с прерыванием
 #define button 2    // кнопка
 #define relay  6    // реле 2
 volatile byte flag=0;
 unsigned long prevmillis;
 int flag1=0; //Для регулировки времени
int flag2=0;

  void setup()
 {
  pinMode(12, OUTPUT);
  digitalWrite(12, HIGH);
  //Инициализация LCD
  lcd.begin(16, 2);
 
  // Печать приветствия на  LCD.
  
  lcd.print("    VODOLEY ");
   lcd.setCursor(0, 1);
  lcd.print("podacha vodi");
  delay(5000);
  lcd.clear();
  //режимы pin
    pinMode(button,INPUT_PULLUP);    // кнопка на вход  вкл.подтягивающий резистор. 
    pinMode(relay,OUTPUT);           // реле на брызгалку 
   attachInterrupt(0, my_func, FALLING); //прерывание на изменение логич. уровня
 }

  void loop()
 {
   int x;
    x = analogRead (0);
   int time;
   time=1;  
   lcd.setCursor(0, 0);
   lcd.print ("TIME: ");
   lcd.print (time);
   lcd.print (" sec");
   //Регулировка времени подачи
   if (x < 200&&flag2==0) {
       flag2=1; 
       time++ ;
        if (time>= 6)time=1;
        lcd.setCursor(0, 0);
        lcd.print ("TIME: ");
        lcd.print (time);
        lcd.print ("sec");
      }
   else if (x > 200 && flag2==0) flag2 = 0;
      
   
      
   
  if (1 == flag)
  { // если кнопку отпустили
    prevmillis = millis();
    digitalWrite(relay,HIGH); //включаем реле
    flag = 2;
  }
  
  if (2 == flag)
  {
    if ( millis()-prevmillis >=time*1000)
    {   //если счёт time вышел, то
      digitalWrite(relay,LOW);   //отключаем воду
      flag=0; //сбрасываем флаг работы
    }
  }
}

void my_func() { //отжали
flag=1; //ставим флаг что работа идёт..
}

 

Вячеслав 151
Offline
Зарегистрирован: 25.03.2015

Подправил скетч, переставил прерывание для Mega2560, вроде меняется время в цикле, но не знаю как остановить цикл на time++. loop выходит постоянно в 3sec.

 #include <LiquidCrystal.h>
 LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
 //декларируем переменные для брызгалки с прерыванием
 #define button 21    // кнопка для Mega2560
 #define relay  36    // реле для Mega2560
 volatile byte flag=0;
 unsigned long prevmillis;
 int flag1=0; //Для регулировки времени
int flag2=0;

  void setup()
 {
 // Serial.begin(9600);
 // pinMode(12, OUTPUT);
 // digitalWrite(12, HIGH);
  //Инициализация LCD
  lcd.begin(16, 2);
 
  // Печать приветствия на  LCD.
  
   lcd.print("    VODOLEY ");
   lcd.setCursor(0, 1);
   lcd.print("podacha vodi");
   delay(5000);
   lcd.clear();
  //режимы pin
    pinMode(button,INPUT_PULLUP);    // кнопка на вход  вкл.подтягивающий резистор. 
    pinMode(relay,OUTPUT);           // реле на брызгалку 
   attachInterrupt(2, my_func, FALLING); //прерывание на изменение логич. уровня
 }

  void loop()
 {
   int x;
    x = analogRead (0);
   int time;
   time=3;  
   
   lcd.setCursor(0, 0);
   lcd.print ("TIME: ");
   lcd.print (time);
   lcd.print (" sec");
  // delay(2000);
   //Регулировка времени подачи
   if (x < 200&&flag2==0) {
       flag2=1; 
       time++ ;
       
       lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print ("TIME: ");
        lcd.print (time);
        lcd.print (" sec");
        delay(1000);
       
   } 
   
  if (1 == flag)
  { // если кнопку отпустили
    prevmillis = millis();
    digitalWrite(relay,HIGH); //включаем реле
    flag = 2;
  }
  
  if (2 == flag)
  {
    if ( millis()-prevmillis >=time*1000)
    {   //если счёт time вышел, то
      digitalWrite(relay,LOW);   //отключаем воду
      flag=0; //сбрасываем флаг работы
    }
  }
}

void my_func() { //отжали
flag=1; //ставим флаг что работа идёт..
}

 

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

37 - строчка постоянно задает time=3; Если хотите стартовать с time=3 - 

37 удалите а в 36 запишите static int time=3;

62 - строчка исправте flag2=0;

54 - строчка delay(1000);  зачем? если флаг стоит.

svjatoy.alex
Offline
Зарегистрирован: 06.12.2015
const int inPin1 = 2;  // кнопка 2 порт 2
const int inPin2 = 3;  // кнопка 2 порт 3
const int inPin3 = 4;  //кнопка  3 порт 4

const int ledPin1 =  13;    // порт 13, для светодиода
const int ledPin2 =  12;    //порт 12 для светодиода
const int ledPin3 =  11;    //порт 11 для светодиода
int flag=0;


void setup()
{
  // Установим порты кнопок как входящие:
  pinMode(inPin1, INPUT);
  pinMode(inPin2, INPUT);
  pinMode(inPin3, INPUT);

  // Установим порт светодиода как исходящий:
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);  
}

void loop()
{
{
  {
    if(digitalRead(3)==HIGH&&flag==0)//
  {
    flag=1; 
  }
    if(digitalRead(3)==LOW&&flag==1)
  {
    digitalWrite(12,!digitalRead(12));
     flag=0;
  }
	   
	     
{
     

	    if(digitalRead(2)==HIGH&&flag==0)//
  {
    flag=1; 
  }
    if(digitalRead(2)==LOW&&flag==1)
  {
    digitalWrite(13,!digitalRead(13));
     flag=0;
  }
	   

	     
{
     

	     if(digitalRead(4)==HIGH)//если кнопка нажата ...

	     {

	     digitalWrite(11,LOW);//включаем светодиод

	     }

	     else//если не нажата...

	     {
     digitalWrite(11,HIGH);//выключаем

	     }

}
}
}
}
}

добрй вечер. такой вопрос что-то я никак не уловлю что делать. по коду выше у меня получилось что кнопки 3 и 2 приходиться дерать около 2 секунд чтоб произошло действие. а если переделываем кнопку 2 в кнопку 4(просто моргать по нажатию) то кнопка 3 начинает работать нормально тоесть нажал и сразу же отпусти и диод загорелся. не надо держать долго.

 

подскажите может я какю переменную не знаю, но как сделать чтоб все две кнопки срабатывали по нажатию а не по удержанию?

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

flag должен быть свой для каждой кнопки, а не один на всех. 

Какой смысл в строках 1-7, если они не используются в loop?

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Чтото Вы столько много скобок на ставили, попробуйте так. А строчки 1-7 он в setup использовал

const int inPin1 = 2;  // кнопка 2 порт 2
const int inPin2 = 3;  // кнопка 2 порт 3
const int inPin3 = 4;  //кнопка  3 порт 4

const int ledPin1 =  13;    // порт 13, для светодиода
const int ledPin2 =  12;    //порт 12 для светодиода
const int ledPin3 =  11;    //порт 11 для светодиода
int flag = 0;


void setup()
{
  // Установим порты кнопок как входящие:
  pinMode(inPin1, INPUT);
  pinMode(inPin2, INPUT);
  pinMode(inPin3, INPUT);

  // Установим порт светодиода как исходящий:
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
}

void loop()

{

  if (digitalRead(3) == HIGH && flag == 0) //
  {
    flag = 1;
  }
  if (digitalRead(3) == LOW && flag == 1)
  {
    digitalWrite(12, !digitalRead(12));
    flag = 0;
  }


  if (digitalRead(2) == HIGH && flag == 0) //
  {
    flag = 1;
  }
  if (digitalRead(2) == LOW && flag == 1)
  {
    digitalWrite(13, !digitalRead(13));
    flag = 0;
  }


  if (digitalRead(4) == HIGH) //если кнопка нажата ...
  {
    digitalWrite(11, LOW); //включаем светодиод
  }

  else//если не нажата...
  {
    digitalWrite(11, HIGH); //выключаем
  }

}

 

svjatoy.alex
Offline
Зарегистрирован: 06.12.2015

так я просто непонимаю как флаг должен быть для каждой кнопки свой? я вот его и использую с переменными 0 и 1 для каждой кнопки. тут вот я реально непонимаю как флаг для каждой кнопки делать

vvadim
Offline
Зарегистрирован: 23.05.2012

int flag1 = 0;
int flag2 = 0;
int flag3 = 0;
int flag4 = 0;

maksim
Offline
Зарегистрирован: 12.02.2012

http://ru.wikihow.com/%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D1%82%D1%8C-%D1%84%...

int flag1 = 0, flag2 = 0, flag3 = 0, flag4 = 0;

 

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Нафига флагу int? Достаточно byte.

Efremoff
Offline
Зарегистрирован: 11.02.2015

Подскажите, есть ли информация, насколько короткий может быть импульс от нажатия кнопки? т.к. периодически, в достаточно больших кодах, я сталкиваюсь с тем, что короткие нажатия кнопки не отрабатываются контроллером. Кто-то сталкивался с такой проблемой?

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Смотря каким способом обрабатываются кнопки. Если повесить их на прерывание - то должны срабатывать всегда. Если методом поллинга (постоянный опрос состояния кнопок) - то увеличить скорость опроса и избавиться от delay() в коде, если есть.

Efremoff
Offline
Зарегистрирован: 11.02.2015

стоит как обычно, через флаг - 

if (digitalRead(x)== HIGH && flag==0){ 
  flag = 1;
  Нужное действие;
}
else { flag = 0; }

А как повесить на прерывание?

Delay в коде нет, кода на 140 строк всего. Почти все просто в условиях if...else.

 

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Это методом поллинга (постоянного опроса). Покажите весь скетч.

Efremoff пишет:

А как повесить на прерывание?

http://arduino.ru/Reference/AttachInterrupt

Efremoff
Offline
Зарегистрирован: 11.02.2015

В скетче есть 11 условий if...else, которые так же обрабатывают нажатия кнопок, в том числе одновременные нажатия двух кнопок. Эти кнопки нажимаются при необходимости человеком. медленно. И есть одна кнопка (описанная выше), которая нажимается механизмом с достаточно быстрой периодичностью (пока стоит обычный микропереключатель, со временем заменю либо на датчик холла, либо на геркон).

при выполнении условий по нажатию происходят разные действия - запись в память, запись в аналоговый порт, и арифметические действия по + и - к существующим переменным. есть пару Delay внутри циклов, которые относятся к кнопкам пользователя. 

Большая часть результата выводится на LCD, подключенному по I2C. 

Я так понимаю, что у меня просто нажатия попадают иногда в такой момент loop() функции, что программа в этот момент просто опрашивает другие кнопки. Я так понимаю, что в моем случае достаточно будет увеличить время нажатой кнопки, и проблема решится (кнопка срабатывает 3-4 раза в секунду, на длительность около 1/20 секунды, а я могу увеличить хотя бы чтобы нажатие кнопки длилось пол цикла движения механизма - т.е. 1/6 секунды примерно.

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Efremoff пишет:

есть пару Delay внутри циклов, которые относятся к кнопкам пользователя. 

Если в момент работы этих delay() механизм нажмёт на кнопку - она не сработает.

Efremoff пишет:

Я так понимаю, что у меня просто нажатия попадают иногда в такой момент loop() функции, что программа в этот момент просто опрашивает другие кнопки.

Либо делает что-то другое, а пока дойдёт до опроса кнопки - она уже не нажата.

Efremoff пишет:

Я так понимаю, что в моем случае достаточно будет увеличить время нажатой кнопки, и проблема решится (кнопка срабатывает 3-4 раза в секунду, на длительность около 1/20 секунды, а я могу увеличить хотя бы чтобы нажатие кнопки длилось пол цикла движения механизма - т.е. 1/6 секунды примерно.

Возможно и получится, попробуйте.

 

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Вообще ардуиновские функции довольно медленные, иногда приходится работать с регистрами и портами AVR напрямую.

Efremoff
Offline
Зарегистрирован: 11.02.2015

не-не. Delay во время работы не срабатывает. Они добавленны к пользовательским действиям, которые срабатывают при начальной настройке механизма, а нажатие "быстрой" кнопки происходит уже во время работы механизма, после его настроки пользователем. Она просто считает кол-во движений, и все. При достижении заданного кол-ва движений - отключается. так что попробуем увеличить время, при котором кнопка находится в нажатом состоянии. 

Oleg.L.
Offline
Зарегистрирован: 19.08.2014

Доброго времени суток. Ребята не откажите в помощи, очень надо. Хотим сделать сигнализацию на 8 каналов. Алгоритм такой:

1. При появлении на "vhod1" сигнала, на соответствующем выходе "AD1" зажигается и мигает светодиод,

с одновременным включением выхода (в скетче обозначен как "vyhodrele")

2. После нажатия кнопки "kvit" (если входной сигнал не пропал) светодиод зажигается постоянно, а выход  "vyhodrele" - отключается

3. После пропадания сигнала на входе автоматически отключается и светодиод

4. Если через 5 минут после нажатия кнопки  "kvit"  со входа "vhod1" не исчез сигнал , снова включается мигающий светодиод

и включается выход "vyhodrele". 

5. Если прошел кратковременный сигнал на вход схема отработала и после нажатия кнопки "kvit" откл. светодиода и  "vyhodrele"

Каналы не должны зависеть друг от друга и после квитирования на любом из каналов схема готова принять сигнал с любого другого входа.

Я попытался написать скетч на один канал,  пункт  1  работает, пункт 5 работает, пункт 2 работает только при постоянном удержании кнопки "kvit" как-то наверно нужно  "зафиксировать" состояние кнопки? А вот пункт 3 и 4  совсем не "идут" . Подсобите, пожалуйста.

001 int vhod1 = 10;  
002  int vhod2 = 11; 
003  int vhod3 = 12; 
004  int vhod4 = 13; 
005  int vhod5 = A0;  
006  int vhod6 = A1;  
007  int vhod7 = A2;  
008  int vhod8 = A3; 
009  int AD1 = 0;  
010  int AD2 = 1;  
011  int AD3 = 2;  
012  int AD4 = 4;  
013  int AD5 = 5;   
014  int AD6 = 6;    
015  int AD7 = 7;  
016  int AD8 = 8;  
017  int kvit = 9;  
018  int vyhodrele = 3;
019  int flag1 = 0;
020  int flag2 = 0;
021  int flag3 = 0;
022  
023  
024  void setup()
025  {
026  pinMode(vhod1, INPUT_PULLUP); 
027  pinMode(vhod2, INPUT_PULLUP); 
028  pinMode(vhod3, INPUT_PULLUP);
029  pinMode(vhod4, INPUT_PULLUP);
030  pinMode(vhod5, INPUT_PULLUP); 
031  pinMode(vhod6, INPUT_PULLUP); 
032  pinMode(vhod7, INPUT_PULLUP);
033  pinMode(vhod8, INPUT_PULLUP);
034  pinMode(kvit, INPUT_PULLUP); 
035  pinMode(AD1, OUTPUT);
036  pinMode(AD2,OUTPUT);
037  pinMode(AD3, OUTPUT);
038  pinMode(AD4,OUTPUT);
039  pinMode(AD5,OUTPUT);
040  pinMode(AD6,OUTPUT);
041  pinMode(AD7,OUTPUT);
042  pinMode(AD8,OUTPUT);
043  pinMode(vyhodrele, OUTPUT); // выход управления через транзистор звуковым сигналом
044  
045  }
046  
047   void loop()
048  
049  {
050    //Фрагмент 1 , отвечающий за включение и мигание светодиода, а так же включение звукового сигнала  при поступлении
051    // сигнала на vhod1
052        if (digitalRead(vhod1) == LOW &&  digitalRead(kvit) == HIGH)   
053                                                                       
054           {
055            flag1++;
056           }
057           else
058           {
059            flag1=0;
060           }
061        if   ( flag1>=5)
062           
063            {
064            if (digitalRead(AD1) == LOW)
065            digitalWrite(AD1,1);
066            digitalWrite(vyhodrele,1);
067            delay(250);             
068            digitalWrite(AD1, 0);
069            delay(250);         
070           digitalWrite(AD1,1); // чтобы светодиод оставался включенным при кратковременном
071                                //срабатывании сигнала на входе
072           flag1=0;
073           }
074      // Фрагмент 2   должен после нажатия кнопки kvit мигающий светодиод зажечь постоянно,
075     // а выход vyhodrele отключить  
076        
077         if (digitalRead(kvit) == LOW && digitalRead(vhod1) == LOW)
078                                                                   
079              {
080                flag2++;
081              }
082              else
083              {
084              flag2=0;
085              }
086              if  (digitalRead(kvit) == LOW && flag2 >=5 )
087               
088               {
089                 if (digitalRead(vyhodrele) == HIGH)  
090                  digitalWrite(vyhodrele,!digitalRead(vyhodrele));
091                  digitalWrite(AD1,1);      
092                  flag2=0;  
093               }
094             
095                
096         //Фрагмент 3 при пропадании сигнала на входе vhod1 и нажатии на кнопку kvit светодиод и выход vyhodrele отключаются
097           if (digitalRead(kvit) == LOW && digitalRead(vhod1) == HIGH)
098                                                                       
099              {
100                flag3++;
101              }
102              else
103              {
104              flag3=0;
105              }
106              if  (flag3>=5)
107               
108             {
109             digitalWrite(AD1,0);        
110             digitalWrite(vyhodrele,0);  
111             flag2=0;
112             
113             }
114           
115       
116  }

 

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014
Oleg.L.  Вот примерно так для одного канала. Если я правильно понял задачу.
#define vhod1  10
 int vhod2 = 11; 
 int vhod3 = 12; 
 int vhod4 = 13; 
 int vhod5 = A0;  
 int vhod6 = A1;  
 int vhod7 = A2;  
 int vhod8 = A3; 
 bool AD1 = 0;  
 int AD2 = 1;  
 int AD3 = 2;  
 int AD4 = 4;  
 int AD5 = 5;   
 int AD6 = 6;    
 int AD7 = 7;  
 int AD8 = 8;  
 #define kvit 9  
 #define vyhodrele 3
 int flag1 = 0;
 int flag2 = 0;
 int flag3 = 0;
unsigned long time;
unsigned long x; //Переменная для прошедшего периода "led"


 void setup()
 {
 pinMode(vhod1, INPUT_PULLUP); 
 pinMode(vhod2, INPUT_PULLUP); 
 pinMode(vhod3, INPUT_PULLUP);
 pinMode(vhod4, INPUT_PULLUP);
 pinMode(vhod5, INPUT_PULLUP); 
 pinMode(vhod6, INPUT_PULLUP); 
 pinMode(vhod7, INPUT_PULLUP);
 pinMode(vhod8, INPUT_PULLUP);
 pinMode(kvit, INPUT_PULLUP);
 //digitalWrite(kvit, HIGH); 
 pinMode(AD1, OUTPUT);
 pinMode(AD2,OUTPUT);
 pinMode(AD3, OUTPUT);
 pinMode(AD4,OUTPUT);
 pinMode(AD5,OUTPUT);
 pinMode(AD6,OUTPUT);
 pinMode(AD7,OUTPUT);
 pinMode(AD8,OUTPUT);
 pinMode(vyhodrele, OUTPUT); // выход управления через транзистор звуковым сигналом

 }



  void loop()
 {
    if (digitalRead(vhod1) == LOW && flag1 ==0)   
     {
      flag1=1;
      digitalWrite(vyhodrele,1);
      }

     if (digitalRead(vhod1)==HIGH && flag3==1)
      {
       flag1=0;
       flag2=0;
       flag3=0;
       digitalWrite(AD1, 0);
       digitalWrite(vyhodrele,0);
      }

    if ( flag1==1 && flag2 == 0)

     {
       if (x != (millis() / 250))
         {
	   x = millis() / 250;	
	   digitalWrite(AD1, !digitalRead(AD1));
	 }
      }

     if (digitalRead(kvit) == LOW )
      {
         flag2=1;
	 flag3=1;
         digitalWrite(vyhodrele,0);
	 if (digitalRead(vhod1) == LOW)
	  {
	   digitalWrite(AD1, 1);
	   time = millis();
          }
	  
      }

     if (flag1==1 && millis()-time>=300000)
      {
        flag2=0;
	digitalWrite(vyhodrele,1);
      }
 }

 

 

Oleg.L.
Offline
Зарегистрирован: 19.08.2014

Попробовал прописать для второго канала, но теперь если сработал первый канал  работает правильно, но если  нажать кнопку kvit, начинает мигать светодиод второго канала и кнопкой kvit ничего не отключается. Не сочтите за назойливость, поправте, пожалуйста  что не так. Задержку времени я изменил намеренно, чтобы долго не ждать при проверке.

#define vhod1  10
#define vhod2  11 
 int vhod3 = 12; 
 int vhod4 = 13; 
 int vhod5 = A0;  
 int vhod6 = A1;  
 int vhod7 = A2;  
 int vhod8 = A3; 
 bool AD1 = 0;  
 bool AD2 = 1;  
 int AD3 = 2;  
 int AD4 = 4;  
 int AD5 = 5;   
 int AD6 = 6;    
 int AD7 = 7;  
 int AD8 = 8;  
 #define kvit 9  
 #define vyhodrele 3
 int flag1 = 0;
 int flag2 = 0;
 int flag3 = 0;
 int flag4 = 0;
 int flag5 = 0;
 int flag6 = 0;
unsigned long time;
unsigned long time1;
unsigned long x; //Переменная для прошедшего периода "led"
unsigned long y; //Переменная для прошедшего периода "led1"

 void setup()
 {
 pinMode(vhod1, INPUT_PULLUP); 
 pinMode(vhod2, INPUT_PULLUP); 
 pinMode(vhod3, INPUT_PULLUP);
 pinMode(vhod4, INPUT_PULLUP);
 pinMode(vhod5, INPUT_PULLUP); 
 pinMode(vhod6, INPUT_PULLUP); 
 pinMode(vhod7, INPUT_PULLUP);
 pinMode(vhod8, INPUT_PULLUP);
 pinMode(kvit, INPUT_PULLUP);
 //digitalWrite(kvit, HIGH); 
 pinMode(AD1, OUTPUT);
 pinMode(AD2,OUTPUT);
 pinMode(AD3, OUTPUT);
 pinMode(AD4,OUTPUT);
 pinMode(AD5,OUTPUT);
 pinMode(AD6,OUTPUT);
 pinMode(AD7,OUTPUT);
 pinMode(AD8,OUTPUT);
 pinMode(vyhodrele, OUTPUT); // выход управления через транзистор звуковым сигналом

 }



  void loop()
 {
    
   
     if (digitalRead(vhod1) == LOW && flag1 ==0)   
     {
      flag1=1;
      digitalWrite(vyhodrele,1);
      }

     if (digitalRead(vhod1)==HIGH && flag3==1)
      {
       flag1=0;
       flag2=0;
       flag3=0;
       digitalWrite(AD1, 0);
       digitalWrite(vyhodrele,0);
      }

    if ( flag1==1 && flag2 == 0)

     {
       if (x != (millis() / 250))
         {
	   x = millis() / 250;	
	   digitalWrite(AD1, !digitalRead(AD1));
	 }
      }

     if (digitalRead(kvit) == LOW )
      {
         flag2=1;
	 flag3=1;
         digitalWrite(vyhodrele,0);
	 if (digitalRead(vhod1) == LOW)
	  {
	   digitalWrite(AD1, 1);
	   time = millis();
          }
	  
      }

     if (flag1==1 && millis()-time>=3000)
      {
        flag2=0;
	digitalWrite(vyhodrele,1);
      
      }
  //================================ канал 2    
      
   if (digitalRead(vhod2) == LOW && flag4 ==0)   
     {
      flag4=1;
      digitalWrite(vyhodrele,1);
      }

     if (digitalRead(vhod2)==HIGH && flag5==1)
      {
       flag4=0;
       flag5=0;
       flag6=0;
       digitalWrite(AD2, 0);
       digitalWrite(vyhodrele,0);
      }

    if ( flag4==1 && flag5 == 0)

     {
       if (y != (millis() / 250))
         {
	   y = millis() / 250;	
	   digitalWrite(AD2, !digitalRead(AD2));
	 }
      }

     if (digitalRead(kvit) == LOW )
      {
         flag4=1;
	 flag5=1;
         digitalWrite(vyhodrele,0);
	 if (digitalRead(vhod2) == LOW)
	  {
	   digitalWrite(AD2, 1);
	   time1 = millis();
          }
	  
      }

     if (flag4==1 && millis()-time1>=3000)
      {
        flag5=0;
	digitalWrite(vyhodrele,1);   
      }
      
   } 

 

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Методом повтора не получится - Код нужно разбить на функции и вызывать с параметром сработавшего датчика. Скорей всего нужно создать новую тему потому что это уже не про кнопки!

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Пробуйте вот по такому принцыпу

#define vhod1  10
 #define vhod2 11 
 #define vhod3 12 
 #define vhod4 13 
 #define vhod5 A0  
 #define vhod6 A1  
 #define vhod7 A2  
 #define vhod8 A3
 #define  AD1  0  
 #define  AD2  1  
 #define  AD3  2  
 #define  AD4  4  
 #define  AD5  5   
 #define  AD6  6    
 #define  AD7  7  
 #define  AD8  8  
 #define kvit 9  
 #define vyhodrele 3

 bool trevoga1 = 0;
 bool trevoga1a = 0;
 bool trevoga1b = 0;
 
 bool trevoga2 = 0;
 bool trevoga2a = 0;
 bool trevoga2b = 0;
unsigned long time;
unsigned long x; //Переменная для прошедшего периода "led"
unsigned long time1;
unsigned long x1; //Переменная для прошедшего периода "led"



 void setup()
 {
 pinMode(vhod1, INPUT_PULLUP); 
 pinMode(vhod2, INPUT_PULLUP); 
 pinMode(vhod3, INPUT_PULLUP);
 pinMode(vhod4, INPUT_PULLUP);
 pinMode(vhod5, INPUT_PULLUP); 
 pinMode(vhod6, INPUT_PULLUP); 
 pinMode(vhod7, INPUT_PULLUP);
 pinMode(vhod8, INPUT_PULLUP);
 pinMode(kvit, INPUT_PULLUP);
 //digitalWrite(kvit, HIGH); 
 pinMode(AD1, OUTPUT);
 pinMode(AD2,OUTPUT);
 pinMode(AD3, OUTPUT);
 pinMode(AD4,OUTPUT);
 pinMode(AD5,OUTPUT);
 pinMode(AD6,OUTPUT);
 pinMode(AD7,OUTPUT);
 pinMode(AD8,OUTPUT);
 pinMode(vyhodrele, OUTPUT); // выход управления через транзистор звуковым сигналом

 }



  void loop()
 {
    if (digitalRead(vhod1) == LOW && trevoga1 ==0)   
     {
      trevoga1=1;
      digitalWrite(vyhodrele,1);
      }

     if (digitalRead(vhod1)==HIGH && trevoga1b==1)
      {
       trevoga1=0;
       trevoga1a=0;
       trevoga1b=0;
       digitalWrite(AD1, 0);
       digitalWrite(vyhodrele,0);
      }

    if ( trevoga1==1 && trevoga1a == 0)

     {
       if (x != (millis() / 250))
         {
	   x = millis() / 250;	
	   digitalWrite(AD1, !digitalRead(AD1));
	 }
      }

     if (digitalRead(kvit) == LOW )
      {
         trevoga1a=1;
	 trevoga1b=1;
         digitalWrite(vyhodrele,0);
	 if (digitalRead(vhod1) == LOW)
	  {
	   digitalWrite(AD1, 1);
	   time = millis();
          }
	  
      }

     if (trevoga1==1 && millis()-time>=1000)
      {
        trevoga1a=0;
	digitalWrite(vyhodrele,1);
      }
 ///////////////////////////////////////////
if (digitalRead(vhod2) == LOW && trevoga2 ==0)   
     {
      trevoga2=1;
      digitalWrite(vyhodrele,1);
      }

     if (digitalRead(vhod2)==HIGH && trevoga2b==1)
      {
       trevoga2=0;
       trevoga2a=0;
       trevoga2b=0;
       digitalWrite(AD2, 0);
       digitalWrite(vyhodrele,0);
      }

    if ( trevoga2==1 && trevoga2a == 0)

     {
       if (x1 != (millis() / 250))
         {
	   x1 = millis() / 250;	
	   digitalWrite(AD2, !digitalRead(AD2));
	 }
      }

     if (digitalRead(kvit) == LOW )
      {
         trevoga2a=1;
	 trevoga2b=1;
         digitalWrite(vyhodrele,0);
	 if (digitalRead(vhod2) == LOW)
	  {
	   digitalWrite(AD2, 1);
	   time1 = millis();
          }
	  
      }

     if (trevoga2==1 && millis()-time>=1000)
      {
        trevoga2a=0;
	digitalWrite(vyhodrele,1);
      }

 }

 

Oleg.L.
Offline
Зарегистрирован: 19.08.2014

Первый канал работает правильно,  при проверке второго канала срабатывает правильно, но при нажатии кнопки kvit (при наличии сработки на входе)продолжает мигать светодиод 2 канала и не сбрасывается vyhodrele. Но если сигнала на входе не стало- сбрасывается кнопкой kvit.

Вот в  Ваш предыдущий вариант я попробовал вставить по аналогии фрагмент второго канала и вроде как работает. Вот взгляните:

#define vhod1  10
 #define vhod2  11
 #define vhod3  12 
 #define vhod4  13 
 #define vhod5  A0  
 #define vhod6  A1  
 #define vhod7  A2  
 #define vhod8  A3 
 bool AD1 = 0;  
 bool AD2 = 1;  
 bool AD3 = 2;  
 bool AD4 = 4;  
 bool AD5 = 5;   
 bool AD6 = 6;    
 bool AD7 = 7;  
 bool AD8 = 8;  
 #define kvit 9  
 #define vyhodrele 3
 int flag11 = 0;
 int flag12 = 0;
 int flag13 = 0;
 
 int flag21 = 0;
 int flag22 = 0;
 int flag23 = 0;
 
 
 
unsigned long time;

unsigned long a; //Переменная для прошедшего периода "led1"
unsigned long b; //Переменная для прошедшего периода "led2"

 void setup()
 {
 pinMode(vhod1, INPUT_PULLUP); 
 pinMode(vhod2, INPUT_PULLUP); 
 pinMode(vhod3, INPUT_PULLUP);
 pinMode(vhod4, INPUT_PULLUP);
 pinMode(vhod5, INPUT_PULLUP); 
 pinMode(vhod6, INPUT_PULLUP); 
 pinMode(vhod7, INPUT_PULLUP);
 pinMode(vhod8, INPUT_PULLUP);
 pinMode(kvit, INPUT_PULLUP);
 //digitalWrite(kvit, HIGH); 
 pinMode(AD1, OUTPUT);
 pinMode(AD2,OUTPUT);
 pinMode(AD3, OUTPUT);
 pinMode(AD4,OUTPUT);
 pinMode(AD5,OUTPUT);
 pinMode(AD6,OUTPUT);
 pinMode(AD7,OUTPUT);
 pinMode(AD8,OUTPUT);
 pinMode(vyhodrele, OUTPUT); // выход управления через транзистор звуковым сигналом

 }



  void loop()
 {
   
    if (digitalRead(vhod1) == LOW && flag11 ==0)   
     {
      flag11=1;
      digitalWrite(vyhodrele,1);
      }

     if (digitalRead(vhod1)==HIGH && flag13==1)
      {
       flag11=0;
       flag12=0;
       flag13=0;
       digitalWrite(AD1, 0);
       digitalWrite(vyhodrele,0);
      }

    if ( flag11==1 && flag12 == 0)

     {
       if (a != (millis() / 250))
         {
	   a = millis() / 250;	
	   digitalWrite(AD1, !digitalRead(AD1));
	 }
      }

     if (digitalRead(kvit) == LOW )
      {
         flag12=1;
	 flag13=1;
         digitalWrite(vyhodrele,0);
	 if (digitalRead(vhod1) == LOW)
	  {
	   digitalWrite(AD1, 1);
	   time = millis();
          }
	  
      }

     if (flag11==1 && millis()-time>=3000)
      {
        flag12=0;
	digitalWrite(vyhodrele,1);
      }
      
      
      //============================== канал2
      
     if (digitalRead(vhod2) == LOW && flag21 ==0)   
     {
      flag21=1;
      digitalWrite(vyhodrele,1);
      }

     if (digitalRead(vhod2)==HIGH && flag23==1)
      {
       flag21=0;
       flag22=0;
       flag23=0;
       digitalWrite(AD2, 0);
       digitalWrite(vyhodrele,0);
      }

    if ( flag21==1 && flag22 == 0)

     {
       if (b != (millis() / 250))
         {
	   b = millis() / 250;	
	   digitalWrite(AD2, !digitalRead(AD2));
	 }
      }

     if (digitalRead(kvit) == LOW )
      {
         flag22=1;
	 flag23=1;
         digitalWrite(vyhodrele,0);
	 if (digitalRead(vhod2) == LOW)
	  {
	   digitalWrite(AD2, 1);
	   time = millis();
          }
	  
      }

     if (flag21==1 && millis()-time>=3000)
      {
        flag22=0;
	digitalWrite(vyhodrele,1);
      } 
      
        
 }

Как Вы считаете добавив по аналогии 3, 4 каналы и тд. Будет работать?

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Если работает значит хорошо, только типы переменных смените так как у меня в последнем посте AD-define, flag-bool

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Вот подправил свой - работает. Посмотрите

#define vhod1  10
 #define vhod2 11 
 #define vhod3 12 
 #define vhod4 13 
 #define vhod5 A0  
 #define vhod6 A1  
 #define vhod7 A2  
 #define vhod8 A3
 #define  AD1  0  
 #define  AD2  1  
 #define  AD3  2  
 #define  AD4  4  
 #define  AD5  5   
 #define  AD6  6    
 #define  AD7  7  
 #define  AD8  8  
 #define kvit 9  
 #define vyhodrele 3

 bool trevoga1 = 0;
 bool trevoga1a = 0;
 bool trevoga1b = 0;
 
 bool trevoga2 = 0;
 bool trevoga2a = 0;
 bool trevoga2b = 0;
unsigned long time;
unsigned long x; //Ïåðåìåííàÿ äëÿ ïðîøåäøåãî ïåðèîäà "led"
unsigned long time1;
unsigned long x1; //Ïåðåìåííàÿ äëÿ ïðîøåäøåãî ïåðèîäà "led"



 void setup()
 {
 pinMode(vhod1, INPUT_PULLUP); 
 pinMode(vhod2, INPUT_PULLUP); 
 pinMode(vhod3, INPUT_PULLUP);
 pinMode(vhod4, INPUT_PULLUP);
 pinMode(vhod5, INPUT_PULLUP); 
 pinMode(vhod6, INPUT_PULLUP); 
 pinMode(vhod7, INPUT_PULLUP);
 pinMode(vhod8, INPUT_PULLUP);
 pinMode(kvit, INPUT_PULLUP);
 //digitalWrite(kvit, HIGH); 
 pinMode(AD1, OUTPUT);
 pinMode(AD2,OUTPUT);
 pinMode(AD3, OUTPUT);
 pinMode(AD4,OUTPUT);
 pinMode(AD5,OUTPUT);
 pinMode(AD6,OUTPUT);
 pinMode(AD7,OUTPUT);
 pinMode(AD8,OUTPUT);
 pinMode(vyhodrele, OUTPUT); // âûõîä óïðàâëåíèÿ ÷åðåç òðàíçèñòîð çâóêîâûì ñèãíàëîì

 }



  void loop()
 {
    if (digitalRead(vhod1) == LOW && trevoga1 ==0)   
     {
      trevoga1=1;
      digitalWrite(vyhodrele,1);
      }

     if (digitalRead(vhod1)==HIGH && trevoga1b==1)
      {
       trevoga1=0;
       trevoga1a=0;
       trevoga1b=0;
       digitalWrite(AD1, 0);
       digitalWrite(vyhodrele,0);
      }

    if ( trevoga1==1 && trevoga1a == 0)

     {
       if (x != (millis() / 250))
         {
	   x = millis() / 250;	
	   digitalWrite(AD1, !digitalRead(AD1));
	 }
      }

     if (digitalRead(kvit) == LOW )
      {
         trevoga1a=1;
	 trevoga1b=1;
         digitalWrite(vyhodrele,0);
	 if (digitalRead(vhod1) == LOW)
	  {
	   digitalWrite(AD1, 1);
	   time = millis();
          }
	  
      }

     if (trevoga1==1 && millis()-time>=1000)
      {
        trevoga1a=0;
	digitalWrite(vyhodrele,1);
      }
 ///////////////////////////////////////////
if (digitalRead(vhod2) == LOW && trevoga2 ==0)   
     {
      trevoga2=1;
      digitalWrite(vyhodrele,1);
      }

     if (digitalRead(vhod2)==HIGH && trevoga2b==1)
      {
       trevoga2=0;
       trevoga2a=0;
       trevoga2b=0;
       digitalWrite(AD2, 0);
       digitalWrite(vyhodrele,0);
      }

    if ( trevoga2==1 && trevoga2a == 0)

     {
       if (x1 != (millis() / 250))
         {
	   x1 = millis() / 250;	
	   digitalWrite(AD2, !digitalRead(AD2));
	 }
      }

     if (digitalRead(kvit) == LOW )
      {
         trevoga2a=1;
	 trevoga2b=1;
         digitalWrite(vyhodrele,0);
	 if (digitalRead(vhod2) == LOW)
	  {
	   digitalWrite(AD2, 1);
	   time = millis();
          }
	  
      }

     if (trevoga2==1 && millis()-time>=1000)
      {
        trevoga2a=0;
	digitalWrite(vyhodrele,1);
      }

 }

 

Oleg.L.
Offline
Зарегистрирован: 19.08.2014

vosara, поясните, не совсем соображу фрагмент с миганием светодиода:

if (x != (millis() / 250))   
         {
  x = millis() / 250;
 
вот в примере ниже понятно как ежесекундно мигает светодиод
 
currentTime = millis();                           // считываем время, прошедшее с момента запуска программы
  if(currentTime >= (loopTime + 1000)){              // сравниваем текущий таймер с переменной loopTime + 1 секунда
    digitalWrite(ledPin, !digitalRead(ledPin));     // включаем/выключаем LED
    loopTime = currentTime;  // присваиваем новое значение таймера

и так по кругу...

 

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Смысл такойже только считается по другому, 250 это задержка в мс. Можете вместо милис подставить любое число и на калькуляторе посмотреть как оно работает 

Mazur
Offline
Зарегистрирован: 13.01.2016

Нпрод можете подсказать по работе с кнопкой?!

Есть две кнопки и одиин светодиод. Как повесить один светодиод на две кнопки?

На кнопку 1 нажал светодиод загорелся, на кнопку 2 нажал - выключился и на оборот

нажал на кнопку 2 - включился, на кнопку 1 выключился. 

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Тупо инвертировать состояние светодиода при нажатии любой из этих кнопок.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013
if (digitalRead(BTN1) || digitalRead(BTN2)) digitalWrite(LED, (!digitalRead(LED)));

 

Mazur
Offline
Зарегистрирован: 13.01.2016

Jeka_M пишет:

Тупо инвертировать состояние светодиода при нажатии любой из этих кнопок.

 

Что то я не понял... Так что ли?!

void setup() 
 { 

 pinMode(12, OUTPUT); 

 } 

 void loop() 

 { 
 if(digitalRead(8)==LOW)//если кнопка не нажата ... 
 { 
 digitalWrite(12,HIGH);//включаем светодиод 
 } 
 else//если нажата... 
 { 
 digitalWrite(12,LOW);//выключаем 
 } 
 if(digitalRead(9)==LOW)//если кнопка не нажата ...
 {
 digitalWrite(12,!digitalRead(12));//инвертируем состояние пина
 
 delay(500);//небольшая защита от "дребезга" контактов кнопки
 }


 }

 

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

 delay(500);//небольшая защита от "дребезга" контактов кнопки

это большая защита и не от дребезга

miha
Offline
Зарегистрирован: 24.01.2016

Добрый день.

Помогите пожалуйста разобраться с программой. На Mega подключено две кнопки ( pin 41 и 43 ) . При нажатии на кнопку (41) должны загораться два светодиода на pin 47 и 53 на 5 секунд. При нажатии на кнопку на pin 43 должны загораться светодиоды на pin 51 и 53 на 10 секунд. Но получается что во втором случае светодиод на pin 53 гаснет через 5 сек. а на pin 51 через 10 сек. Подскажите пожалуйста где ошибка.

int flag=0;
int flag1=0;
unsigned long cmillis;
unsigned long i=5000;
void setup() {
   pinMode (41, INPUT);
   pinMode (43, INPUT);
  pinMode (47, OUTPUT);
  pinMode (53, OUTPUT);
  pinMode (51, OUTPUT);

  
}

void loop() {

  if ((digitalRead(41)==HIGH)&&(flag==0)){
    cmillis=millis();
    digitalWrite(47,!digitalRead(47));
    digitalWrite(53,!digitalRead(53));
    flag=1;
  }
    if (millis()-cmillis>i){
      digitalWrite(47,LOW);
      digitalWrite(53,LOW);
      flag=0;
      
    }
      if (digitalRead(41)==LOW&&flag==1){
        flag=0;
      }
      
  if ((digitalRead(43)==HIGH)&&(flag1==0)){
    cmillis=millis();
    digitalWrite(51,!digitalRead(51));
    digitalWrite(53,!digitalRead(53));
    flag1=1;
  }
    if (millis()-cmillis>i+5000){
      digitalWrite(51,LOW);
      digitalWrite(53,LOW);
      flag1=0;
      
    }
      if (digitalRead(43)==LOW&&flag1==1){
        flag1=0;
      }
}

 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

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

Вот скелет алгоритма, защиту от дребезга добавь сам.

#define btn41  41
#define btn43  43
#define led47  47
#define led51  51
#define led53  53
const unsigned long periodBtn41 = 5000; // длительность включения LED по нажатии Btn41
const unsigned long periodBtn43 = 10000;
unsigned long timeoutLED47;  // переменная для расчета времени отключения LED47
unsigned long timeoutLED51;
unsigned long timeoutLED53;

void setup() 
{
  pinMode (btn41, INPUT);
  pinMode (btn43, INPUT);
  pinMode (led47, OUTPUT);
  pinMode (led51, OUTPUT);
  pinMode (led53, OUTPUT);
}

void loop() 
{
  unsigned long currentTime = millis();
  
  // проверяем кнопки
  if (!digitalRead(btn41)) 
  {
    timeoutLED47 = currentTime + periodBtn41;
    timeoutLED53 = currentTime + periodBtn41;
  }
  
  if (!digitalRead(btn43)) 
  {
    timeoutLED51 = currentTime + periodBtn43;
    timeoutLED53 = currentTime + periodBtn43;
  }
  
  // проверяем светодиоды
  if (currentTime < timeoutLED47) digitalWrite(led47, HIGH);
  else digitalWrite(led47, LOW);
  
  if (currentTime < timeoutLED51) digitalWrite(led51, HIGH);
  else digitalWrite(led51, LOW);
  
  if (currentTime < timeoutLED53) digitalWrite(led53, HIGH);
  else digitalWrite(led53, LOW);
}

 

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

А можно исправить Ваш скетч

int flag=0;
int flag1=0;
unsigned long cmillis;
unsigned long i=5000;
void setup() {
   pinMode (41, INPUT);
   pinMode (43, INPUT);
  pinMode (47, OUTPUT);
  pinMode (53, OUTPUT);
  pinMode (51, OUTPUT);

  
}

void loop() {

  if ((digitalRead(41)==HIGH)&&(flag==0)){
    cmillis=millis();
    digitalWrite(47,!digitalRead(47));
    digitalWrite(53,!digitalRead(53));
    flag=1;
  }
    if (millis()-cmillis>i&&flag=1){//Необходимо добавить проверку флага 
      digitalWrite(47,LOW);
      digitalWrite(53,LOW);
      flag=0;
      
    }
      if (digitalRead(41)==LOW&&flag==1){
        flag=0;
      }
      
  if ((digitalRead(43)==HIGH)&&(flag1==0)){
    cmillis=millis();
    digitalWrite(51,!digitalRead(51));
    digitalWrite(53,!digitalRead(53));
    flag1=1;
  }
    if (millis()-cmillis>i+5000&&flag1==1){//Необходимо добавить проверку флага 
      digitalWrite(51,LOW);
      digitalWrite(53,LOW);
      flag1=0;
      
    }
      if (digitalRead(43)==LOW&&flag1==1){
        flag1=0;
      }
}