Best practices for capturing Barcode scanner data?

My question is more about how to handle a bunch of streaming data on an ethernet network that may be coming into my PLC at an unknown rate. The fact that it is coming from a barcode scanner is somewhat irrelevant.

I have PLC logic that is taking string data from a Barcode scanner and placing it into a string called RAW_INPUT. When this RAW_INPUT string changes, I push the value into a FIFO (array of Strings) named SCANNER_FIFO via PLC logic since this signifies a new barcode being scanned. When the array isn’t empty, I turn the DATA_WAITING bit on in the PLC. I then have a timed Client script that checks the value of the DATA_WAITING bit every 1000ms. If the DATA_WAITING bit is on, I write a 1 to the HMI_DATA_REQUEST bit in the PLC, which reads the latest barcode string from SCANNER_FIFO and moves it into BARCODE_DATA. I then have a tag change script in Ignition monitoring BARCODE_DATA to perform all the HMI-related operations whenever I see the value change to anything other than an empty string. This is where the storing of the value in a database, updating some counters on the HMI, etc, occur. Basically, my goal of this SCANNER_FIFO and PLC logic is to queue up the input data (which can be coming at an unknown rate) to present it to my Ignition application in a consistent and controlled manner.

When I setup simulation logic in the PLC (for stress-testing) to push a new simulated Barcode value to RAW_INPUT, I find that out of every 1000 codes being simulated, the HMI tends to “miss” a few. It is definitely better than when I was attempting to monitor the RAW_INPUT tag for changes directly.

I have a special scan class for the trigger and string tags. (Method:direct, slow rate:250ms). My client script is running every 1000ms as mentioned previously, and I have a 500ms dwell built in to the PLC logic that will turn the DATA_WAITING bit on (it will stay off for 500ms in between “data requests” if there is more than one barcode value available in the FIFO.) I can always increase all my delays and intervals to play it safe, but I want to make sure I am not masking any design flaws in the process of doing that.

Please let me know if there is anything I can do to explain this better.


Some other info: I did not use a Tag Change script on DATA_WAITING because I was concerned about triggers being missed. If one trigger gets missed (if I don’t see the bit go low in between barcodes), I’ll never be able to trigger the HMI_DATA_REQUEST bit, which causes the PLC logic to copy the latest data into BARCODE_DATA and turn off DATA_WAITING (until the dwell timer expires)

I’m not sure it needs to be as complicated as you’ve described. It may work to run your script as a gateway event script which is triggered off of the change of the RAW_INPUT tag. If you have your the RAW_INPUT tag being scanned at a fast rate (<500ms) then this should work to catch all scans provided they are at least 1 second apart to give your script time to run. See the ‘Tag Event Scripts’ section in the manual for info relating to how five changes can be queued while the script is running.

How is the barcode data being transmitted to the PLC from the scanner?

The scanner communicates with the PLC over ethernet.

The problem with simply monitoring the RAW_INPUT tag is that if that tag changes twice before Ignition reads it we will miss barcodes.

If the scans are coming in less than 1 second intervals I might try moving the scanned data into alternating buffer tags and triggering the tag change script off of each of these tags.

I like the FIFO idea, but I might have done the flow a bit differently.

Incoming Data:
–Scan Barcode
–Append a 0-9 digit. The first one gets a zero, next next a one, etc, rolling over after 9. This ensures that at least one character is different between scans.
–Stick the result into the FIFO.

Outgoing Data:
– Read from FIFO into whatever location for Ignition to rad it.
– After Ignition processes it, send the same string back. When the strings are equal , you know the process is complete.
– Rinse, repeat.