4) KeyPadI used simple 16 4x4 Matrix Keyboard Keypad. you can buy it online or locally for few dollars.
This keypad has 8 connectors (4x4 matrix rows and columns).
I decided to connect it Arduino via only one wire. Usually most people connects each row/column out to controller digital pin, therefore uses 8 digital in-s.
But why 8 pin when there is one pin enough?!
You just need few resistors.
Resistors should be selected to guarantee voltages spread as mach as possible.
here is a table with resistors and according voltage readings (after ADC converted it to int, we suppose VCC is converted to 1024 as in Arduino)
| R (in kOhm) | 0 | 22 | 47 | 68 |
| 0 | 0 | 185 | 327 | 414 |
| 82 | 461 | 522 | 577 | 614 |
| 180 | 658 | 685 | 711 | 730 |
| 280 | 755 | 769 | 784 | 795 |
This numbers are more presentable in chart. Goal is to avoid chart lines crossing.
Even though the readings from ADC may cross due to electrical noises in circuit.
To avoid this I use software filter
char KeyPad::ReadKey(int KeyReads, int KeyReadDelay)
{
char ret=NoKeyChar;
int ai;
int aiMin=1024, aiMax=0;
float aiAvr=0;
for (int i=0;i<KeyReads;i++)
{
ai=analogRead(KeyPadPin);
if (ai<aiMin)
aiMin=ai;
if (ai>aiMax)
aiMax=ai;
aiAvr+=ai;
delay(KeyReadDelay);
}
aiAvr/=(float)mKeyReads;
float dev;
if (aiAvr==0)
dev=0;
else
dev=(aiMax-aiMin)/aiAvr;
if (dev<KeyReadPrec)
{
ai=aiAvr;
for (int i=0;i<mKeyCount;i++)
{
if(ai>=mKeyIntsL[i] and ai<=mKeyIntsH[i])
{
ret=mKeys[i];
break;
}
}
}
return(ret);
}
The function
ReadKey has 2 parameters
KeyReads and
KeyReadDelay.
Code reads KeyPin several times (
KeyReads) with some delay (
KeyReadDelay) to get average reading that prevents analog noise.
But noise isn't the only problem for KeyPad, there is transitional state during pressing or releasing key, when resistance of connector is changing from 0 to disconnected and if this function runs this moment, it may get wrong reading. To prevent this, I use max and min values of readings and compare them to average value, than I calculate difference (let call it deviation). If the deviation is too big, then KeyPad isn't in stable state and reading should be discarded. here we check it
dev=(aiMax-aiMin)/aiAvr;
if (dev<KeyReadPrec)
KeyReadPrec is acceptable deviation to guarantee stable readings.
You can note in electrical scheme that there is used another digital pin of Atmega. That is due to Atmega powerdown mode. KeyPad used also wake up interrupt.
Here is intterupt attaching code from main fail of the project.
attachInterrupt(0, wakeUpNow, LOW);
In KeyPad library there are many other functions that will discussed lately.