My recent experience using the Zebra AOI for printing from the PLC

JaxGTO

Member
Join Date
Apr 2009
Location
Kalieefornia
Posts
1,069
Here is my recent experience using the Zebra AOI for printing from the PLC. Please do not ask me for my PLC or template files as they are the property of my end customer and I cannot share them. But if you have questions I will do my best to answer them.


1. Licensing.

Licensing is best done through your local Zebra office. What will happen when you purchase it, is that you will receive what they call credits. When you download the license you use up your credits that they call ZPoints. You then have to follow the document ‘Activating the Network Connect OS’. That will walk you through activating the printer with the right firmware for CIP operations. It is best to also open a ticket with tech support to be sure you get the right file. This first time I tried it, it sent me the wrong firmware. Plus the tech support people have some great examples and other related documents they can send you.

2. Setup as a Network Printer from a PC or Server

I found it very handy to have the printer setup as a network printer. The main reason is for using the Zebra Setup Utility. This utility allows you to connect directly to the printer and execute ZPL commands. It is a big time saver for creating, testing and storing template files. The best document for learning ZPL command I found was the ‘Programming Guide for ZPL II’ which you can find on the internet. It does a pretty good job of explaining each command. It also has some good examples of using the template files.

3. AOI Installation

This is a pretty straight forward installation. I was able to get it to work in a CompactLogix running Version 19 and a ControlLogix (1756-L71) running Version 30.

4. AOI Usage

This is where all the fun begins. The main thing I found is that if you only need 5 or less field variables in your label you are better off using the built in fields PRINTERNAME:O.XF_Field1 through 5. I needed about 30 so I ended up having to use the PRINTERNAME:O.RawParserData using 3 blocks transferred for each label. One thing to keep in mind is if your using more than 5 variables then you can’t use the 1-5 variable fields, you have to put everything in the RawParserData method.

For the RawParserData method you place data in the block 318 bytes at a time (VERY IMPORTANT NOTE: The first two words must remain nulls or zero). I had to use 3 blocks so I made string that matched the RawParserData tag so I could simple map my data to those blocks and then copy them into the RawParseData tag and trigger the write. To make it easier to layout I used an Excel sheet to layout each block. You can have spaces in words to make the data you have to insert easier to find. For example:
Starting at element 2 ‘^FN801^FDXXXXX^FS ^FN802^FDXXXXXXXX^FS^FN’
Here my template (stored on the printers EEPROM memory) uses the variable number 801 and 802. When I send the block to print I replace the X’s with the actual values. I converted using the ControlLogix instructions to convert INT and Real to string then used the MID function to extract just the data I wanted. The template file has the corresponding lines to use that variable data that look like this:
‘^FO84,1069^ADN,36,20^FN801^FS’
‘^FO245,1069^ADN,36,20^FN802^FS’

Using the RawParserData tag you can send as many blocks as you need to the printer. You don’t even have to really use a template file. You could send the entire formatted label with embedded data to the printer. But having a template makes it easier to modify later and a lot less blocks to transfer. Another option is that you can send the template file from the PLC when you not in the middle of printing. I did this using the GSV command to sense when the printer was not connected, then sent the template file to it when it returned. This was because being a production printer it could get replaced in the middle of the night with the spare and this insures the printer has the current template file. And of course I made sure they have the instructions for putting the license and firmware on the spare printer. Because an off the shelf printer won’t work. It will connect to the PLC but it will ignore the printing commands.

The first block starting at word 2 has to be the ‘^XA’ and in the last block you send there must be a ‘^XZ’ (anywhere in the block after the last of your data). Keep in mind no matter how many blocks you send the first two words of each block sent has to be zero. So each block has 318 words of data you can send.

A command can cross blocks. In the example above the ‘^FO84,1069^A’ can be at the end of one block and the ‘DN,36,20^FN801^FS’ can be at the beginning of the next. But if you have the room to leave some spaces, it is easier to read if they don’t cross blocks.

5. Template Files

For the template file be sure to store it on the ‘E:’ drive so if the printer loses power it will retain the file. For my template file I made a text file on my PC then used the Zebra Setup Utility to send it to the printer. You can get a listing of the files on the ‘E:’ drive by typing ‘^XA^HWE:^XZ’ in the utility.

Do yourself a favor and document you template file. The printer has plenty of memory and it is a big time save when trouble shooting a problem. To add a comment use the ^FX command. For example:
^FX This section prints the header
All comments are ignored by the printer until it see the next ‘^’. You can have multiple lines of comments this way so you don’t have to put a ^FX at the beginning of each line.

I purchased the Zebra program Label Designer. It was not very helpful and the codes it generated would have used four times the data I needed to transfer. So unless your printing labels from your PC it really won’t help you with printing from a PLC.

A good resource for testing the format of your block is on the internet. Although it will not work for testing variable data. It is at:
http://labelary.com/viewer.html

6. Sending the Block in RawParserData tag.

I used a simple counter to do this. I place the first block of data (built in other strings) into the tag and then increment the tag ‘PRINTERNAME:O.SequenceNumber’. Then wait for the return tag ‘PRINTERNAME:I.SequenceNumber’ to be equal to the output tag. This is your indication that the printer received the block of data. Increment the counter and repeat until the counter is done. When the printer receives the last block with the ‘^XZ’ it, it will print the label. Seems simple but getting to this point took me a couple of weeks of trial and error.
 
Counter

@JaxGTO

I'm having problems with #6, how can you increment the sequence_number? I try it, and I mean, its working, but when it finished printing sequence number increment and increment and increment haha and I dont know why. Can you help me and give me and idea
 
@JaxGTO

I'm having problems with #6, how can you increment the sequence_number? I try it, and I mean, its working, but when it finished printing sequence number increment and increment and increment haha and I dont know why. Can you help me and give me and idea


Show your code; what is triggering the incrementing? Remember that every rung in a continuous task gets executed at 10-1000Hz, more or less.
 
I have a bit that triggers the sending of the data. When that bit is on I increment the output sequence number by one with a simple ADD.
 
When I increment the output sequence number I move a copy of it to another register. When that register matches the input sequence number I reset the trigger.
Now that is a simplified version of what actually happens. The code i have has to send up to 3 blocks of data before it prints the label. But the basic idea is the same.
 
Real men , er, ... real control guys don't use this approach.

What if customer need to replace their printer in the middle of the night?
 
Real men , er, ... real control guys don't use this approach.

What if customer need to replace their printer in the middle of the night?


Not that I feel that I need to defend myself, but the topic was not replacing it in the middle of the night. For your information I monitor the printer using a GSV. If it goes offline, I send the complete configuration to it from the PLC. All the tech needs to do is set the IP from the printer display, which there are complete instructions on the local HMI screen, with pictures. I then give them the option on the local HMI to re-print as many as the last 10 labels.
 
Not meant to offend you. If I am not mistaken, the firmware need to be installed & upgraded to be CIP compliance, that the part I don't think your customer can do it.
 
Last edited:
@L33ER
In my case I installed the new firmware in all my printers ( converted them from tcp/ip to EIP) , so the only change I would have to do is to change IP address.
My approach is not the same as Jagxto’s.
Sorry I just saw this item today.
BTW: L33ER is on of my favorites.
 

Similar Topics

My customer had an old PanelView 1000 in a system that is going to be pulled out next year. The PV screen became oxidized so bad you could barley...
Replies
1
Views
1,691
Is anyone aware of any recent Rockwell Software security issues that require version upgrades to mitigate? I'm talking over the past 2 months.
Replies
1
Views
704
I have 6 Red Lion DSP units displaying PLC strings and data to 6 industrial LED screens. After sending the .cd3 file from screen 2 to screen 6...
Replies
3
Views
1,013
We have just recently had an "outside" organisation upgrade our AB SLC PLC with a Controllogix. In doing so they have changed all of the messages...
Replies
9
Views
1,764
Hi guys, I have a local station SCADA program that requires a daily automatic 1 page printout of the most recent alarms from the Alarm and Event...
Replies
4
Views
3,366
Back
Top Bottom