Опять кнопка

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

Гуглил и по форуму полазил, но решения не нашёл.

Задача вроде и простая, но не получается. Удерживаю кнопку 3 сек - загорается светодиод. Отпускаю - гаснет. А у меня просто вкл- выкл.




int HOLD_DELAY = 3000; 
int ledPin     = 13;      
int switchPin  = 3;
int sw_state = 0;
int sw_laststate = 0;
void setup() {
  pinMode(ledPin, OUTPUT);      
  pinMode(switchPin, INPUT);    
}
void loop(){
  sw_state = digitalRead(switchPin);   
  if (sw_state == HIGH ){
  sw_state = sw_laststate;
  millis()  >= HOLD_DELAY;  
  digitalWrite(ledPin, LOW);
  }
  else {
  digitalWrite(ledPin, HIGH);
  }
}

 

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

Первую ссылку смотрел. По второй вот такой код написал - работает. Спасибо.



int pin = 2;
int led = 13;
unsigned long eventTime=0;
int buttonstate =0;

void setup(){
pinMode(pin, INPUT);
pinMode(led, OUTPUT);
}

void loop(){
int buttonstate=digitalRead(pin);
if(buttonstate==HIGH) eventTime=millis();
if(millis()-eventTime>3000){      
digitalWrite(led, HIGH); 
}
else 
{
digitalWrite(led, LOW); 
}
}

 

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

В начальном положении диоды не горят. Нажал один раз - загорелся первый, нажал второй раз - загорелся второй, первый погас. Опять нажал - оба не горят.



 int regim=1; 
 int flag=0; 

 void setup()   
 { 
 pinMode(4,OUTPUT);    
 pinMode(5,OUTPUT);        
 }
 void loop()
 {       
     if(digitalRead(8)==HIGH&&flag==0)     
     { 
       regim++;   
       flag=1;        
          
     if(regim>3)
     { 
       regim=1;
     }    
     }        
     if(digitalRead(8)==LOW&&flag==1)      
    {           
       flag=0;
    }       
    if(regim==1)
    { 
      digitalWrite(4,LOW);
      digitalWrite(5,LOW);     
    } 
    if(regim==2)
    { 
      digitalWrite(4,HIGH);
      digitalWrite(5,LOW); 
    }       
    if(regim==3) 
    {         
      digitalWrite(5,HIGH);
      digitalWrite(4,LOW);        
    }       
         
 } 

Как в такой код ввести удержание кнопки 3 секунды - горят оба диода, отпустил - погасли не нарушая предыдущей цикличности.

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

При таком подходе нужно инкрементировать regim++;  не при нажатии кнопки, а при ее отпускании.

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

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

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

Не совсем, нажали кнопку, сохранили текущее значение millis(), отпустили кнопку - сравниваем сохраненное и текущее значение millis(), если меньше 3 секунд значит инкрементируем regim++;, а если больше значит делаем что-то еще.

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

Можно например так сделать

unsigned long eventTime = 0;
int regim = 1; 
int flag = 0; 

void setup()   
{ 
  pinMode(4, OUTPUT);    
  pinMode(5, OUTPUT);        
}

void loop()
{       
  if(digitalRead(8) == HIGH && flag == 0)     
  { 
    flag = 1;  
    eventTime = millis();
  } 

  if(digitalRead(8) == HIGH && flag == 1 && millis()-eventTime > 3000) regim = 0;

  if(digitalRead(8) == LOW && flag == 1)      
  {
    flag = 0;   
    if(millis()-eventTime < 3000) regim++;
    if(regim > 3) regim = 1;
  }
  
  switch(regim)
  {
  case 0: 
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH); 
    break; 
  case 1: 
    digitalWrite(4, LOW);
    digitalWrite(5, LOW); 
    break;    
  case 2: 
    digitalWrite(4, HIGH);
    digitalWrite(5, LOW); 
    break;
  case 3:        
    digitalWrite(5, HIGH);
    digitalWrite(4, LOW);     
    break;   
  }       
} 

 

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

Cпасибо maksim. Немного подправил ( в case 2 и case 3 добавил break ) и всё отлично работает.

Нашёл интересную програмку - красивое мерцание светодиода. Если честно, то не могу разобраться как её можно адаптировать в код с кнопками, чтобы мерцал какой нибудь светодиод.  Я с такой структурой прграммы ещё не сталкивался.



int ledPin = 5;      
int value = LOW;   
long cnt = 0;                       // will store last time LED was updated
long low = 0;                      // interval at which to blink (milliseconds)
long high = 1000;             // interval at which to blink (milliseconds)
int op = 3;
long a = 0;
 
void setup()
{
  pinMode(ledPin, OUTPUT);     
}
 
void loop()
{
  a += op; 
  blinkl( a+30, 10 );
  if( a > 200 || a < 0 ) op *= -1;
}
 
void blinkl(long low, long high ) 
{  
  int c = 5;
  while ( c > 0 ) { 
   blink( low, high ); 
   c-=1; 
 }
}
 
void blink( long low, long high ) 
{
  long period = 4000;
  long pt = period * high / (low + high );
  int value = LOW;
  digitalWrite(ledPin, value);
   
  while( period > 0 ) {    
    if (period < pt && value == LOW ) {  
      value = HIGH;
      digitalWrite(ledPin, value);      
    }      
    period -= 1;
  }  
}

 

savdm
Offline
Зарегистрирован: 03.02.2015

решено в др. теме. Прошу удалить моё сообщение.