Search code examples
c#arraystcp

How to read three TCP/IP RFID readers using a router using a PC application?


I have purchased 3 RFID readers which are TCP/IP compatible. I have started by first connecting one reader to my my router and also connected my PC to the same router. I have adjusted the reader's IP to match the routers IP, so the PC can communicate with the reader. I use the following code to connect to the reader:

private void connect_reader(string IP)
    {
        try
        {
            if (device.ConnectDevice(IP, 4501) == true)
            {
                try
                {
                    Boolean flag = device.StopReadTag();
                    flag = device.StopReadTag();
                    if (true == flag)
                    {
                        MessageBox.Show("Reader connected successfully.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        EnableButtons();
                    }
                    else
                    {
                        MessageBox.Show("Reader not connected successfully.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        device.DisConnectDivice();
                        button_OpenPort.Enabled = false;
                    }
                }
                catch (System.Net.Sockets.SocketException ex)
                {
                    MessageBox.Show("Reader not connected successfully.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    device.DisConnectDivice();
                }
            }
            else
            {
                MessageBox.Show("Reader not connected successfully.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        catch (System.Net.Sockets.SocketException ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

The following code is used to disconnect from the reader:

private void disconnect_reader()
    {
        device.DisConnectDivice();
        MessageBox.Show("Reader disconnected successfully.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
        button_OpenPort.Enabled = true;
    }

The reader connects successfully to the PC using the application. My router also has two more additional ethernet ports and therefore I would like to connect another two readers to the router.

My application is to extract the ID from the RFID tags when there are read by the RFID readers. I also want to know what reader scanned that particular RFID tag. For example, I have three readers with the following IP addresses: reader1(192.168.4.100), reader2(192.168.4.101), and readers(192.168.4.102). Now position those three readers at three different positions in an apartment. A person with an RFID tag walks pass reader2, reader2 then scans the RFID tag and relays the info back to the application. First, the application can only connect to one antenna only. So what I want to do is to store all the IP addresses of the three readers in an array, as shown below. Then I want to loop through each reader for a period of time. So in the example above when the RFID tag is detected my reader2, the application will store the RFID tag ID and also assign the RFID tag ID to reader2.

My question is, therefore, in the above code I was thinking of just storing the IP addresses of each reader in the array and then connect to one reader at a time. So for instances:

void reader() //example method
{
   array string reader_ip[] = {192.168.4.100; 192.168.4.101; 192.168.4.102};

   for(int i = 0; i <4; i++) //Loop through all readers by connecting to the reader via their IP addresses for a period of time them disconnect from the reader and then connect to the other reader.
   {
     connect_reader(reader_ip[i]); //Connects to the specific reader 
     readTags(); //readTags that are detected by the connected reader
     disconnect_reader(); disconnects to the specific reader 
     timeDelay(); //time delay of 2secs before reconnecting to the next reader
   }
}

Is this the correct way for switching between the networked readers, in order to obtain the data that is scanned by the different readers?


Solution

  • Without knowing which manufacturer or SDK you are working with, I can only make you some suggestions in pseudo code.

    Main Point: The example code you have provided is limiting you since you have chosen to have one device which I have understood to be an instance of an RFIDReader class. I would recommend you take an approach of having a collection of RFIDReader, that you connect to a single time at the being of your application, and maintain those connections until you are finished. That may look something like this:

    In the following, I use a made up class called RFIDReader. It can Connect(), Disconnect(), and GrabTags() which simple up dates a the property of Tags, a collection of the tags in detected:

    public class RFIDReader
    {
        // Container property for detected tags
        public List<Tag> Tags { get; private set; }
    
        // Connection Methods
        public void Connect(string ipAdress) { }
        public void Disconnect() { }
    
        // Polling Method
        public void GrabTags()
        {
            // Tags = GrabMeSomeTags()
        }
    }
    

    In the console application example below, (again all pseudo, no error checking etc), I have chosen to use a System.Timers.Timer to "Poll" all three readers in turn, every 2000ms:

    class Program
    {
        // An array of your three RFID readers
        static RFIDReader[] rFIDReaders = new RFIDReader[3];
        // An array of the three IPAdresses
        static string[] ipAdress = new string[3]
        {
                "192.168.4.100",
                "192.168.4.101",
                "192.168.4.102"
        };
    
        static void Main(string[] args)
        {
            // A timer for polling the readers, every 2000ms (2 seconds)
            Timer pollTimer = new Timer(2000);
            pollTimer.Elapsed += PollTimer_Elapsed;
    
            // Setup
            for(int i = 0; i < 3; i++)
            {
                Console.WriteLine($"Connecting to reader {i} at IPAdress {ipAdress[i]}");
                rFIDReaders[i].Connect(ipAdress[i]);
            }
    
            // Start Timer
            Console.WriteLine("Starting reader polling...");
            pollTimer.Start();
            Console.WriteLine("System Running.");
    
            // Wait for user to Exit
            Console.WriteLine("Press any ket to exit...");
            Console.ReadKey();
    
            // Stop the timer
            pollTimer.Stop();
    
            // Disconnect the RFIDReaders
            foreach (RFIDReader rFIDReader in rFIDReaders)
            {
                rFIDReader.Disconnect();
            }
        }
    
        private static void PollTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            foreach(RFIDReader rFIDReader in rFIDReaders)
            {
                rFIDReader.GrabTags();
            }
        }
    }
    

    This solution will hold on Console.ReadKey();, mean while, every two seconds the Timer.Elapsed event invokes the handler PollTimer_Elapsed. You could use any mechanism for your application continuing of course (perhaps you have some Form/WPF GUI?), but key is that the timer will regularly have the RFIDReaders update they're own collection of Tag for your analysis.