Помогите с кнопками и светом разобраться

Whynot
Offline
Зарегистрирован: 27.12.2012

В общем проблема банальная не работает управление светодиодом от кнопки

в целом хочется следующего

если жать на кнопку менее 1 сек то светодиод или гаснет или зажигается (смотря что он делел до нажатия)

если нажать дольше 1 сек то плавно гаснет или зажигается

пытаюсь сначала сделать первую часть

int pin = Button; // кнопка
int led = GREEN_LED; // светодиод
unsigned long dur; // длина нажатия

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

void loop(){
  if (pin==HIGH){
    dur = millis(); // тут вроде должно храниться время нажатия
  }
  if (dur<1000){ // если жмем кнопку менее 1 сек то...
    digitalWrite(led,!digitalRead(led)); // зажигаем или гасим диод
  }
}
Проблема в том что диод горит постоянно если  (dur<1000)
и негорит постоянно  (dur>1000)
 
Помогите разобраться
 
maksim
Offline
Зарегистрирован: 12.02.2012

1. Вставка программного кода в тему/комментарий
2. Что такое  Button и GREEN_LED, вы в каком-то эмуляторе пишите?
3. Начните изучение стандартных примеров работы с кнопками: Exemples -> 2.Digital -> ...

 

leshak
Offline
Зарегистрирован: 29.09.2011

Пробема в том что фараза слово "время нажатия" в русском языке является не однозначным. Это может быть как

"точное время когда нажали кнопку" так и "сколько времени держим нажатым". То есть "момент" и "период".

В коде переменную dur вы вначале используете в одном смысле, а потом в другом. Сохраняете "когда нажали", а сравниваете как "сколько времени держим нажатую". Логично что если мы нажали кнопку, предполложим в 13 часов, сорок минут, то это время всегдя больше, скажем "одной минуты".

Вообщем разберитесь где у вас "момент времени", а где "временной интервал". Подсказка: millis() возращает "момент времени", а интервал  уже вычислять самому.

К тому же, когда будете засекать "момент нажатия", обратите внимание что вам нужно засечь именно переход от LOW в HIGH, то есть "начало давления".  Если смотреть просто на HIGH, То у вас по жизни будет "вот только что нажали кнопку".

leshak
Offline
Зарегистрирован: 29.09.2011

Вообщем примерно так:

unsigned long eventTime=0;

void loop(){
   if(УСЛОВИЕ_СОБЫТИЯ) eventTime=millis(); // засекли когда произошло событие

  if(eventTime && (millis()-eventTime>XXXX)){ // проверям прошло ли XXXX миллесекунд с события
      
       ..... что-то делаем по воду этого события ....
        
        eventTime=0; // обнуляем время события, что-бы повторно его не обработать

  }
}

 

В вашем случае, можно обнулять eventTime (или dur) когда кнопку отпустили, а не внутри обработчика события. Что-бы небыло сработок типа "нажали кратко, отпустили, а оно потом через время сработало".

 

Whynot
Offline
Зарегистрирован: 27.12.2012

maksim пишет:

1. Вставка программного кода в тему/комментарий

Увидел тему после того как написал сообщение, хотел исправить но кнопки "редактировать" чтото на форуме нет (или я её незамечаю)

2. Что такое  Button и GREEN_LED, вы в каком-то эмуляторе пишите?

Ну это я написал для того чтобы не путаться у каждого вместо этих значений могут быть свои номера вводов выводов (но я пишу в эмуляторе Energia для MSP430 поэтому кнопку на плате pin 5 заменил на Button, а pin 14 на Green_led)

3. Начните изучение стандартных примеров работы с кнопками: Exemples -> 2.Digital -> ...

 

Whynot
Offline
Зарегистрирован: 27.12.2012

Ну сначала я вцепился в функцию pulseIn

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

и код был такой

int pin = Button;
int led = Green_led;
unsigned long duration;

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

