Search code examples
c#sdkrfidoctane-sdk

How to encode an RFID UHF tag only once using Impinj speedway


Im using ocatne SDK C# and impinj speedway R420 to encode RFID UHF gen2 tags.

I used the samples of the SDK to write to the tags and it is working, my problems start when i want encode continuous and i will explain.

I want to put a single tag in the reader field encode it and remove it and then to wait for 2nd tag encode it and so on....

I was tring to set Search Mode to 'Single Target' and use Session 2 but it is only reading the tag and not encoding it, i never get the encode seq to run.

any other option it just keep encoding and encoding very fast and i dont know when to remove the tag so i can control the encoding data.

my code here:

using System;
using System.Threading;
using Impinj.OctaneSdk;
using System.Windows.Threading;


namespace OctaneSdkExamples
{
    class Program
    {
        // Create an instance of the ImpinjReader class.
        static ImpinjReader reader = new ImpinjReader();

        const ushort EPC_OP_ID = 123;
        const ushort PC_BITS_OP_ID = 321;

        static Random random = new Random((int)DateTime.Now.Ticks);

        public static void DelayAction(int millisecond)
        {
            var timer = new DispatcherTimer();
            timer.Tick += delegate

            {
                timer.Stop();
            };

            timer.Interval = TimeSpan.FromMilliseconds(millisecond);
            timer.Start();
        }

        static string GetRandomEpc()
        {
            string epc = "";
            int numWords = random.Next(1, 7);

            for (int i = 0; i < numWords; i++)
                epc += random.Next(0, ushort.MaxValue + 1).ToString("X4");

            return epc;
        }

        static void ProgramEpc(string currentEpc, ushort currentPcBits, string newEpc)
        {
            // Check that the specified EPCs are a valid length
            if ((currentEpc.Length % 4 != 0) || (newEpc.Length % 4 != 0))
                throw new Exception("EPCs must be a multiple of 16 bits (4 hex chars)");

            Console.WriteLine("\nAdding a write operation to change the EPC from :");
            Console.WriteLine("{0} to {1}\n", currentEpc, newEpc);

            // Create a tag operation sequence.
            // You can add multiple read, write, lock, kill and QT
            // operations to this sequence.
            TagOpSequence seq = new TagOpSequence();

            // Specify a target tag based on the EPC.
            seq.TargetTag.MemoryBank = MemoryBank.Epc;
            seq.TargetTag.BitPointer = BitPointers.Epc;
            seq.TargetTag.Data = currentEpc;

            // If you are using Monza 4, Monza 5 or Monza X tag chips,
            // uncomment these two lines. This enables 32-bit block writes
            // which significantly improves write performance.
            //seq.BlockWriteEnabled = true;
            //seq.BlockWriteWordCount = 2;

            // Create a tag write operation to change the EPC.
            TagWriteOp writeEpc = new TagWriteOp();
            // Set an ID so we can tell when this operation has executed.
            writeEpc.Id = EPC_OP_ID;
            // Write to EPC memory
            writeEpc.MemoryBank = MemoryBank.Epc;
            // Specify the new EPC data
            writeEpc.Data = TagData.FromHexString(newEpc);
            // Starting writing at word 2 (word 0 = CRC, word 1 = PC bits)
            writeEpc.WordPointer = WordPointers.Epc;

            // Add this tag write op to the tag operation sequence.
            seq.Ops.Add(writeEpc);

            // Is the new EPC a different length than the current EPC?
            if (currentEpc.Length != newEpc.Length)
            {
                // We need adjust the PC bits and write them back to the 
                // tag because the length of the EPC has changed.

                // Adjust the PC bits (4 hex characters per word).
                ushort newEpcLenWords = (ushort)(newEpc.Length / 4);
                ushort newPcBits = PcBits.AdjustPcBits(currentPcBits, newEpcLenWords);

                Console.WriteLine("Adding a write operation to change the PC bits from :");
                Console.WriteLine("{0} to {1}\n", currentPcBits.ToString("X4"), newPcBits.ToString("X4"));

                TagWriteOp writePc = new TagWriteOp();
                writePc.Id = PC_BITS_OP_ID;
                // The PC bits are in the EPC memory bank.
                writePc.MemoryBank = MemoryBank.Epc;
                // Specify the data to write (the modified PC bits).
                writePc.Data = TagData.FromWord(newPcBits);
                // Start writing at the start of the PC bits.
                writePc.WordPointer = WordPointers.PcBits;

                // Add this tag write op to the tag operation sequence.
                seq.Ops.Add(writePc);

            }

            // Add the tag operation sequence to the reader.
            // The reader supports multiple sequences.
            reader.AddOpSequence(seq);
        }

        static void Main(string[] args)
        {
            try
            {

                reader.Connect("10.0.1.201");

                // Assign the TagsReported event handler.
                // This specifies which method to call
                // when tags reports are available.
                reader.TagsReported += OnTagsReported;

                reader.TagOpComplete += OnTagOpComplete;

                Settings settings = reader.QueryDefaultSettings();

                settings.Report.IncludeAntennaPortNumber = true;
                settings.Report.IncludePcBits = true;
                settings.ReaderMode = ReaderMode.AutoSetDenseReader;
                settings.Antennas.DisableAll();
                settings.Antennas.GetAntenna(1).IsEnabled = true;
                settings.Antennas.GetAntenna(1).MaxRxSensitivity = true;
                settings.Antennas.GetAntenna(1).TxPowerInDbm = 10;
                settings.SearchMode = SearchMode.SingleTarget;
                settings.Session =2;
                settings.TagPopulationEstimate = 1;

                reader.ApplySettings(settings);
                // Start reading.
                reader.Start();

                // Wait for the user to press enter.
                Console.WriteLine("Press enter to exit.");
                Console.ReadLine();

                // Stop reading.
                reader.Stop();

                // Disconnect from the reader.
                reader.Disconnect();
            }
            catch (OctaneSdkException e)
            {
                // Handle Octane SDK errors.
                Console.WriteLine("Octane SDK exception: {0}", e.Message);
            }
            catch (Exception e)
            {
                // Handle other .NET errors.
                Console.WriteLine("Exception : {0}", e.Message);
            }
        }

        static void OnTagsReported(ImpinjReader sender, TagReport report)
        {
            // This event handler is called asynchronously 
            // when tag reports are available.
            // Loop through each tag in the report 
            // and print the data.
            reader.TagsReported -= OnTagsReported;
            Tag tag = report.Tags[0];
            ProgramEpc(tag.Epc.ToHexString(), tag.PcBits, GetRandomEpc());

        }

        static void OnTagOpComplete(ImpinjReader reader, TagOpReport report)
        {
            // Loop through all the completed tag operations.
            foreach (TagOpResult result in report)
            {
                // Was this completed operation a tag write operation?
                if (result is TagWriteOpResult)
                {
                    // Cast it to the correct type.
                    TagWriteOpResult writeResult = result as TagWriteOpResult;
                    if (writeResult.OpId == EPC_OP_ID)
                        Console.WriteLine("Write to EPC complete : {0}", writeResult.Result);
                    else if (writeResult.OpId == PC_BITS_OP_ID)
                        Console.WriteLine("Write to PC bits complete : {0}", writeResult.Result);

                    // Print out the number of words written
                    Console.WriteLine("Number of words written : {0}", writeResult.NumWordsWritten);


                }
            }
            //DelayAction(3000);
            //Thread.Sleep(3000);
            reader.TagsReported += OnTagsReported;
        }
    }
}

Solution

  • When you use Session 2 and Single Target, the tag will respond only once, until it has been out of the field for more than a certain amount of time. That means that when you read it, and then try to program it, it doesn't respond anymore. Therefore it is necessary in this set-up to use Dual Target.

    To figure out whether you already have programmed a specific tag, keep track of the TID of a tag: for most tags this contains a unique serial number programmed on IC production that will never change, even if you change the EPC. You can watch this value for a new tag to be entered in the field.