#1 2018-03-05 14:41:20

radio-active
Учасник
Зареєстрований: 2017-03-31
Повідомлень: 10

Помогите с нажатием на кнопку (удержание)

Есть скетч.
Он управляет светом.
1-й режим - ходовые огни
2-й и 3-й - стробоскопы.

В машине при включении ксенона идет помеха, которая как то попадает в сериал порт и дает ложное собрание.
Ни кондеры ни резисторы ни дроселя - не помогают
Выход один - назначить действие на удержание, но у меня это не получается и все, помогите:

int led1 = 6;
int led2 = 7;
int led3 = 8;
int led4 = 9;

int lighton = 4;
int val=1, stope=1;
long previousMillis = 0;
int buttonState = 0; 
long interval = 300;

void setup() {
Serial.begin(9600); 
   delay(2);
pinMode(2, INPUT);
digitalWrite(2, HIGH);

pinMode (led1, OUTPUT);
pinMode (led2, OUTPUT);
pinMode (led3, OUTPUT);
pinMode (led4, OUTPUT);

digitalWrite(led1, HIGH);
digitalWrite(led2, HIGH);
digitalWrite(led3, HIGH);
digitalWrite(led4, HIGH);
  
pinMode (lighton, INPUT); // Вход для выключателя DRL от фар
digitalWrite(lighton, HIGH);
attachInterrupt(0, buttonPin, FALLING);
while(!Serial);
}

void one()
{  
  while(stope==1)
  {  
if (digitalRead(lighton) == LOW)
{
digitalWrite(led1, HIGH);
digitalWrite(led2, HIGH);
digitalWrite(led3, HIGH);
digitalWrite(led4, HIGH);
}


if (digitalRead(lighton) == HIGH) //Если подается +12 с зажигания - ДХО горят
{
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, HIGH);
digitalWrite(led4, HIGH);
}
  if(Serial.available() > 0) stope = Serial.parseInt();
} 
}

void two()
{
  while(stope==1)
  {
  digitalWrite(led1, HIGH);
  digitalWrite(led2, LOW);
  digitalWrite(led3, HIGH);
  digitalWrite(led4, LOW);
  delay(300);
  digitalWrite(led1, LOW);
  digitalWrite(led2, HIGH);
  digitalWrite(led3, LOW);
  digitalWrite(led4, HIGH);
  delay(300);
  if(Serial.available() > 0) stope = Serial.parseInt();
  }
}
void three()
{
    while(stope==1)
  {
    digitalWrite(led1, HIGH);
    digitalWrite(led3, HIGH);
        delay(40);
    digitalWrite(led1, LOW);
    digitalWrite(led3, LOW);
        delay(40);
    digitalWrite(led1, HIGH);
    digitalWrite(led3, HIGH);
        delay(40);
    digitalWrite(led1, LOW);
    digitalWrite(led3, LOW);
        delay(40);
    digitalWrite(led1, HIGH);
    digitalWrite(led3, HIGH);
        delay(40);
    digitalWrite(led1, LOW);
    digitalWrite(led3, LOW);
        delay(40);
    digitalWrite(led1, HIGH);
    digitalWrite(led3, HIGH);
        delay(40);
    digitalWrite(led1, LOW);
    digitalWrite(led3, LOW);
        delay(40);
    digitalWrite(led1, HIGH);
    digitalWrite(led3, HIGH);
        delay(40);
    digitalWrite(led1, LOW);
    digitalWrite(led3, LOW);
        delay(40);
    digitalWrite(led1, HIGH);
    digitalWrite(led3, HIGH);
        delay(40);    
 
    
    digitalWrite(led2, HIGH);
    digitalWrite(led4, HIGH);
        delay(40);
    digitalWrite(led2, LOW);
    digitalWrite(led4, LOW);
        delay(40);
    digitalWrite(led2, HIGH);
    digitalWrite(led4, HIGH);
        delay(40);
    digitalWrite(led2, LOW);
    digitalWrite(led4, LOW);
        delay(40);
    digitalWrite(led2, HIGH);
    digitalWrite(led4, HIGH);
        delay(40);
    digitalWrite(led2, LOW);
    digitalWrite(led4, LOW);
        delay(40);
    digitalWrite(led2, HIGH);
    digitalWrite(led4, HIGH);
        delay(40);
    digitalWrite(led2, LOW);
    digitalWrite(led4, LOW);
        delay(40);
    digitalWrite(led2, HIGH);
    digitalWrite(led4, HIGH);
        delay(40);
    digitalWrite(led2, LOW);
    digitalWrite(led4, LOW);
        delay(40);  
    digitalWrite(led2, HIGH);
    digitalWrite(led4, HIGH);
        delay(40);     
   
    
    if(Serial.available() > 0) stope = Serial.parseInt();
  }
  }
  