void loop(){
duration = pulseIn(pin, HIGH);
if (duration<2000){
digitalWrite(led, HIGH);
}
else{
  digitalWrite(led, LOW);
}
}

Но в итоге этот код вообще странный т.к. диод горит всегда и гаснет после удержания кнопки нажатой в течении 2-х сек, а при отпускании снова горит и на duration < или > ему вообще пофиг

Whynot
Offline
Зарегистрирован: 27.12.2012

Спасибо!

Но не варит оно, может я чегото конечно не догоняю но

диод горит всегда

int pin = Button;
int led = Green_led;
unsigned long eventTime=0;



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

void loop(){
if(pin==HIGH) eventTime=millis(); // засекли когда произошло событие

  if(millis()-eventTime>5000){ // проверям прошло ли XXXX миллесекунд с события
      
      digitalWrite(led,!digitalRead(led)); 
        
        eventTime=0; // обнуляем время события, что-бы повторно его не обработать

  }
}

 

Whynot
Offline
Зарегистрирован: 27.12.2012

leshak пишет:

К тому же, когда будете засекать "момент нажатия", обратите внимание что вам нужно засечь именно переход от LOW в HIGH, то есть "начало давления".  Если смотреть просто на HIGH, То у вас по жизни будет "вот только что нажали кнопку".

Все понял кроме одного какой оператор осуществляет засекание перехода LOW в High??

step962
Offline
Зарегистрирован: 23.05.2011

Я, со своей стороны, посоветую вам разобраться в отличиях между понятиями "событие" и "состояние". Тогда советы Leshak'а пойдут вам в прок.

А пока что вы проверяете состояние кнопки 100500 раз в секунду и обнаружив на соответствующем пине состояние HIGH (кнопка нажата) радостно регистрирует время наступления события. Пардон, какого? Может быть кнопка у вас вот в сей момент перешла из состояния "отжато" в "нажадо" и тогда телодвижения с регистрацией точного времени имеют под собой основание. А может быть, на нее уже с утра давят не отпуская... Зачем в таком случае засекать время? Ведь события не произошло (=состояние не изменилось).

UPD. Пока я читал-писал, вы уже успели выразить недоумение советом Leshak'а. В таком случае - вперед на изучение упомянутых в первом предложении различий!!!

UPD2. Оператор, засекающий переход LOW->HIGH - вы сами, точнее, написанная вами программа.

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

Whynot пишет:

Спасибо!

Но не варит оно, может я чегото конечно не догоняю но

диод горит всегда

int pin = Button;
int led = Green_led;
unsigned long eventTime=0;



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

void loop(){
if(pin==HIGH) eventTime=millis(); // засекли когда произошло событие

  if(millis()-eventTime>5000){ // проверям прошло ли XXXX миллесекунд с события
      
      digitalWrite(led,!digitalRead(led)); 
        
        eventTime=0; // обнуляем время события, что-бы повторно его не обработать

  }
}

 

Вы думаете, я просто так вас направил сначала изучать стандартные примеры? Покажите в каком месте вашего кода происходит чтение состояния вывода?

Whynot
Offline
Зарегистрирован: 27.12.2012

 

if(pin==HIGH)

я всегда считал что в 13 строке идет чтение состояния

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

Если вам так сложно посмотреть стандартные примеры, сделаю это за вас:

void loop(){
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) {     
    // turn LED on:    
    digitalWrite(ledPin, HIGH);  
  } 
  else {
    // turn LED off:
    digitalWrite(ledPin, LOW); 
  }
}

 

step962
Offline
Зарегистрирован: 23.05.2011

И еще раз напоминаю - вам необходимо не просто считывать состояние, а отслеживать события. В данном конкретном случае - изменение состояния вывода с LOW на HIGH (ну или с HIGH на LOW). Именно от этих событий (моментов их наступления) вы и будете отсчитывать интервалы времени, в зависимости от которых и будете тем или иным способом включать/выключать свои светодиоды.

Но сначала - изучать основы...

Whynot
Offline
Зарегистрирован: 27.12.2012

