Wednesday, September 30, 2009

Easily Add External I/O to Custom Software – Keyboard Encoder Modules

Arcade Game photo by Robin Norman - Stock Exchange user: otto_taroEver have the need/desire to be able to have your software  interact with a hardware input device other than a mouse or keyboard? Using a Keyboard Encoder Module and a little creativity you can take the input of something like an industrial switch, button, or Programmable Logic Controller (PLC) output and read it in your program as if it were a keystroke from a keyboard. This technique has been in use for a long time by arcade game manufacturers (think joystick and buttons). The devices are relatively reliable, but even if they fail, they are inexpensive and easy to replace.
I used the KE24 Keyboard Encoder Module from Hagstrom Electronics, but due to the declining availability of PS/2 style miniDIN connectors in PC’s, the KE-USB24 would probably be an acceptable choice.
Quick VB.Net code for a Windows Form to check which keystroke was pressed:
   1: ' a constant representing the keystroke value 
   2: ' mapped to a button press. In this example, the F5 key

   3: Dim keyActCounterIncrement as String = "116" 
   4:  
   5: Protected Overrides Function ProcessCmdKey( _
   6:              ByRef msg As System.Windows.Forms.Message, _
   7:              ByVal keyData As System.Windows.Forms.Keys) _
   8:              As Boolean
   9:  
  10:         ' get the key map data
  11:         Dim strKeyData As String = CStr(keyData)
  12:         
  13:         ' The key was pressed to increment a piece part counter.
  14:         If keyData = keyActCounterIncrement Then
  15:             DoSomethingLikeIncrementACounter()
  16:             Return True
  17:         End If
  18: End Function

Here’s a good key translation chart for reference.

[updated 10/19/2009 to add WPF code snippet]
XAML:

   1: <Window x:Class="Window1"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     Title="Pacer" Height="300" Width="300">
   5:     <Grid>
   6:         <TextBox Height="23" Margin="126,74,32,0" Name="txtActCounter" VerticalAlignment="Top" />
   7:         <TextBlock Height="21" Margin="51,77,0,0" Name="lblActCounter" VerticalAlignment="Top" Text="Actual Count" HorizontalAlignment="Left" Width="77" />
   8:     </Grid>
   9: </Window>


   1: Class Window1 
   2:     Private intActCounter As Integer = 0
   3:     Private Sub Window1_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
   4:         ' register an event handler to intercept the keyboard input
   5:         EventManager.RegisterClassHandler(GetType(Window), _
   6:             Keyboard.KeyUpEvent, New KeyEventHandler(AddressOf KeyUpCapture), True)
   7:         ' set a textbox counter to zero
   8:         txtActCounter.Text = intActCounter.ToString
   9:     End Sub
  10:     Private Sub KeyUpCapture(ByVal sender As Object, ByVal e As KeyEventArgs)
  11:         ' if keypress is F5
  12:         '   do something
  13:         If e.Key = Key.F5 Then
  14:             ' increment counter
  15:             intActCounter += 1
  16:             ' update textbox to counter value
  17:             txtActCounter.Text = intActCounter.ToString
  18:  
  19:         End If
  20:  
  21:     End Sub
  22: End Class
There are a few considerations to using this method:
  • It is a low voltage, low current “dry contact” device, but you still might want to consider soliciting the help of an electrician/controls engineer to wire it up to make sure you don’t fry your new “toy”, your PC, yourself, or another unsuspecting bystander
  • It is a low voltage device so the wiring between the keyboard encoder module and the input device needs to be located in close proximity (i.e. minimal wire length). If you need more distance, I recommend wiring the field device to an industrial dry contact relay bank and locating the relay bank in close proximity to the keyboard encoder module.
  • You probably want to map the inputs to keys, or combinations of keys that are not typically used in normal typing, like the tilde (~), so as not to inadvertently register text actually typed from the keyboard as inputs from the keyboard encoder module.

Thursday, August 20, 2009

Unlink height and width scaling in Expression Design

Sometimes the simplest things can be the most aggravating. I wanted to change the width of an object without changing the height, but I wanted to do it by the numbers not the drag handles. Every time I typed in the new width, the height changed proportionately. It took me a while to notice the “unlink” icon in the bottom toolbar between the height and width setter textboxes. Like magic clicking the icon allows independent adjustment of height and width of the selected entity.

Unlink height and width settings

Monday, July 27, 2009

WPF controls not showing a state change

I created a dependency property in the code behind to enable/disable a button during processing.wpf code-behind

In the XAML, I bound the IsEnabled property to the dependency property. XAML button binding

The button wasn’t showing the state change. Don’t forget to add the Name property to the window or the property won’t show the state change. XAML window name

Thursday, July 16, 2009

Encoding Media with Expression Blend and Encoder 2 SDK

This week I presented for the Fort Wayne .Net Users Group (NUFW). There were about ten people in attendance and the presentation lasted about one and a half hours with an Encoder GUI walkthrough and two demos. The Power Point presentation and source code can be downloaded here. The theme of the main Demo was ZooTube a simple WPF app to encode media with an Intro and an in-video watermark (screenshot of app is below the video). The code was based on the VB sample code that is included in the Encoder 2 SDK download. The finished video is shown below.
zootube wpf app screenshot

Wednesday, July 8, 2009

LINQ Query Samples in VB

Sometimes what you are looking for is right in front of you. There are a lot more samples of LINQ query syntax in C# than VB.Net and the syntax is enough different that it often requires a sample snippet to get it right in all but the simplest queries. I rarely use the Visual Studio snippets when programming so I didn’t even think to look there for LINQ snippets, but they are there. Just right click in the source window, “Insert Snippet”, “Data – LINQ, XML, Designer, ADO.Net”, “LINQ Queries”.

Wednesday, May 27, 2009

Smiling and Profiling – Potpourri of Profiler Utility

Last night I presented for the Fort Wayne chapter of PASS (Professional Association for SQL Server). You can download the presentation titled Smiling and Profiling - A Potpourri of Profiler Utility. The meeting was held in downtown Fort Wayne at the Pint and Slice in their spacious upstairs meeting area. It was a small group, but that always promotes great conversation.

Thursday, April 16, 2009

Open IIS hosted Visual Studio project on a box without IIS

I recently experienced an occasion to open a project created in Visual Studio 2008 SP1 configured to use IIS on a different box that did not have IIS installed. The project would not open and a message box indicated it was because IIS was not installed on the machine. The problem was easy to solve, but it required making a manual edit to the vbproject file.

The quick fix was to create a new Web Application project on the workstation without IIS, open the <project_name>.vbproj file in Wordpad or another editor and copy the XML between the <WebProjectProperties> tags.

   1: <WebProjectProperties> 
   2:           <UseIIS>False</UseIIS> 
   3:           <AutoAssignPort>True</AutoAssignPort> 
   4:           <DevelopmentServerPort>1159</DevelopmentServerPort> 
   5:           <DevelopmentServerVPath>/</DevelopmentServerVPath> 
   6:  
   7:  
   8:           <IISUrl> 
   9:           </IISUrl> 
  10:           <NTLMAuthentication>False</NTLMAuthentication> 
  11:           <UseCustomServer>False</UseCustomServer> 
  12:           <CustomServerUrl> 
  13:           </CustomServerUrl> 
  14:           <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile> 
  15:         </WebProjectProperties>
  16:  

Open the <project_name>.vbproj file of the project that would not open without IIS and paste the copied XML into the appropriate place in the file. Voila! The project can now be opened on the PC without IIS installed.



Technorati Tags: