АнтиДребезг. Не пойму - хорошо ли ?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

 Цель: написать подпрограмму раз и навсегда для кнопки, чтобы не искрила... Потом - попытаться всунуть это дело в библиотеку....

Промежуточный результат - не пойму.... Толи хорошо написАл, то-ли тестировал неправильно....

Судите сами, пожста....

/*



// Файл ButtonMagic.h
#ifndef ButtonMagic_h
#define ButtonMagic_h
#include "Arduino.h"   // или  #include "WProgram.h"
class ButtonMagic
{
  public :
    ButtonMagic( int pin ) ;
    byte GetEvent(  ) ;
  private:
    byte _pin; 
} ;
#endif




// Файл ButtonMagic.cpp
#include "Arduino.h"   // или  #include "WProgram.h"
#include "ButtonMagic.h"
ButtonMagic::ButtonMagic( int pin , )
{
  pinMode( pin , INPUT ) ;
  digitalWrite( pin , HIGH ) ;
  _pin = pin ;
}
byte GetEvent( ) ;
{
  boolean A , B ;
  int Event ;
  if ( millis() - BtnMouseLoopTime > 25 ) 
    { A = BtnMouseStatus == 0 ;
      B = digitalRead( BtnMouse ) == HIGH ;
      if ( A && B )   { Event = 1 ; }
      if ( A && !B )  { Event = 2 ; }
      if ( !A && B )  { Event = 3 ; }
      if ( !A && !B ) { Event = 1 ; }      
      switch ( Event ) 
        { case 2 :
            { BtnMouseStatus = 1 ;
              BtnMouseLoopTime = millis() ; 
            }
          break ;
          case 3 :
            { BtnMouseStatus = 0 ;
              BtnMouseLoopTime = millis() ; 
            }
          break ;
        }
    }
  return Event ;
}


*/


// СКЕТЧ
#define BtnMouse 7                       // подключение кнопки
uint32_t BtnMouseLoopTime = 0 ;          // фиксация времени предшествующего состояние кнопки
uint8_t BtnMouseStatus = 0 ;             // предшествующее состояние кнопки
#define LedMouse 13                      // подключение светодиода
uint16_t N = 0 ;                         // для контроля наличия дребезга
//-----------------------------------------------------------------  
void setup()
{  
  Serial.begin( 9600 ) ;
  pinMode( BtnMouse , INPUT ) ;            // режим пина кнопки
  digitalWrite( BtnMouse , HIGH ) ;        // подтяжка пина к +
  pinMode( LedMouse , OUTPUT ) ;           // режим пина светодиода
} 
//-----------------------------------------------------------------  
uint8_t EventBtnMouse() 
{
  boolean A , B ;
  uint8_t Event ;
  if ( millis() - BtnMouseLoopTime > 5 ) 
    { A = BtnMouseStatus == 0 ;
      B = digitalRead( BtnMouse ) == HIGH ;
      if ( A && B )   { Event = 1 ; }
      if ( A && !B )  { Event = 2 ; }
      if ( !A && B )  { Event = 3 ; }
      if ( !A && !B ) { Event = 1 ; }      
      switch ( Event ) 
        { case 2 :
            { BtnMouseStatus = 1 ;
              BtnMouseLoopTime = millis() ; 
            }
          break ;
          case 3 :
            { BtnMouseStatus = 0 ;
              BtnMouseLoopTime = millis() ; 
            }
          break ;
        }
    }
  return Event ;
}
//----------------------------------------------------------------- 
void loop()
{ 
//  if ( EventBtnMouse() == 2 )
//  {
//    N ++ ;
//    Serial.println( N ) ;
//  }
  if ( EventBtnMouse() == 3 )
  {
    N ++ ;
    Serial.println( N ) ;
  }  
}
//----------------------------------------------------------------- 

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

 Вверху - жалкая пародия на конвертацию в библу....

При задержке = 1 в строке #81 - мало искрит, при значении = 50 - вааще не замечено :)

Тестил кнопкой-пальцем, потом подключил один канал энкодера ( без определения направления вращения ) - тоже не искрит !!!!!!

До ООП - далеко, сделал как смог.... И ещё... Напрягают после Паскаля сложносочинённые операторы CPP//// Поэтому - каждая операция отдельно.... За это не лупите, пожста....

Обсудить - есть кто ?

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

 А поискать на arduino.cc готовые либы для этого не пробовали?

http://arduino.cc/playground/Code/Bounce

Если погуглить их еще киллограм найти можно. Кто их только не писал :)  Хотя я, лично, предпочитаю все-таки в "писать вручную". не такая уж сложна логика, плюс часто в  проекте бывают свою "нюансы" и с их проще учесть "частным решением", чем "универсальным".

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

 Дык - готовые потом.... Сначала самому поучиться надо... И сравнить с другими... Спасибо за ссылку !

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

 Ну если "самому":

  1.  Зачем постить скетч с кусками старого закоменченного кода?
  2. Строка 81. "Магическая цифра 5". Почему ее не оформить тоже в виде define?
  3. Зачем строки 84,87? Event = 1 - никогда не обрабатывается. Значит их можно просто выкинуть. Тогда и switch становится не нужен. Всю логику можно впихнуть в тело if-вов строк 85, 86
  4. "digitalRead( BtnMouse ) == HIGH" эквивалентно "digitalRead( BtnMouse )". Имеем "просто лишние буквы"
  5. "A = BtnMouseStatus == 0" тоже можно написать короче "A=!BtnMouseStatus"
  6. Использования A и B - плохая идея. Тем более что "означают" совсем разные вещи. Когда кто-то будет читать ваш код - он интуитивно будет предполагать что A и B - два экземпляра одного и того же явления. Например "две кнопки".  То что один это Status, а второй это "нажатали кнопка" - нужно мозг хмурить. Вообщем подлянку "последователям" - вы заложили. Или даже самому себе, если будете работать с этим кодом через несколько месяцев.
  7. И вообще "не говорящие имена" - очень плохой подход (ну кроме самых очевидных случаев). Имя переменной типа  isButtonPressed  - говорит гораздо больше. Понять какой смысл в выражении if(isButtonPressed && BtnMouseStatus) гораздо легче чем if(A && B). 
  8. Кстати, в таком случае вообще не понятно зачем вам A. Раз она всегда инвертирована по отношеню к BtnMouseStatus. Может лучше сразу условия писать опираясь на BtnMouseStatus? К тому же это точно "статус"? Не prevIsButtonPressed?
  9. BtnMouseLoopTime почему int-тового типа? У вас бывает отрицательно время? Функция millis() возвращает unsigned long. Логично и переменную делать такого же типа.

Учитывая все это. Я не стал вникать "как рабоает этот код".