In manufacturing, part tracking is essential for quality control and resource management. One method for tracking parts throughout production lines and across multiple sites involves generating and scanning barcodes.
Although existing software can format and send print commands from manual user inputs, automating this process within your Ignition project can minimize errors and streamline label generation. Ignition, a widely used SCADA application, offers robust integration capabilities when combined with MES platforms. Employing labels to display identifying information such as part numbers, materials, and timestamps significantly reduces the need for manual data entry.
Automating label printing provides additional advantages, such as enabling formatting changes and modifications directly within the Ignition Designer, thereby making the process scalable for future adjustments. This feature is particularly useful when utilizing different barcode scanners or reformatting the printed codes.
This blog will guide you through setting up printing scripts directly in the Ignition Designer, as well as cover the basics of label formatting with ZPL.
Using Ignition to Print Labels
Several methods are available for printing labels using the Ignition platform, depending on the network configuration of the printer and Ignition Gateway. One approach is to use a Gateway Message Handler to call the print functions, combined with an HMI button that an operator can use to format the data and send it to the Gateway.
Another approach involves sending commands to the printer within Ignition scripts on the component scripts/events themselves. This method integrates print commands into functions, automatically sending commands to the printer as processes occur. For instance, when an operator sets the status of a part to "shipped" the script that updates this status could include a print command.
Most industrial printers utilize Zebra Programming Language (ZPL) for formatting information. While ZPL strings may initially appear complex, they are straightforward when broken down into a series of short commands. ZPL offers flexibility for displaying data to optimize label size and orientation. There are also many options for formatting label barcodes.
After pulling in data from tags, a database, or user input to display on the label, it must be parsed into strings. ZPL commands then reformat the data into a ZPL string for printing and subsequent scanning. Below is an example of these commands and the resulting label. An online generator can assist in visualizing the code as we have done below.
Commands you should know:
^XA command to start a new format
^FO 'field origin,' sets the coordinates of where the data is positioned
^FS 'field separator,' moves to a new formatting command
^XZ ends every format
^FD 'field data,' precedes the data you are inserting into the formatted ZPL string
Example:
zplString = """
^XA #Start Format
^FO50,20^BXN,6,200,26,26^FD%s^FS #Field origin, data matrix bar code, field data, field separator (create barcode)
^CF0,48 #Sets font size to 48
^FO220,30^FD%s^FS #Text1 print (position and orientation set)
^CF0,32 #Set font size to 32
^FO220,90^FD%s^FS #Text2 print (position and orientation set)
^CF0,64 #Set font size to 64
^FO220,130^FD%s^FS #Text3 print (position and orientation set)
^XZ #End Format
"""%(BarcodeData, Text1, Text2, Text3)
Here is a visual of the label formatted above using this online generator.
Examples and Scripting Explained
Now that we have covered the basics of generating a ZPL strings, there are a couple options for sending the string to the printer. The recommended method uses the Socket API, which can be imported as a Python module directly into Ignition scripts. Find more information on the Socket API with Ignition here.
One method to send the ZPL string to the printer is to create a gateway message handler, similar to "gatewayPrint" referenced in this example:
#Gateway message handler: 'gatewayPrint'
def handleMessage(payload):
import time
for label in payload['payload']: #For printing multiple labels
data = {"payload":label}
performPrint(data) #Calls print function for each label
def performPrint(payload):
import java.lang.Exception as JavaException
try:
import os
import socket #Import Socket module
printerIP = "[printer IP]"
port=[printer port]
#Open socket
tcpSocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
#Send to printer
tcpSocket.connect((printerIP,port))
tcpSocket.sendall(payload)
finally:
#Close socket
tcpSocket.shutdown(socket.SHUT_RDWR)
tcpSocket.close()
except (Exception, JavaException) as err:
log.infof(str(err)) #Logs error
Next, either on a button event, or within a script, call the gateway message handler:
#Script on the event or within component scripting that calls 'gatewayPrint'
system.util.sendMessage(project="[project name]", messageHandler="gatewayPrint", payload=payload, scope="G")
This sends the ZPL string to the printer. The message handler diagnostics can be viewed on the Status Page of the gateway.
Another method is to define a function within a standard Ignition script, then call the function in an event or through a message handler/tag change script:
import socket #Imports socket module to communicate with printer
def sendToPrinter(printerIP, payload):
#Send to printer if valid printer IP
if printerIP != '':
port=[port] #Port to listen on
try:
updSocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #Use default protocol (Transmission Control Protocol (TCP)) to transport messages to the network
updSocket.connect((printerIP,port)) #Connect to printer
updSocket.sendall(payload) #Send payload (ZPL string) to printer
updSocket.shutdown(socket.SHUT_RDWR) #Shutdown connection and close
updSocket.close
finally:
pass
Then, on the button event (or in message handler/change script):
#This is the script on the button event
sendToPrinter('[printer IP address]', payload)
These two examples essentially accomplish the same thing, using different methods of scripting within Ignition.
Learn more about DMC's Ignition expertise and contact us to get started on your next HMI, SCADA, or MES project.