JaxGTO
Member
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.
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.