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