using System;
using System.Threading;
using Windows.Devices.Gpio;
using Windows.Devices.SerialCommunication;
using Windows.Storage.Streams;
namespace GpioEventSerial
{
public class Program
{
private static Keypad4X3 _keypad;
private static GpioPin Led1;
private static DevantechLcd03 _lcd;
public static void Main()
{
try
{
// Set up the green led on Quail
Led1 = GpioController.GetDefault().OpenPin(4 * 16 + 15); // Green led on Quail (PE15)
Led1.SetDriveMode(GpioPinDriveMode.Output);
// Create an instance of the Devantech LCD display in serial mode
_lcd = new DevantechLcd03()
{
BackLight = true,
Cursor = DevantechLcd03.Cursors.Hide
};
_lcd.ClearScreen();
_lcd.Write(1, 1, "Starting scan");
// Create an instance of the keypad
_keypad = new Keypad4X3(3 * 16 + 14, 0 * 16 + 14, 0 * 16 + 10, 0 * 16 + 9, 0 * 16 + 5, 3 * 16 + 0, 3 * 16 + 1);
_keypad.KeyPressed += _keypad_KeyPressed;
_keypad.KeyReleased += _keypad_KeyReleased;
_keypad.StartScan();
}
catch (Exception ex)
{
// Do whatever please you with the exception caught
}
finally // Enter the infinite loop in all cases
{
while (true)
{
Thread.Sleep(100);
}
}
}
private static void _keypad_KeyReleased(Object sender, Keypad4X3.KeyReleasedEventArgs e)
{
_lcd.Write(1, 3, "Key : " + e.KeyChar);
Led1.Write(GpioPinValue.Low);
}
private static void _keypad_KeyPressed(Object sender, Keypad4X3.KeyPressedEventArgs e)
{
Led1.Write(GpioPinValue.High);
}
}
public class Keypad4X3
{
public event KeyPressedEventHandler KeyPressed = delegate { };
public event KeyReleasedEventHandler KeyReleased = delegate { };
private static GpioPin[] _rows;
private static GpioPin[] _columns;
private Thread _scanThread;
private Boolean _scanThreadActive;
public Keypad4X3(int row1, int row2, int row3, int row4, int column1, int column2, int column3)
{
var controller = GpioController.GetDefault();
var Row1 = controller.OpenPin(row1);
Row1.SetDriveMode(GpioPinDriveMode.Output);
Row1.Write(GpioPinValue.Low);
var Row2 = controller.OpenPin(row2);
Row2.SetDriveMode(GpioPinDriveMode.Output);
Row2.Write(GpioPinValue.Low);
var Row3 = controller.OpenPin(row3);
Row3.SetDriveMode(GpioPinDriveMode.Output);
Row3.Write(GpioPinValue.Low);
var Row4 = controller.OpenPin(row4);
Row4.SetDriveMode(GpioPinDriveMode.Output);
Row4.Write(GpioPinValue.Low);
var Col1 = controller.OpenPin(column1);
Col1.SetDriveMode(GpioPinDriveMode.InputPullDown);
var Col2 = controller.OpenPin(column2);
Col2.SetDriveMode(GpioPinDriveMode.InputPullDown);
var Col3 = controller.OpenPin(column3);
Col3.SetDriveMode(GpioPinDriveMode.InputPullDown);
_rows = new[] { Row1, Row2, Row3, Row4 };
_columns = new[] { Col1, Col2, Col3 };
}
public void StartScan()
{
if (_scanThreadActive) { return; }
_scanThreadActive = true;
_scanThread = new Thread(ScanThreadMethod);
_scanThread.Start();
}
public void StopScan()
{
_scanThreadActive = false;
}
private void ScanThreadMethod()
{
var prevKey = -1;
while (_scanThreadActive)
{
var nbKey = 0;
// Scans the matrix
for (var i = 0; i < 4; i++)
{
for (var j = 0; j < 3; j++)
{
if (ReadMatrix(i, j) == GpioPinValue.Low) continue;
// A key has been pressed
var keyNum = (i * 3) + j + 1;
nbKey += keyNum;
if ((prevKey != keyNum) && (prevKey == -1)) // A key has been pressed and no other is currently pressed (avoids dealing with multiple keys at the same time)
{
prevKey = keyNum;
var tempEvent = KeyPressed;
tempEvent(this, new KeyPressedEventArgs(keyNum, KeytoChar(keyNum)));
}
break;
}
}
if (nbKey == 0) // No key pressed in this pass
{
// Was there a key pressed before ?
if (prevKey != -1)
{
var tempEvent = KeyReleased;
tempEvent(this, new KeyReleasedEventArgs(prevKey, KeytoChar(prevKey)));
}
prevKey = -1;
}
// Leave time for other processes
Thread.Sleep(100);
}
}
private GpioPinValue ReadMatrix(int row, int column)
{
_rows[row].Write(GpioPinValue.High);
var colState = _columns[column].Read();
_rows[row].Write(GpioPinValue.Low);
return colState;
}
private char KeytoChar(int keyValue)
{
char c;
if (keyValue < 10) { c = (char)(keyValue + 48); }
else
{
switch (keyValue)
{
case 10:
c = '*';
break;
case 11:
c = '0';
break;
case 12:
c = '#';
break;
default:
c = ' '; // Should never happen
break;
}
}
return c;
}
public delegate void KeyPressedEventHandler(object sender, KeyPressedEventArgs e);
public delegate void KeyReleasedEventHandler(object sender, KeyReleasedEventArgs e);
public class KeyPressedEventArgs
{
public KeyPressedEventArgs(int pKeyValue, char pKeyChar)
{
KeyValue = pKeyValue;
KeyChar = pKeyChar;
}
public int KeyValue { get; private set; }
public char KeyChar { get; private set; }
}
public class KeyReleasedEventArgs
{
public KeyReleasedEventArgs(int pKeyValue, char pKeyChar)
{
KeyValue = pKeyValue;
KeyChar = pKeyChar;
}
public int KeyValue { get; private set; }
public char KeyChar { get; private set; }
}
}
public class DevantechLcd03
{
public enum Cursors
{
Hide,
Underline,
Blink
};
private readonly SerialDevice _lcdSerial;
private DataWriter outputDataWriter;
private Cursors _cursor;
private Boolean _backLight;
public DevantechLcd03()
{
try
{
_lcdSerial = SerialDevice.FromId("COM3");
_lcdSerial.BaudRate = 9600;
_lcdSerial.Parity = SerialParity.None;
_lcdSerial.StopBits = SerialStopBitCount.Two;
_lcdSerial.Handshake = SerialHandshake.None;
_lcdSerial.DataBits = 8;
outputDataWriter = new DataWriter(_lcdSerial.OutputStream);
Init();
}
catch { }
}
private void Init()
{
_backLight = false;
_cursor = Cursors.Blink;
}
public Cursors Cursor
{
get { return _cursor; }
set
{
outputDataWriter.WriteBytes(new[] { (byte)(4 + value) });
outputDataWriter.Store();
Thread.Sleep(1);
_cursor = value;
}
}
public Boolean BackLight
{
get { return _backLight; }
set
{
outputDataWriter.WriteBytes(new[] { value ? (Byte)19 : (Byte)20 });
outputDataWriter.Store();
Thread.Sleep(1);
_backLight = value;
}
}
public void SetCursor(byte x, byte y)
{
if (x <= 0 || x > 20 || y <= 0 || y > 4) { return; }
outputDataWriter.WriteBytes(new byte[] { 3, y, x });
outputDataWriter.Store();
Thread.Sleep(1);
}
public void Write(string text)
{
outputDataWriter.WriteString(text);
outputDataWriter.Store();
Thread.Sleep(1);
}
public void Write(byte x, byte y, string text)
{
if (x <= 0 || x > 20 || y <= 0 || y > 4) { return; }
SetCursor(x, y);
Write(text);
}
public void ClearScreen()
{
outputDataWriter.WriteBytes(new byte[] { 12 });
outputDataWriter.Store();
Thread.Sleep(1);
}
}
}
Comments