Мне не сложно вот как раз сидел вкуривал

int pin = 5;
int led = 14;
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>1000){ // проверям прошло ли XXXX миллесекунд с события
      
      digitalWrite(led,!digitalRead(led)); 
        
        eventTime=0; // обнуляем время события, что-бы повторно его не обработать

  }
}

Вроде работает

Но диод рвется гореть

т.е. все работает так

Диод горит

жмем кнопку более 1 сек - гаснет

потом сам зажигается

Как не зажигать диод самопроизвольно?

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

Забудьте пока про время, разберитесь сначала с "событием", там же смотрим пример StateChangeDetection, и пытаемся понять что до вас пытается донести step962.

Whynot
Offline
Зарегистрирован: 27.12.2012

Ну незнаю/непонимаю я, что пытаются мне донести

я в упор не понимаю примера StateChangeDetection

int pin = 5;
int led = 14;
unsigned long eventTime=0;
int buttonstate =0;
int lastButtonState = 0; 
int buttonPushCounter = 0;

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

void loop(){
buttonstate=digitalRead(pin);
if (buttonstate != lastButtonState){

  if(buttonstate==HIGH){
   buttonPushCounter++;
  }
  lastButtonState = buttonstate;
  
  if (buttonPushCounter % 1 == 0) {
  eventTime=millis(); // засекли когда произошло событие

  if(millis()-eventTime>1000){ // проверям прошло ли XXXX миллесекунд с события
      
      digitalWrite(led,!digitalRead(led)); 
        
        eventTime=0; // обнуляем время события, что-бы повторно его не обработать
  }
}
}
}

В итоге этот код не работает

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

maksim
Offline
Зарегистрирован: 12.02.2012
maksim
Offline
Зарегистрирован: 12.02.2012
maksim
Offline
Зарегистрирован: 12.02.2012
int pin = 5;
int led = 14;

int flag = 0;

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

void loop(){
  
  if(digitalRead(pin) == HIGH && flag == 0){ // если кнопка нажата и флаг не установлен, то
    digitalWrite(led, !digitalRead(led)); // переключаем светодиод
    delay(10); // задержка для устранения дребезга
    flag = 1;  // устанавливаем флаг
  }
  if(digitalRead(pin) == LOW){ // если кнопка не нажата, то
    flag = 0; // сбрасываем флаг
  }

}

для дальнейшего написания вам лучше этот пример рассматреть в таком виде

int pin = 5;
int led = 14;

int flag = 0;

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

void loop(){

  if(digitalRead(pin) == HIGH){ // если кнопка нажата
    if(flag == 0){ // и флаг не установлен, то
      digitalWrite(led, !digitalRead(led)); // переключаем светодиод
      delay(10); // задержка для устранения дребезга
      flag = 1;  // устанавливаем флаг
    }
  }
  else{ // если кнопка не нажата, то
    flag = 0; // сбрасываем флаг
  }

}

 

Whynot
Offline
Зарегистрирован: 27.12.2012

Спасибо

буду ссылки читать

leshak
Offline
Зарегистрирован: 29.09.2011

Смотрите что значит "событие перехода из LOW в HIGH"? Это значт что кнопка БЫЛА не нажата, а СТАЛА нажата.

В самом описании событие у нас присусвует и LOW и HIGH значит и в условии должны оба присутсвовать, логично? Два элемента в if проверять нужно "прошлое состояние кнопки" и "текущие состояние кнопки".

Под "прошлое" подразумевается "что мы прочитали при предыдущем опросе кнопки". Если мы опрашиваем кнопку один раз за проход loop, значит "то что мы прочитали при прошлом проходе loop". А значит нужно куда-то сохранять его. Завести еще одну переменную.

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

Whynot
Offline
Зарегистрирован: 27.12.2012
int pin = 5;
int led = 2;

int flag = 0;

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

void loop(){

  if(digitalRead(pin) == LOW){ // если кнопка нажата
    if(flag == 0){ // и флаг не установлен, то
      digitalWrite(led, !digitalRead(led)); // переключаем светодиод
      delay(50); // задержка для устранения дребезга
      flag = 1;  // устанавливаем флаг
    }
  }
  else{ // если кнопка не нажата, то
    flag = 0; // сбрасываем флаг
  }

}

Вот этот код работает хороше

а код с 

  pinMode(led, OUTPUT);
  pinMode(pin, INPUT);
 digitalWrite(pin, HIGH)

Работает хуже

Я вот не понимаю как переход состояния L-H  привязать и замерить длину нажатия

 

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

Вообще-то 

pinMode(pin, INPUT_PULLUP);

и

pinMode(pin, INPUT);
digitalWrite(pin, HIGH);

одно и тоже.

Whynot
Offline
Зарегистрирован: 27.12.2012

Я это понимаю поэтому и удивлен

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

Пока вы не поймете как работает ваш код (#21) вы так и не сможете понять что такое "переход"/"событие" или наоборот. ) Покажите какие строки кода, собственно, и находятся в этом "переходе"/"событии" ?

leshak
Offline
Зарегистрирован: 29.09.2011

 

Whynot пишет:

Я вот не понимаю как переход состояния L-H  привязать и замерить длину нажатия

Во первых "замерить длину" - у вас уже есть пример. Вам нужно разобратся как L-H детектить.

Попробуйте дословно перевести с русского языка в код то что я вам описал #20
 
Переменная "флаг" IMHO тут немного запутывает (хотя можно и через нее, скорее неудачное название). 
 
Лучше оттолнитесь от примера из #11.
 
Вот там у вас уже есть "как считать текущие состояние кнопки". В переменную buttonState.
(только, раз вы начали использовать подтягивающий резистор, то нужно делать !digitalRead()).
 
Теперь осталось, как я уже говорил, завести еще одну переменную куда мы будем сохранять .....
а ладно, черт с ним, вот:
 
#define PIN_BUTTON 2

byte prevButtonState=0;


void loop(){
  // читаем состояние кнопки, buttonState==TRUE - кнопка нажата
  byte buttonState=!digitalRead(PIN_BUTTON); // уберите восклицательный знак если кнопка притянута к земле
  
  
  if(!prevButtonState && buttonState){ // перешли из "не нажато", в "нажато"
     // что-то делаем по этому поводу, засекаем момент нажатия и т.п.
  };
  
  if(prevButtonState && !buttonState){ // перешли из "нажато", в "не нажато"
    // что-то делаем по этому поводу. Обнуляем "момент нажатия", сбрасываем флаги и т.п.
  }
  
  
  prevButtonState=buttonState; // запомнили на следующий проход loop()-а какое у нас было состояние
}

 

 

Whynot
Offline
Зарегистрирован: 27.12.2012
if(digitalRead(pin) == LOW){ // если кнопка нажата
    if(flag == 0){ // и флаг не установлен, то
           flag = 1;  // устанавливаем флаг
      else{ // если кнопка не нажата, то
    flag = 0; // сбрасываем флаг

Насколько я понимаю событие -это манипуляции с flag

leshak
Offline
Зарегистрирован: 29.09.2011

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

Вот фраза "лампочка горит" - это событие или состояние? "включение лампочки" - это событие или состояние?

Без четкого улавливание разницы этих двух вещей - трудно писать/понимать код.

Whynot
Offline
Зарегистрирован: 27.12.2012

"лампочка горит" -  состояние

"включение лампочки" - это событие

но как я считаю - для меня важно состояние кнопка нажата и длительность этого состояния

Я вот набросал нерабочий код как заготовку чего хочу добиться (пока на {} и ; не обращайте внимания)

 

int pin = 5; // кнопка
int led = 14; // диод
unsigned long eventTime=0; //время начала события
unsigned long eventStopTime=0;// время окончания события
byte Time=0; //храним длину события в byte т.к. он имеет значение 0...255 это нужно для fade (кстати как из unsigned long перейти в byte?)
int buttonstate =0; // состояние кнопки
int fadeValue = 0;// для fade
int prevButtonState=0;  // состояние кнопки 


void setup(){
pinMode(pin, INPUT_PULLUP);
pinMode(led, OUTPUT);

}

void loop(){
int buttonstate=digitalRead(pin); //смотрим на кнопку
if(!prevButtonState && buttonState){ // перешли из "не нажато", в "нажато"
    eventTime=millis(); // засекли когда произошло событие
  };
  
  if(prevButtonState && !buttonState){ // перешли из "нажато", в "не нажато"
   eventStopTime=millis(); // засекли когда окончилось событие
  }
  
  
  prevButtonState=buttonState; // запомнили на следующий проход loop()-а какое у нас было состояние
}
 if(eventTime-eventStopTime<1000)  // проверям прошло ли XXXX миллесекунд с события до его окончания
{
 if(prevButtonState== 0){ // и флаг не установлен, то
      digitalWrite(led, !digitalRead(led)); // переключаем светодиод
      delay(50); // задержка для устранения дребезга
      prevButtonState= 1;  // устанавливаем флаг
else{ // если кнопка не нажата, то
    prevButtonState= 0; // сбрасываем флаг
      
    }
  }
 
  }
if(eventTime-eventStopTime>1000&&prevButtonState== 0)  // проверям прошло ли XXXX миллисекунд с события до его окончания и флаг не установлен, то

<strong><em>/* тут мне неясно как взять только 3 сек  - типа в течении 3 сек свет плавно нарастает а потом достигает максимума и дальше хоть удержись кнопку, ничего не происходит*/</em></strong>

 time=eventTime-eventStopTime;
 for(int fadeValue = 0 ; fadeValue <= time/11; fadeValue +=5) { //делим 3000 милисек на 255 равно 11,76. берем 11 и зажигаем свет в зависимости от времени удержания кнопки
    // sets the value (range from 0 to 255):
    analogWrite(led, fadeValue);         
     prevButtonState= 1;  // устанавливаем флаг                 
  } 

if(eventTime-eventStopTime>1000&&flag == 1) ){ // тут смотрим горит ли свет по flag и гасим его
  // fade out from max to min in increments of 5 points:
  for(int fadeValue = 255 ; fadeValue >=  time/11; fadeValue -=5) { 
    // sets the value (range from 0 to 255):
    analogWrite(led, fadeValue);         
    prevButtonState= 0;             
 
else{ // если кнопка не нажата, то
    prevButtonState= 0; // сбрасываем флаг
      eventTime=0; // обнуляем время события, что-бы повторно его не обработать
      eventStopTime=0; 
}

 

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

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

Whynot
Offline
Зарегистрирован: 27.12.2012

вообще тут уже всем кажется ясно что я не понимаю

что за фронт сигнала такой и бьюсь об это как в закрытую дверь 

кнопка либо true или false, что за непонятное состояние полунажатия????

вы же не со знанием этой потаенной истины родились!? Где хоть это обьясняется?? Где почитать о этом?

 

то что мне написал step962

" пока что вы проверяете состояние кнопки 100500 раз в секунду и обнаружив на соответствующем пине состояние HIGH (кнопка нажата) радостно регистрирует время наступления события. Пардон, какого? Может быть кнопка у вас вот в сей момент перешла из состояния "отжато" в "нажадо" и тогда телодвижения с регистрацией точного времени имеют под собой основание. А может быть, на нее уже с утра давят не отпуская... Зачем в таком случае засекать время? Ведь события не произошло (=состояние не изменилось)."

кажется мне вполне логичным

да я проверяю состояние кнопки если кнопку нажали регистрирую время нажатия -логично

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

step962
Offline
Зарегистрирован: 23.05.2011

Whynot пишет:

вообще тут уже всем кажется ясно что я не понимаю

что за фронт сигнала такой и бьюсь об это как в закрытую дверь 

Первая же ссылка в Яндексе по магическому поисковому запросу "фронт сигнала" - тыц.

Цитата:

кнопка либо true или false, что за непонятное состояние полунажатия????

Наверное, все же не состояние полунажатия, а переход из одного состояния в другое, т.е. пресловутый "фронт сигнала"?

Цитата:

вы же не со знанием этой потаенной истины родились!? Где хоть это обьясняется?? Где почитать о этом?

Ровно так же поступаем и с другими непонятными словосочетаниями.

leshak
Offline
Зарегистрирован: 29.09.2011

Дам совет, но вряд ли вы сможете его послушатся (я бы не послушался): отложите все на день два. Пойдите прогуляйте на лыжах (или другая физ. нагрузка), а потом вернетесь к задаче. Без сарказма говорю. Серьезно. Состояние "ушел в тупняки" бывает у каждого и регулярно. А когда одновременно 5-ть человек пытаются что-то объяснить - это вообще не удивительно. Нужно просто отвлечься отдохнуть.

Когда вернетесь: не нужно искать "тайные знания". Банальная логика и здравый смысл. Представте себе что вы контроллер которому нужно выполнять скетч. Попробуйте в голове выполнить. Представить что происходит когда кнопка нажата, какие значения имеет каждая переменная при первом проходе loop, при втором. Нажали кнопку, еще парочку раз в голове "прокрутили".

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

Делаем File/New. И пытаемся решить задачу "если кнопку держат нажатой больше одной секунды - зажигаем диод, если отпустили - сразу гаснет". Давайте вначале это. Потом досконально понять "как это работает", а потом уже постепенно "усложнять/добавлять" плюшки в него будем.

Что-бы решить эту задача вам нужно "слепить вместе" два кода (практически без добавлений каких-то переменных и т.п.) из сообщения #25 - в нем есть как ловить момент нажатия и отжатия кнопки и сообщения #3 - там пример "как следить за интервалом".  В этих премерах отсутсвует только setup(). Нужно дописать инициализацию светика на выход и подтяжку кнопки вверх.

Попробуйте их "слепить". Постарайтесь воздержатся от введения дополнительных переменных, преобразования типов и т.п. и т.п.

Итак: держим кнопку нажатой более 1 сек - светик загорелся, отпустили - сразу погас.

leshak
Offline
Зарегистрирован: 29.09.2011

Раз уж зацепили "фронт сигнала" - тут опять все проще чем кажется. Просто представте напряжение на каком-то контакте как "уровень воды". Когда он меняется от  нуля до 5v и обратно "поднялся/опустился" - это похоже на "прошла волна".  Передний край этой "волны" назовут "фронтом", а задний - спадом. Вот и все. Просто предствте обычную волну на мелководье. Вы сидите в какой-то точке и меряете глубину (напряжение) и поверх вас прокатываетяс цунами. "Вот все пипец" (резкое наростание грубины) - это фронт, "фух. вроде попускает" - спад ;)

По ссылке на википедию которую дал step962 все замечательно видно на картинке.

1 — низкий уровень сигнала,2 — высокий уровень сигнала,3 — нарастание сигнала (передний фронт), 4 — спад сигнала (задний фронт)
 

 

 

 

 

Единсвенное что они не добавили для полного понимания - это оси координат. Что-бы было понятно что это горафик функции напряжение от времени V(t). Мысленно дорисуйте их сами. По вертикали - это напряжения на пине, а по горизонтали - время .

Update: смотрите на код из #25. Строка 11 ловит точки (3), а строка 15 ловит точки (4). 
Код из сообщения  #3 замеряет текущую длину "плато" (2)

 

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

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

У меня такой вопрос - вы понимаете что функция loop, в которой находится ваша программа повторяется несколько сотен тысяч, а иногда и несколько миллионов раз в секунду?
 

leshak
Offline
Зарегистрирован: 29.09.2011

maksim пишет:

Вам нужно всего лишь понять смысл протого механизма называемого тригером

Да шо же вы делаете? :) У человека и так информационный перегруз. А вы все новые слова подкидываете. Ему же кажется что это "еще что-то" с чем нужно разобратся, а не что это все время одну и ту же вещь называют разными именами пытаясь объяснить.

Максим, представте что вы нормальный человек. А нормального человека  слово "триггер" - пугает :) Да еще и "разных видов бывают" (ну ваще!!!!)

Offtop: меня вот убивает использование слово "транзакция" в инструкциях к банкоматам. Я не могу себе вообразить как какая-то бабушка с пенсией на карточке сможет это когда-нибудь понять. Я сомневаюсь что хотя-бы 10% самих банковских работников точно и правильно понимают значение этого слова (обычно путают с "проводкой"). Даже не каждый програмер, в зависимости от области деятельности, точно понимает (если не работает с базами, ORM и т.п.). А тут его используют "для работяг получающих зарплату".

Whynot
Offline
Зарегистрирован: 27.12.2012

Да' я понимаю что loop крутится как колесо с высокой частотой и что помимо состояния low и high будет несколько сотен циклов непонятно чего (пока кнопка нажимается) 

меня путают стандартные примеры где рассмотрено нажатие кнопки и светодиод

там все просто if(pin, high){digitalwrite(led,high)

else (led,low)

Все! В примерах никто не заморачивается фронтами  , а потом появляется пример StateChangeDetection с каимито счетчиками

в итоге я смотрю на это И вижу

2х2=4 пример 1

g(x) = f '(x)/f(x) пример 2

Те пример один предельно прост а пример два предельно сложен и прочитать про середину просто негде

 

 

 

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

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

leshak
Offline
Зарегистрирован: 29.09.2011

Whynot пишет:

Все! В примерах никто не заморачивается фронтами  , а потом появляется пример StateChangeDetection с каимито счетчиками

Ну да. Там же не делают "разрыва во времени". Как нажали - так и засветили. Важно только "текущие состояние кнопки". Поэтому никаких "время событие", попыток различать вид события (нажали или отпустили), никаких "а что у нас было перед этим" и т.п.

Мы хотим "чуть позже". Нажатие кнопки - в один момент, а действия по этому поводу - в другой. Поэтому и приходится "покупать часы" (millis()), запоминать время и т.п.

Whynot пишет:

в итоге я смотрю на это И вижу

2х2=4 пример 1

g(x) = f '(x)/f(x) пример 2

Те пример один предельно прост а пример два предельно сложен и прочитать про середину просто негде

Это скорее вы пытаетесь "перепрыгнуть" :) Посмотрите в предыдущих постах я предложил вам упрощенную задачу. А "серединные" примеры, обычно сам человек разбирается. Путем комбинирования нескольких простых. Только вот их суть - нужно понять, а не "сразу бежать в сложное". Сделатте парочку 2x2, 3x3, 3x2  . Вы только "посмотрели" 2x2, а сами 3x3, 3x2 не сделали :) Сразу за f'(x) взялись :)

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

В вашем случае нет никакой середины, есть самый первый проход "колеса" когда кнопка только нажалась/отпустилась, тоесть в примере if(pin, high){digitalwrite(led,high) пока вы держите кнопку на led так и будет каждый раз посылаться сигнал high, хотя это нужно сделать только один раз. 

void loop() {
  if(pin == high){
    if(prev_pin == low){
      digitalwrite(led, high);
      prev_pin = high;
  }
}

 

Whynot
Offline
Зарегистрирован: 27.12.2012

Подтвердите мою догадку 

о том что контроллер понимает, что событие произошло, когда сравнивает предыдущее и текущее состояние кнопки

и если эти состояния отличаются то это и есть "событие" 

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

Все верно, только это не "контроллер понимает", а вы так пишите код, вы создаете механизм, который работает по вашему алгоритму.

Whynot
Offline
Зарегистрирован: 27.12.2012

Спасибо 

Наконецто до меня дошло 

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

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