void loop() 
{
if(Serial.available() > 0) val = Serial.parseInt();
switch(val)
{
  case 1:stope=1; one();break;
  case 2:stope=1; two();break;
  case 3:stope=1; three();break;  
}
}


void buttonPin()
{
  static unsigned long millis_prev;
  if(millis()-1000 > millis_prev)
  { 
  stope=1;
  delay(50);
  val++;
    delay(50);
  stope=0;
  Serial.println(val);
      if(val==4)val=1;
  }
  millis_prev = millis();        
 
} 

Неактивний

#2 2018-03-06 10:43:46

radio-active
Учасник
Зареєстрований: 2017-03-31
Повідомлень: 10

Re: Помогите с нажатием на кнопку (удержание)

Экранировать пробовал, от части помогло, но не полностью...
Я уже не знаю что пробовать.
Изначально это был проект "по приколу". Вещь - которая не сильно нужна.
Но теперь уже принципиально доделать...

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

Остання редакція radio-active (2018-03-06 10:45:04)

Неактивний

#3 2018-03-06 13:39:57

vvr
Учасник
Зареєстрований: 2015-04-12
Повідомлень: 716

Re: Помогите с нажатием на кнопку (удержание)

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

Активний

#4 2018-03-06 14:14:35

radio-active
Учасник
Зареєстрований: 2017-03-31
Повідомлень: 10

Re: Помогите с нажатием на кнопку (удержание)

vvr пише:

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

Пробовал, причем тут дребезг контактов??? Кнопка отрабатывает четко. Если кнопку не нажимать (даже отключить) и включить фары - идет сработка.

Библиотеку onebutton пробовал, не вышло что то...

Неактивний

#5 2018-03-06 14:26:06

Green
Учасник
Зареєстрований: 2015-11-08
Повідомлень: 588

Re: Помогите с нажатием на кнопку (удержание)

)) Тогда причём кнопка? Найдите источник помехи и устраните. Мудрёно? )

Неактивний

#6 2018-03-06 14:59:54

radio-active
Учасник
Зареєстрований: 2017-03-31
Повідомлень: 10

Re: Помогите с нажатием на кнопку (удержание)

Green пише:

)) Тогда причём кнопка? Найдите источник помехи и устраните. Мудрёно? )

Да, мудрЁно... 4 блока розжига и есть помеха....
Просто подскажите как сделать длинное нажатие, что бы на короткое нажатие не было реакции.
При включении фар идет короткая помеха, которая как то попадает в Serial. И программа расценивает эту помеху за нажатие.
А вот если программа будет ждать длинное нажатие, то на эту помеху не должна сработать....

Неактивний

#7 2018-03-06 15:06:16

radio-active
Учасник
Зареєстрований: 2017-03-31
Повідомлень: 10

Re: Помогите с нажатием на кнопку (удержание)

Ну хоть это, ито не получается интегрировать:

#include "OneButton.h"
OneButton button(2, true);

void setup() {
  button.attachLongPressStart(buttonPin);
  pinMode(13, OUTPUT);  
}

void loop() {
  button.tick();
  delay(10);
}

void buttonPin() {
  digitalWrite(13, HIGH);
}

Неактивний

#8 2018-03-07 12:38:25

renoshnik
Учасник
Зареєстрований: 2017-04-03
Повідомлень: 823

Re: Помогите с нажатием на кнопку (удержание)

