libraries / Mitov / Mitov_Keypad.hon commit Added link to project report (97a3ba0)
   1////////////////////////////////////////////////////////////////////////////////
   2//                                                                            //
   3//     This software is supplied under the terms of a license agreement or    //
   4//     nondisclosure agreement with Mitov Software and may not be copied      //
   5//     or disclosed except in accordance with the terms of that agreement.    //
   6//         Copyright(c) 2002-2016 Mitov Software. All Rights Reserved.        //
   7//                                                                            //
   8////////////////////////////////////////////////////////////////////////////////
   9
  10#ifndef _MITOV_KEYPAD_h
  11#define _MITOV_KEYPAD_h
  12
  13#include <Mitov.h>
  14
  15namespace Mitov
  16{
  17//---------------------------------------------------------------------------
  18        class KeypadBasicKeyElement;
  19        class BasicKeypad;
  20//---------------------------------------------------------------------------
  21        class KeypadKeys
  22        {
  23        public:
  24                virtual void RegisterKey( int ARow, int ACol, KeypadBasicKeyElement *AKey ) = 0;
  25                virtual BasicKeypad *GetRootOwner() = 0;
  26        };
  27//---------------------------------------------------------------------------
  28        class KeypadBasicKeyElement;
  29//---------------------------------------------------------------------------
  30        class BasicKeypad : public OpenWire::Component, public KeypadKeys
  31        {
  32                typedef OpenWire::Component inherited;
  33
  34        public:
  35                uint32_t        DebounceInterval = 50;
  36
  37        };
  38//---------------------------------------------------------------------------
  39        template< int C_X, int C_Y > class Keypad : public BasicKeypad
  40        {
  41                typedef BasicKeypad inherited;
  42
  43        public:
  44//              Mitov::SimpleList<OpenWire::VlaueSinkPin<bool> >        RowsInputPins;
  45                Mitov::SimpleList<OpenWire::SourcePin>  ColumnsOutputPins;
  46
  47        public:
  48                const uint8_t   *_Pins;
  49
  50        protected:
  51                bool    FInScanning = false;
  52
  53                KeypadBasicKeyElement   *FKeyMap[ C_X ][ C_Y ];
  54
  55        public:
  56                virtual BasicKeypad *GetRootOwner() override
  57                {
  58                        return this;
  59                }
  60
  61                virtual void RegisterKey( int ARow, int ACol, KeypadBasicKeyElement *AKey ) override
  62                {
  63                        FKeyMap[ ACol ][ ARow ] = AKey;
  64                }
  65
  66        protected:
  67                virtual void SystemInit()
  68                {
  69                        for( int i = 0; i < C_Y ; ++i )
  70                                pinMode( _Pins[ i ], INPUT_PULLUP );
  71
  72                        inherited::SystemInit();
  73                }
  74
  75                virtual void SystemLoopBegin( unsigned long currentMicros ) override;
  76
  77        };
  78//---------------------------------------------------------------------------
  79        class KeypadBasicKeyElement // : public OpenWire::Component
  80        {
  81        public:
  82                virtual void SetButtonValue( unsigned long currentMicros, bool AValue )
  83                {
  84                }
  85
  86        };
  87//---------------------------------------------------------------------------
  88        template<typename T_OWNER> class KeypadKeyElement : public KeypadBasicKeyElement
  89        {
  90                typedef KeypadBasicKeyElement inherited;
  91
  92        protected:
  93                T_OWNER &FOwner;
  94
  95        public:
  96                KeypadKeyElement( T_OWNER &AOwner ) :
  97                        FOwner( AOwner )
  98                {
  99                }
 100
 101                KeypadKeyElement( T_OWNER &AOwner, int ARow, int ACol ) :
 102                        FOwner( AOwner )
 103                {
 104                        AOwner.RegisterKey( ACol, ARow, this );
 105                }
 106
 107        };
 108//---------------------------------------------------------------------------
 109        template<typename T_OWNER> class KeypadBasicKey : public KeypadKeyElement<T_OWNER>
 110        {
 111                typedef KeypadKeyElement<T_OWNER> inherited;
 112
 113/*
 114        protected:
 115                virtual void SystemLoopBegin( unsigned long currentMicros )
 116                {
 117                        inherited::SystemLoopBegin( currentMicros );
 118                }
 119*/
 120        public:
 121                using inherited::inherited;
 122
 123        };
 124//---------------------------------------------------------------------------
 125        class DigitalKeypadKey : public KeypadBasicKey<BasicKeypad>
 126        {
 127                typedef KeypadBasicKey<BasicKeypad> inherited;
 128
 129        public:
 130                OpenWire::SourcePin     OutputPin;
 131
 132        protected:
 133                unsigned long   FLastTime = 0;
 134                bool    FValue : 1;
 135                bool    FLastValue : 1;
 136
 137        public:
 138                virtual void SetButtonValue( unsigned long currentMicros, bool AValue )
 139                {
 140                        if( AValue != FLastValue )
 141                                FLastTime = millis();
 142
 143                        FLastValue = AValue;
 144                        if( FValue != FLastValue )
 145                                if( millis() - FLastTime > FOwner.DebounceInterval )
 146                                {
 147                                        FValue = FLastValue;
 148                                        OutputPin.SendValue( ! FValue );
 149                                }
 150
 151                }
 152
 153        public:
 154                DigitalKeypadKey( BasicKeypad &AOwner, int ARow, int ACol ) :
 155                        inherited( AOwner, ARow, ACol ),
 156                        FLastValue( false ),
 157                        FValue( false )
 158                {
 159                }
 160        };
 161//---------------------------------------------------------------------------
 162        class CharacterKeyGroup : public KeypadKeyElement<KeypadKeys>, public KeypadKeys
 163        {
 164                typedef KeypadKeyElement<KeypadKeys> inherited;
 165
 166        public:
 167                OpenWire::SourcePin     OutputPin;
 168
 169        public:
 170                virtual BasicKeypad *GetRootOwner() override
 171                {
 172                        return FOwner.GetRootOwner();
 173                }
 174
 175                virtual void RegisterKey( int ARow, int ACol, KeypadBasicKeyElement *AKey ) override
 176                {
 177                        FOwner.RegisterKey( ARow, ACol, AKey );
 178                }
 179
 180        public:
 181                using inherited::inherited;
 182
 183        };
 184//---------------------------------------------------------------------------
 185        class CharKeypadKey : public KeypadBasicKey<CharacterKeyGroup>
 186        {
 187                typedef KeypadBasicKey<CharacterKeyGroup> inherited;
 188
 189        public:
 190                char    Character = 'a';
 191
 192        protected:
 193                unsigned long   FLastTime = 0;
 194                bool    FValue = false;
 195                bool    FLastValue = false;
 196
 197                BasicKeypad     *FRootOwner;
 198
 199        public:
 200                virtual void SetButtonValue( unsigned long currentMicros, bool AValue )
 201                {
 202                        if( AValue != FLastValue )
 203                                FLastTime = millis();
 204
 205                        FLastValue = AValue;
 206                        if( FValue != FLastValue )
 207                                if( millis() - FLastTime > FRootOwner->DebounceInterval )
 208                                {
 209                                        FValue = FLastValue;
 210                                        if( ! FValue )
 211                                                FOwner.OutputPin.Notify( &Character );
 212
 213//                                      OutputPin.Notify( &FValue );
 214                                }
 215
 216                }
 217
 218        public:
 219                CharKeypadKey( CharacterKeyGroup &AOwner, int ARow, int ACol ) :
 220                        inherited( AOwner, ARow, ACol )
 221                {
 222                        FRootOwner = AOwner.GetRootOwner();
 223                }
 224        };
 225//---------------------------------------------------------------------------
 226//---------------------------------------------------------------------------
 227//---------------------------------------------------------------------------
 228//---------------------------------------------------------------------------
 229        template< int C_X, int C_Y > void Keypad< C_X, C_Y >::SystemLoopBegin( unsigned long currentMicros )
 230        {
 231                if( ! FInScanning )
 232                {
 233                        FInScanning = true;
 234                        for( int i = 0; i < C_X; ++i )
 235                                ColumnsOutputPins[ i ].SendValue( false );
 236                }
 237
 238                for( int i = 0; i < C_Y; ++i )
 239                        if( ! digitalRead( _Pins[ i ] ))
 240                                FInScanning = false;
 241
 242//              if( ! FInScanning )
 243//                      Serial.println( "----------------------------" );
 244
 245                for( int i = 0; i < C_X; ++i )
 246                {
 247                        if( ! FInScanning )
 248                        {
 249                                for( int j = 0; j < C_X; ++j )
 250                                {
 251//                                      Serial.print( i != j ); Serial.print( " " );
 252                                        ColumnsOutputPins[ j ].SendValue( i != j );
 253                                }
 254
 255//                              Serial.println( "" );
 256                        }
 257
 258//                      if( ! FInScanning )
 259//                              Serial.println( "+++++++++++++++++++++++++" );
 260
 261                        for( int j = 0; j < C_Y; ++j )
 262                                if( FKeyMap[ i ][ j ] )
 263                                {
 264//                                      if( ! FInScanning )
 265//                                      {
 266//                                              if( ! digitalRead( _Pins[ j ] ) )
 267//                                              {
 268//                                                      Serial.print( i ); Serial.print( "," ); Serial.println( j );
 269//                                              }
 270//                                              Serial.print( i ); Serial.print( "," ); Serial.print( j ); Serial.print( " = " ); Serial.print( digitalRead( _Pins[ j ] ) ); Serial.print( "  " ); 
 271//                                      }
 272
 273                                        FKeyMap[ i ][ j ]->SetButtonValue( currentMicros, digitalRead( _Pins[ j ] ));
 274                                }
 275
 276//                      if( ! FInScanning )
 277//                              Serial.println( "" );
 278                }
 279                        
 280                inherited::SystemLoopBegin( currentMicros );
 281        }
 282//---------------------------------------------------------------------------
 283}
 284
 285#endif