#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
Сообщений: 481

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
Сообщений: 490

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
Сообщений: 330

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
Сообщений: 330

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

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

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

Selen
Участник
Зарегистрирован: 2017-01-02
Сообщений: 71

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

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

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

Green
Участник
Зарегистрирован: 2015-11-08
Сообщений: 490

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
Сообщений: 490

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
Сообщений: 71

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

Быстрое сообщение

Введите сообщение и нажмите Отправить

Подвал раздела