The KP16 keypad column keys 1,4,7,* does not produce a key press, and when 2 is pressed, I receive 1, when 5 is pressed, I receive 4, when 8 is pressed, I receive 7, when 0 is pressed, I receive *. The column 3,6,9,# has no response, and the column A,B,C,D works ok. See the IsKeyPressed(out char key) function.
This problem happened after I ported my code from MF4.2 to MF4.3. When I create a new empty MF 4.3 project, with only a Raptor board and a KP16 keypad, the same code works ok.
using System;
using Microsoft.SPOT;
using System.Threading;
using System.Text;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using GTME = Gadgeteer.Modules.GHIElectronics;
namespace KeyPadKP16Test
{
/// <summary>
/// The keyboard character is stored in the KeyboardEventArgs class
/// </summary>
public class KP16EventArgs : EventArgs
{
private char cKeyPressed;
public KP16EventArgs(char _cKey)
{
cKeyPressed = _cKey;
}
public char KeyChar
{
get
{
return cKeyPressed;
}
set
{
cKeyPressed = value;
}
}
public string KeyString
{
get
{
string rs;
rs = new string(KeyChar, 1);
return rs;
}
}
public byte KeyByte
{
get
{
return (byte)KeyChar;
}
}
}
/// <summary>
/// The delegate for the Keyboard event handler
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public delegate void KP16EventHandler(object sender, KP16EventArgs e);
/// <summary>
/// Constructs a KP16KeyPad class by given parameters
/// </summary>
/// <param name="dev">Parent device</param>
/// <param name="_keypad_KP16">Gadgeteer KP16 keypad object</param>
/// <param name="Code">Equipment code</param>
public class KP16KeyPad
{
private const int CHECK_MSEC = 40; // Read hardware every X msec
private const int PRESS_MSEC = 80; // Stable time before registering pressed
private const int RELEASE_MSEC = 80; // Stable time before registering released
private bool DebouncedKeyPress = false;
private int Count = RELEASE_MSEC / CHECK_MSEC;
private const int PressCount = PRESS_MSEC / CHECK_MSEC;
private const int ReleaseCount = RELEASE_MSEC / CHECK_MSEC;
public event KP16EventHandler KeyPressEvent;
private GTME.KeypadKP16 keypad_KP16;
private int LoggingLevel;
private int ScanKeyPadInterval;
/// <summary>
/// Constructor
/// </summary>
/// <param name="dev"></param>
/// <param name="_keypad_KP16"></param>
/// <param name="_systemData"></param>
/// <param name="Code"></param>
public KP16KeyPad( GTME.KeypadKP16 _keypad_KP16 )
{
Debug.Print("Initializing ");
keypad_KP16 = _keypad_KP16;
LoggingLevel = 2;
ScanKeyPadInterval = CHECK_MSEC;
ThreadStart KP16ScanStarter = new ThreadStart(KP16ScanLoop);
Thread KP16ScanThread = new Thread(KP16ScanStarter);
KP16ScanThread.Start();
Debug.Print("Done initializing " );
}
/// <summary>
/// Fires the key press event if an event handler method is registered
/// </summary>
/// <param name="e"></param>
private void FireKeyEvent(char key)
{
if (KeyPressEvent != null)
{
KP16EventArgs e = new KP16EventArgs(key);
KeyPressEvent(this, e);
}
if (LoggingLevel > 1)
{
Debug.Print(" KP16 Key = " + key.ToString());
}
}
private bool IsKeyPressed(out char key)
{
key = (char)0;
//This is for testing KP16 keypad
if (keypad_KP16.IsPressed(GTM.GHIElectronics.KeypadKP16.Key.A))
{
key = 'A';
return true;
}
if (keypad_KP16.IsPressed(GTM.GHIElectronics.KeypadKP16.Key.B))
{
key = 'B';
return true;
}
if (keypad_KP16.IsPressed(GTM.GHIElectronics.KeypadKP16.Key.C))
{
key = 'C';
return true;
}
if (keypad_KP16.IsPressed(GTM.GHIElectronics.KeypadKP16.Key.D))
{
key = 'D';
return true;
}
if (keypad_KP16.IsPressed(GTM.GHIElectronics.KeypadKP16.Key.Pound))
{
key = '#';
return true;
}
if (keypad_KP16.IsPressed(GTM.GHIElectronics.KeypadKP16.Key.Star))
{
key = '*';
return true;
}
if (keypad_KP16.IsPressed(GTM.GHIElectronics.KeypadKP16.Key.Zero))
{
key = '0';
return true;
}
if (keypad_KP16.IsPressed(GTM.GHIElectronics.KeypadKP16.Key.One))
{
key = '1';
return true;
}
if (keypad_KP16.IsPressed(GTM.GHIElectronics.KeypadKP16.Key.Two))
{
key = '2';
return true;
}
if (keypad_KP16.IsPressed(GTM.GHIElectronics.KeypadKP16.Key.Three))
{
key = '3';
return true;
}
if (keypad_KP16.IsPressed(GTM.GHIElectronics.KeypadKP16.Key.Four))
{
key = '4';
return true;
}
if (keypad_KP16.IsPressed(GTM.GHIElectronics.KeypadKP16.Key.Five))
{
key = '5';
return true;
}
if (keypad_KP16.IsPressed(GTM.GHIElectronics.KeypadKP16.Key.Six))
{
key = '6';
return true;
}
if (keypad_KP16.IsPressed(GTM.GHIElectronics.KeypadKP16.Key.Seven))
{
key = '7';
return true;
}
if (keypad_KP16.IsPressed(GTM.GHIElectronics.KeypadKP16.Key.Eight))
{
key = '8';
return true;
}
if (keypad_KP16.IsPressed(GTM.GHIElectronics.KeypadKP16.Key.Nine))
{
key = '9';
return true;
}
return false;
}
/// <summary>
/// Scan keyboard for key press every CHECK_MSEC time
/// </summary>
void KP16ScanLoop()
{
while (true)
{
try
{
Thread.Sleep(ScanKeyPadInterval);
PollKeboard();
}
catch (Exception ex1)
{
}
}
}
/// <summary>
/// Poll the keyboard to detect a key press
/// </summary>
/// <param name="timer"></param>
//void KeboardPollTimer_Tick(GT.Timer timer) - if using a GT Timer
void PollKeboard()
{
// Service routine called every CHECK_MSEC to
// debounce both edges of key switches
bool RawState;
char KeyChar;
RawState = IsKeyPressed(out KeyChar);
if (RawState == DebouncedKeyPress)
{
// Set the timer which will allow a change from the current state.
if (DebouncedKeyPress)
Count = ReleaseCount;
else
Count = PressCount;
}
else
{
// Key has changed - wait for new state to become stable.
if (--Count <= 0)
{
// Timer expired - accept the change.
DebouncedKeyPress = RawState;
// And reset the timer.
if (DebouncedKeyPress)
{
Count = ReleaseCount;
FireKeyEvent(KeyChar);
}
else
{
Count = PressCount;
}
}
}
}
}
}