нажал - запомнил время 1
отпустил - запомнил время 2
получил разницу время 2 и время 1
если меньше заданного значения - игнорировать

Неактивний

#9 2018-03-07 21:45:12

radio-active
Учасник
Зареєстрований: 2017-03-31
Повідомлень: 10

Re: Помогите с нажатием на кнопку (удержание)

renoshnik пише:

нажал - запомнил время 1
отпустил - запомнил время 2
получил разницу время 2 и время 1
если меньше заданного значения - игнорировать

Да, но я не могу внедрить из за:
attachInterrupt(0, buttonPin, FALLING);

оно мне все портит....

Так скетч отдельно работает:

int T = 0;

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

  void loop()
 {
      if(digitalRead(2)==LOW)//если кнопка нажата ...
      {
        T++;// прибавляем к переменной 1 при каждой смене цикла.
      delay(500);//небольшая защита от "дребезга" контактов кнопки
      }
      else
      {
        T=0;
      }
      if(T>=3)
      {
        digitalWrite(13,!digitalRead(13));//инвертируем состояние пина
        T=0;
      }
 }

А как вставляю в основной код - работает не корректно...

Неактивний

#10 2018-03-08 10:15:11

renoshnik
Учасник
Зареєстрований: 2017-04-03
Повідомлень: 823

Re: Помогите с нажатием на кнопку (удержание)

зачем attachInterrupt(0, buttonPin, FALLING); ???

Неактивний

#11 2018-03-11 12:14:08

Selen
Учасник
Зареєстрований: 2017-01-02
Повідомлень: 87

Re: Помогите с нажатием на кнопку (удержание)

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

Неактивний

#12 2018-03-11 13:03:55

Green
Учасник
Зареєстрований: 2015-11-08
Повідомлень: 588

Re: Помогите с нажатием на кнопку (удержание)

Подозреваю, что человек просто не шарит. Бывает же такое?)

Неактивний

#13 2018-03-12 10:27:43

radio-active
Учасник
Зареєстрований: 2017-03-31
Повідомлень: 10

Re: Помогите с нажатием на кнопку (удержание)

Green пише:

Подозреваю, что человек просто не шарит. Бывает же такое?)

Ну так вы шарящий - подскажите! "Люблю" таких умников на форумах, которые сами нехрена не разбираются, но умничают больше других.

Неактивний

#14 2018-03-12 11:28:07

Green
Учасник
Зареєстрований: 2015-11-08
Повідомлень: 588

Re: Помогите с нажатием на кнопку (удержание)

radio-active пише:

нехрена

научитесь правильно писать сначала.

Неактивний

#15 2018-03-12 12:14:35

Olej
Учасник
З Харьков
Зареєстрований: 2018-03-08
Повідомлень: 234

Re: Помогите с нажатием на кнопку (удержание)

Green пише:
radio-active пише:

нехрена

научитесь правильно писать сначала.

ни хрена?  roll

Неактивний

#16 2018-03-12 21:36:35

Selen
Учасник
Зареєстрований: 2017-01-02
Повідомлень: 87

Re: Помогите с нажатием на кнопку (удержание)

я бы сделал следущее,

для начало избавился бы от делэй и от прерывания. использовал бы таймер -  библиотеку SimpleTimer.h .
долгое нажатие сделал бы тоже через таймер. т.е. нажал кнопку - запустился таймер напр. (на 3 сек.) по окончании таймера выполняется функция где идет проверка не нажата ли кнопка.

Неактивний

#17 2018-03-21 10:37:01

maxmix
Учасник
Зареєстрований: 2018-03-21
Повідомлень: 10

Re: Помогите с нажатием на кнопку (удержание)

завести счетчик, он накручивается пока нажата кнопка, при достижении выполняется код. после выполнения кода обнуляется счетчик.
Ну а если правильно big_smile то лучше взять готовый велосипед и изваять типа:
if ((millis() - buttonTimer > longPressTime) && (longPressActive == false)) {

    longPressActive = true;
    LED1State = !LED1State;
    digitalWrite(LED1, LED1State);

}
longPressTime - переменная где задаш скок надо удерживать чтоб сие чудо сработало
никаких делаев и переполнения переменных. все ок и все сработает



по аппаратному: самый кайфовый метод на сегодня (для меня лично, в условиях жостких помех от ЧПУ) является PC817 последовательно резистор на 3.3 кОм и последовательно светодиод, именно светодиод- индикация которая подскажет что опто работает и не сгорела, так для перестраховки. Это входной контур а выходной естественно с подтяжкой на GND через 10кОм резистор и напрямую к 5V. Когда опто замыкает- на входе в ардуино(или любого другого МК) 5V.
Работает нормально, при чем в очень большом диапазоне от 9v- 26VDC.
Ссори за баламут но еще не обжился, только зарегистрировался smile

Неактивний

#18 2019-11-02 00:40:43

UFO 007
Гість

Re: Помогите с нажатием на кнопку (удержание)

radio-active пише:

Есть скетч.
Он управляет светом...

вобчем смысл такой: обнаружил факт нажатия (защитившись от дребезга deBouncerом) и через delay(500) проверяешь val = digitalRead(кнопка)... Если val = удерживаемой кнопке, то запускаем цикл обработки удержания

#19 2019-11-02 00:48:09

UFO007
Гість

Re: Помогите с нажатием на кнопку (удержание)

И про самодельный тимер:
unsigned long volatile now;

typedef struct {
  unsigned long Start;  // Переменная хранения начального значения счетчика миллисекунд
  unsigned long Period; // Переменная хранения периода таймера
  bool Enable;
} myStructT;
//---------------------------------------------------------------------------------------------------
myStructT OpenTimer;       // привязать коня
...
  OpenTimer.Enable = false;       // только привязать коня = 2,5 мин
  OpenTimer.Period = 150000;   
...
где-то в лупе:
  now = millis();
...
    OpenTimer.Start = now;
    OpenTimer.Enable = true;
ну и соответственно
bool Timer( myStructT T )
{
      if( millis()  >  (T.Start + T.Period) ) 
        return true;
      else
        return false;
}

#20 2019-11-02 07:28:11

Watchdog
Гість

Re: Помогите с нажатием на кнопку (удержание)

UFO007 пише:

И про самодельный тимер: ...

Только UFO007 забыл про тот факт, что значение переменной системного времени чиклическое, с периодом 49,7102696181 суток. И вот это не всегда будет соответствовать действительности:

 if (millis()  >  (T.Start + T.Period)) ...

smile

#21 2019-11-02 08:43:31

vvr
Учасник
Зареєстрований: 2015-04-12
Повідомлень: 716

Re: Помогите с нажатием на кнопку (удержание)

if( millis()  - T.Start > T.Period ) 

великое переполнение миллис)))))

Активний

#22 2019-11-03 00:54:42

Avazart
Учасник
Зареєстрований: 2019-05-05
Повідомлень: 181

Re: Помогите с нажатием на кнопку (удержание)

У Вас бывает период больше чем в ~50 cуток? Нет никакой проблемы переполнения.

Остання редакція Avazart (2019-11-03 00:55:05)

Неактивний

#23 2019-11-03 11:01:24

Kaka
Учасник
Зареєстрований: 2018-03-21
Повідомлень: 384

Re: Помогите с нажатием на кнопку (удержание)

Avazart пише:

У Вас бывает период больше чем в ~50 cуток? Нет никакой проблемы переполнения.

Причём тут период? Если писать как в #19, то проблема возникает с любым периодом, хоть в 1 мс.

Неактивний

#24 2019-11-03 15:34:53

Avazart
Учасник
Зареєстрований: 2019-05-05
Повідомлень: 181

Re: Помогите с нажатием на кнопку (удержание)

Вы имеете ввиду про сложение вместо вычитания?
С вычитанием должно нормально работать.

Остання редакція Avazart (2019-11-03 15:35:47)

Неактивний

#25 2019-11-03 21:05:20

Kaka
Учасник
Зареєстрований: 2018-03-21
Повідомлень: 384

Re: Помогите с нажатием на кнопку (удержание)

Я имею в виду то, что написано в посте №19.

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму