Phidget Force Sensor Programming
August 23, 2011 2 Comments
For the next TriNUG main meeting, I thought of have a Family Feud type game. To that end, I wanted to simulate the buzzer/button that the contestants use:
To that end, I purchased 2 force sensors from Phidgets and hooked them up to my 8/8/8 Interface kit. I guess the contestants will use a finger versus their entire hand:
The sensor is very straight forward – you press the button and the Interface kit reads how much pressure is applied:
Thinking on how it would work as FamilyFeud buzzer system, I just need to keep track of who applied force 1st – the amount of pressure is irrelevant. Also, I need a trigger mechanism that starts listening at certain points – so that contestants don’t jump the gun.
I first started with a WPF project to see if I could hook into the Phidget InterfaceKit. I created a basic WPF application and wrote the following code (pretty much straight from the programmers guide):
public partial class MainWindow : Window { InterfaceKit _interfaceKit; public MainWindow() { InitializeComponent(); _interfaceKit = new InterfaceKit(); _interfaceKit.open(); _interfaceKit.waitForAttachment(3000); _interfaceKit.SensorChange += new SensorChangeEventHandler(_interfaceKit_SensorChange); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(String.Format("Name={0}",_interfaceKit.Name)); stringBuilder.Append(Environment.NewLine); stringBuilder.Append(String.Format("Label={0}", _interfaceKit.Label)); this.InterfaceKitInfoLabel.Content = stringBuilder.ToString(); } void _interfaceKit_SensorChange(object sender, SensorChangeEventArgs e) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(String.Format("Index={0}", e.Index)); stringBuilder.Append(Environment.NewLine); stringBuilder.Append(String.Format("Value={0}", e.Value)); this.PressureSensor01Label.Content = stringBuilder.ToString(); } }
When I hit F5 and pressed a sensor, I got this error:
Ugh! I looks like Phidgets programming need to support thread affinity?! To confirm, I wrote a Console application that does pretty much the exact same thing:
static void Main(string[] args) { Console.WriteLine("Start"); InterfaceKit interfaceKit = new InterfaceKit(); interfaceKit.Attach += new Phidgets.Events.AttachEventHandler(interfaceKit_Attach); interfaceKit.SensorChange += new Phidgets.Events.SensorChangeEventHandler(interfaceKit_SensorChange); interfaceKit.open(); interfaceKit.waitForAttachment(); Console.WriteLine("-End-"); Console.ReadLine(); } static void interfaceKit_Attach(object sender, Phidgets.Events.AttachEventArgs e) { Console.Write(String.Format("Interface Kit {0} attached",e.Device.Name)); } static void interfaceKit_SensorChange(object sender, Phidgets.Events.SensorChangeEventArgs e) { Console.WriteLine(String.Format("Sensor {0} changed with the value {1}.",e.Index, e.Value)); } }
When I F5 and press the sensor, I get the following:
So it looks like I need to be thread-aware on WPF applications. After some digging into the code samples from the most recent documentation, I found this nugget of a project:
Sure enough, the code has thread-affinity:
void ifk_Attach(object sender, AttachEventArgs e) { this.Dispatcher.Invoke(new Action(delegate() { makeDigiInArrays(); makeDigiOutArrays(); makeSensorInArrays(); InterfaceKit attached = (InterfaceKit)sender; attachedLbl.Content = attached.Attached.ToString(); nameLbl.Content = attached.Name; serialNoLbl.Content = attached.SerialNumber.ToString(); versionLbl.Content = attached.Version.ToString(); digitalInputCountLbl.Content = attached.inputs.Count.ToString(); digitalOutputCountLbl.Content = attached.outputs.Count.ToString(); sensorCountLbl.Content = attached.sensors.Count.ToString(); for (int i = 0; i < attached.inputs.Count; i++) { digiInChkArray[i].Visibility = System.Windows.Visibility.Visible; digiInLblArray[i].Visibility = System.Windows.Visibility.Visible;
So this simple project just jumped up a notch if I want to use WPF.
Very neat idea! How did people like the game?
It went over well.
Also check out: