Working with the Phidgets RFID Reader

I recently worked on a project that made use of Phidgets hardware. Phidgets has many offers for interfacing hardware sensors to a computer using USB. Provided that the drive is installed, using the service is pretty straight forward. They have software components available for a variety of languages and operating systems. For the project that I was working on, a computer would have multiple Phidget RFID readers. When there are multiple instances of hardware on a system, a specific instance can be addressed through it’s serial number. On this project, the serial numbers were stored in a configuration file. For the single machine on which this project was deployed, that was fine. Once that was a success the client wanted the software deployed to another 7 machines.

The most direct strategy for this would be to make a configuration file for each machine that had its specific serial numbers in it. I did this temporarily, but I am not a fan of having differences in deployment files. A simple mistake could result in the wrong configuration being deployed and a non-working software system. Deployments would be frequent because users were interacting with the software during this phase of development. An unexpected problem we encountered was someone disconnected hardware from one computer and moved it to another. Why they decided to perform this hardware swap is not known to me. But it resulted in two machines sensors that were no longer responsive.

After a little digging I found a much better solution.

For some reason the Phidgets code examples that I encounter don’t mention this, but it is also possible to get notification of a Phidgets device being connected or disconnected from the computer and the serial number of the device being references. I used a .Net environment for my development, but this concept is applicable in other languages too. I’ll be using .Net in my code examples.

In the .Net environment, Phidget’s offers a class named Manager in their SDK. The Manager class when instantiated raises Attached and Detached events each time an item of hardware is connected or disconnected from the system. If the class is instantiated after hardware has already been connected, it will raise Attached events for each item of hardware that is already there. The event argument object contains a member of the class Phidget that among other data contains the serial number of the item found and what type of hardware it is. For the application I was asked to update, I was only interested in the RFID reader hardware. I had the code ignore any Phidget of any other type. While it is unlikely the client would randomly connect such hardware to the machines running the solution, for the sake of code reuse it is better to have such protection in the application.

Let’s make an application that will list the RFID readers and the RFID readers detected by each tag. I’m writing this in WPF. Not shown here is some of the typical code you might find in such a project such as a ViewModel base class. In my sample project, I wrapped the Phidgets Manager class in another class that will also keep a list of the Phidget object instances that it has found. An abbreviated version of the class follows. The Phidget’s Manager class will start raising Attached and Detached events once its Open() method has been called. If there is already hardware attached, expect events to be raised immediately.

    public partial class PhidgetsManager:IDisposable
    {
        Manager _manager;
        List<Phidget> _phidgetList = new List<Phidget>();
        public PhidgetsManager()
        {
            _manager = new Manager();
            _manager.Attach += _manager_Attach;
            _manager.Detach += _manager_Detach;
        }

        private void _manager_Detach(object sender, Phidget22.Events.ManagerDetachEventArgs e)
        {
            _phidgetList.Remove(e.Channel);
            OnPhidgetDetached(e.Channel);
        }

        private void _manager_Attach(object sender, Phidget22.Events.ManagerAttachEventArgs e)
        {
            _phidgetList.Add(e.Channel);
            OnPhidgetAttached(e.Channel);
        }
        public enum Action
        {
            Connected, 
            Disconnected
        }

        public class PhidgetsActionEventArgs
        {
            public Phidget Phidget { get; internal set;  }
            public Action Action { get; internal set; }
        }

        public delegate void PhidgetsActionEvent(object sender, PhidgetsActionEventArgs args);
        public event PhidgetsActionEvent DeviceAttached;
        public event PhidgetsActionEvent DeviceDetached;

        protected void OnPhidgetAttached(Phidget p)
        {
            if (DeviceAttached != null)
            {
                var arg = new PhidgetsActionEventArgs()
                {
                    Action = Action.Connected,
                    Phidget = p
                };
                DeviceAttached(this, arg);
            }
        }

        protected void OnPhidgetDetached(Phidget p)
        {
            if (DeviceDetached != null)
            {
                var arg = new PhidgetsActionEventArgs()
                {
                    Action = Action.Connected,
                    Phidget = p
                };
                DeviceDetached(this, arg);
            }
        }

    }

In my MainViewModel I only wanted to capture the RFID readers. It has its own list for maintaining these. When a device of the right type is found, I create anew RFID number and assign its DeviceSerialNumber. When the class’s Open() method is called, it will attach to the correct hardware since the serial number has been set. The RFID instance is added to my list. My list uses a wrapper class that exposes the device serial number and the current RFID tag that the device sees. This is exposed through a ViewModel object so that the UI will automatically update.

    public class RFIDReaderViewModel: ViewModelBase, IDisposable
    {
        RFID _reader;

        public RFIDReaderViewModel(Phidget phidget)
        {
            if(phidget == null)
            {
                throw new ArgumentNullException("phidget");
            }
            if(phidget.ChannelClass != ChannelClass.RFID)
            {
                throw new ArgumentException($"Phidget must be an RFID Reader. The received item was a {phidget.ChannelClassName}");
            }
            this.Reader = new RFID();
            this.Reader.DeviceSerialNumber = phidget.DeviceSerialNumber;
            this.Reader.Tag += Reader_Tag;
            this.Reader.TagLost += Reader_TagLost;
            this.Reader.Open();
        }

        private void Reader_TagLost(object sender, Phidget22.Events.RFIDTagLostEventArgs e)
        {
            Dispatcher.CurrentDispatcher.Invoke(() =>
            {
                CurrentTag = String.Empty;
            });
        }

        private void Reader_Tag(object sender, Phidget22.Events.RFIDTagEventArgs e)
        {
            Dispatcher.CurrentDispatcher.Invoke(() =>
            {
                CurrentTag = e.Tag;
            });
        }

        public RFID Reader
        {
            get { return _reader;  }
            set { SetValueIfChanged(() => Reader, () => _reader, value); }
        }
        String _currentTag;
        public String CurrentTag
        {
            get { return _currentTag;  }
            set { SetValueIfChanged(() => CurrentTag, ()=>_currentTag, value);  }
        }

        public void Dispose()
        {
            try
            {
                this.Reader.Close();
            }
            catch (Exception exc)
            {

            }
        }
    }

All that’s left is the XAML. In the XAML for now, I’m only interested in listing the serial numbers and the tag strings.

<UserControl x:Class="PhidgetDetectionDemo.Views.MainView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:PhidgetDetectionDemo.Views"
             >
    <Grid>
        <ListView ItemsSource="{Binding ReaderList}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="{Binding Reader.DeviceSerialNumber}" />
                        <TextBlock Grid.Column="1" Text="{Binding CurrentTag}"/>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</UserControl>

With that in place, now when I run the project, I get live updates of RFID tags coming into or out of range of each of the readers connected.

If you try to run this though, you may encounter a problem. The RFID readers (as the name implies) use radio frequencies for their operation. If they are close to each other, they may interact and interfere with each other. Don’t worry, this doesn’t mean that you can’t use them in close proximity. In my next entry I’ll show how to deal with RFID readers that are close to each other and mitigate interference through software.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.