User Tools

Site Tools


in202:seance_6:jalon_4

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
in202:seance_6:jalon_4 [2021/05/03 09:49]
bmonsuez
in202:seance_6:jalon_4 [2022/11/18 10:47] (current)
Line 54: Line 54:
  
 <code cpp> <code cpp>
-template<​int First, int... _Rest> ​class _ButtonEvents ​+template<​int First, int... _Rest>
 class _ButtonEvents <First, _Rest...>​ : private _ButtonEvents <​_Rest...> ​ class _ButtonEvents <First, _Rest...>​ : private _ButtonEvents <​_Rest...> ​
 { {
Line 108: Line 108:
  
 <code cpp> <code cpp>
 +template<​int First, int... _Rest>
 class _ButtonEvents <First, _Rest...>​ : private _ButtonEvents <​_Rest...> ​ class _ButtonEvents <First, _Rest...>​ : private _ButtonEvents <​_Rest...> ​
 { {
Line 144: Line 145:
 Pour ce faire, il suffit de définit une fonction ''​SetupButton(int thePort, Button* theButton)''​ comme suit : Pour ce faire, il suffit de définit une fonction ''​SetupButton(int thePort, Button* theButton)''​ comme suit :
  
 +<code cpp>
 +template<​int First, int... _Rest>
 class _ButtonEvents <First, _Rest...>​ : private _ButtonEvents <​_Rest...> ​ class _ButtonEvents <First, _Rest...>​ : private _ButtonEvents <​_Rest...> ​
 { {
Line 272: Line 275:
     }     }
 } }
 +</​code>​
 +
 +===== Code correspondant à la classe Button ===== 
 +
 +<code cpp>
 +
 +#ifndef buttonHPP
 +#define buttonHPP
 +#​include"​Component.hpp"​
 +
 +enum ButtonEvent { PRESSED = 0x1, RELEASED = 0x2 };
 +
 +typedef void (*interrupt_type)();​
 +
 +class Button;
 +
 +template <int... _Is>
 +class _ButtonEvents;​
 +template <>
 +class _ButtonEvents<>​ {
 +public:
 +    static interrupt_type GetPressed(int thePort) { return NULL; } 
 +    static interrupt_type GetReleased(int thePort) { return NULL; }
 +    static interrupt_type GetChanged(int thePort) { return NULL; }
 +    static void SetButton(int thePort, Button* theButton) {}
 +}; // Empty events
 +template <int First, int... _Rest>
 +class _ButtonEvents<​First,​ _Rest...>​ : private _ButtonEvents<​_Rest...> ​
 +
 +private:
 +    static const int mPortNumber = First;
 +    static Button* mButton;
 +    static void Pressed();
 +    static void Released();
 +    static void Changed();
 +public:
 +    static interrupt_type GetPressed(int thePort) { return thePort == mPortNumber ? Pressed : _ButtonEvents<​_Rest...>::​GetPressed(thePort);​ }
 +    static interrupt_type GetReleased(int thePort) { return thePort == mPortNumber ? Released : _ButtonEvents<​_Rest...>::​GetReleased(thePort);​ }
 +    static interrupt_type GetChanged(int thePort){ return thePort == mPortNumber ? Changed : _ButtonEvents<​_Rest...>::​GetChanged(thePort);​ } 
 +    static void SetButton(int thePort, Button* theButton);
 +};
 +
 +typedef _ButtonEvents<​0,​ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13> ButtonEvents;​
 +
 +class Button: public Component
 +{
 +private:
 +    uint32_t m_PortNumber;​
 +public:
 +    Button(uint32_t thePortNumber,​ const char* theName, bool isDebug = false):
 +      m_PortNumber(thePortNumber),​ Component(theName,​ isDebug)
 +    { 
 +        pinMode(m_PortNumber,​ INPUT);
 +        ButtonEvents::​SetButton(m_PortNumber,​ this);
 +    }
 +    void MonitorEvents(ButtonEvent anEvent)
 +    {
 +      if(anEvent == (PRESSED | RELEASED))
 +          attachInterrupt(digitalPinToInterrupt(m_PortNumber), ​
 +            ButtonEvents::​GetChanged(m_PortNumber),​ CHANGE);
 +      else if(anEvent == PRESSED)
 +      {
 +          attachInterrupt(digitalPinToInterrupt(m_PortNumber), ​
 +            ButtonEvents::​GetPressed(m_PortNumber),​ RISING);
 +      }
 +      else if(anEvent == RELEASED)
 +          attachInterrupt(digitalPinToInterrupt(m_PortNumber), ​
 +            ButtonEvents::​GetReleased(m_PortNumber),​ FALLING);
 +    }
 +    bool IsPressed() { return digitalRead(m_PortNumber) == HIGH; }
 +    virtual void OnPressed()
 +    {
 +      if(IsDebug())
 +          Serial << name() << "​Button is pressed\n";​
 +    }
 +    virtual void OnReleased()
 +    {
 +      if(IsDebug())
 +          Serial << name() << "​Button is released\n";​
 +    }
 +    virtual void OnChanged()
 +    {
 +      if(IsDebug())
 +          Serial << name() << "​Button state has changed\n";​
 +    }
 +};
 +template<​int First, int... _Rest>
 +Button* _ButtonEvents<​First,​ _Rest...>::​mButton = NULL;
 +template<​int First, int... _Rest>
 +void _ButtonEvents<​First,​ _Rest...>::​Pressed() ​
 +{ if(mButton != NULL) mButton->​OnPressed();​ }
 +template <int First, int... _Rest>
 +void _ButtonEvents<​First,​ _Rest...>::​Released() ​
 +{ if(mButton != NULL) mButton->​OnReleased();​ }
 +template <int First, int... _Rest>
 +void _ButtonEvents<​First,​ _Rest...>::​Changed() ​
 +{ if(mButton != NULL) mButton->​OnChanged();​ }
 +
 +template <int First, int... _Rest>
 +void _ButtonEvents<​First,​ _Rest...>::​SetButton(int thePort, Button* theButton)
 +{
 +    if(thePort == mPortNumber) ​
 +        mButton = theButton;
 +    else
 +        _ButtonEvents<​_Rest...>::​SetButton(thePort,​ theButton);
 +}
 +
 +#endif
 +
 </​code>​ </​code>​
  
in202/seance_6/jalon_4.1620035351.txt.gz · Last modified: 2021/05/03 09:49 by bmonsuez