This README demonstrates how to communicate with a Videojet printer using the Zipher Text Communications Protocol, as detailed in the official documentation:
📄 Protocol PDF: Zipher Text Coms Protocol v1.21
This code:
- Establishes a TCP socket connection to a Videojet printer
- Sends commands to retrieve machine and recipe status (
GST
andGJD
) - Parses the response
- Updates internal values with the printer's status and recipe info
Command | Name | Min Version |
---|---|---|
SEL | Job Select (sequential fields) | 1 |
SLA | Job Select (named fields) | 1 |
JDU | Job Data Update (sequential fields) | 1 |
JDA | Job Data Update (named fields) | 1 |
PRN | 1 | |
SST | Set printer state | 1 |
GST | Get printer state | 1 |
CAF | Clear All Faults | 1 |
PML | PackML commands and requests | 1 |
SLI | Job Select with Allocation | 2 |
JDI | Job Data Update with Allocation | 2 |
GPC | Get Counts | 2 |
SPC | Set Counts | 2 |
LAS | Line Assignment | 3 |
LDU | Line Data Update | 3 |
LSL | Line Select | 3 |
CLN | Clear Line | 3 |
SLN | Stop Line | 3 |
IJS | Interactive Job Selection | 4 |
CQI | Clear Queue Item | 4 |
GTD | Get Time And Date | 5 |
TAD | Set Time And Date | 5 |
GAN | Get async notification enable map | 6 |
SAN | Set async notification enable map | 6 |
EAN | Enable all async notifications | 6 |
DAN | Disable all async notifications | 6 |
DPN | Disable print notifications | 6 |
SNO | Enable/Disable a Single Notification | 6 |
CAW | Clear All Warnings | 6 |
CEM | Clear error (Fault or Warning) | 6 |
GFT | Get current Faults | 6 |
GWN | Get current Warnings | 6 |
STS | Async current overall status | 6 |
ERS | Async current error status | 6 |
JOB | Async current job details | 6 |
PRS | Async print start | 6 |
PRC | Async print complete | 6 |
OUT | Async output changes | 6 |
QSZ | Get update queue size and status | 6 |
GJN | Get selected job name and line | 6 |
GJL | Get Job List | 7 |
GJF | Get Job Field List | 7 |
GJD | Get Current Job Data | 7 |
CMD | Perform printer specific command | 8 |
SPD | Set Print Density (2300 or later) | 9/10 |
GPD | Get Print Density (2300 or later) | 9/10 |
SHD | Serialisation Header and Data | 11 |
SHO | Serialisation Header Only | 11 |
SDO | Serialisation Data Only | 11 |
SCF | Serialisation Change Field Data | 11 |
SRC | Serialisation Record Count | 11 |
SCB | Serialisation Clear Buffer | 11 |
SID | Serialisation Indexed Data | 11 |
SFS | Serialisation Free Space | 11 |
SNI | Serialisation Next Record Index | 11 |
SLR | Serialisation Last Record Index | 11 |
SMR | Serialisation Set Max Records | 11 |
SGM | Serialisation Get Max Records | 11 |
SED | Set Encoder Direction | 11 |
GED | Get Encoder Direction | 11 |
GCL | Get Consumable Levels | 11 |
DFS | Determine Free Space | 11 |
Command | Description |
---|---|
GST |
Get status information |
GJD |
Get job data / recipe info |
Each command ends with CR
(carriage return, ASCII 13).
dim Separator[1] as System.String;
dim splittedString[50] as string;
dim msg[50] as System.Byte;
dim receivedStatus[1024] as System.Byte;
dim receivedStatusString as string;
dim overallState as string;
dim errorState as string;
dim currentRecipe as string;
dim batchCount as string;
dim totalCount as string;
dim recipesCount as integer;
dim recipeIndex as integer;
try
' ### POSSIBLE SOCKET CREATION ###
if (ClientSocket == null) then
ClientSocket = new System.Net.Sockets.Socket(
System.Net.Sockets.AddressFamily.InterNetwork,
System.Net.Sockets.SocketType.Stream,
System.Net.Sockets.ProtocolType.TCP
);
ClientSocket.SendTimeout = 2500;
ClientSocket.ReceiveTimeout = 10000;
endif;
' ### SOCKET OPENING ###
if (not ClientSocket.Connected) then
ClientSocket.Connect(YOUR-IP-ADDRESS, YOUR-TCP-PORT);
endif;
if (ClientSocket.Connected) then
Separator[1] = "|";
' ### READING MACHINE STATUS ###
msg = System.Text.Encoding.ASCII.GetBytes("GST" + StringChar(13));
ClientSocket.Send(msg, System.Net.Sockets.SocketFlags.None);
ClientSocket.Receive(receivedStatus[], 0, 1024, System.Net.Sockets.SocketFlags.None);
receivedStatusString = System.Text.Encoding.ASCII.GetString(receivedStatus[]);
splittedString = System.Convert.ToString(receivedStatusString).Split(Separator, System.StringSplitOptions.None);
overallState = splittedString[2];
errorState = splittedString[3];
currentRecipe = splittedString[4];
batchCount = splittedString[5];
totalCount = splittedString[6];
' ### READING RECIPE PARAMETERS ###
msg = System.Text.Encoding.ASCII.GetBytes("GJD" + StringChar(13));
ClientSocket.Send(msg, System.Net.Sockets.SocketFlags.None);
ClientSocket.Receive(receivedStatus[], 0, 1024, System.Net.Sockets.SocketFlags.None);
receivedStatusString = System.Text.Encoding.ASCII.GetString(receivedStatus[]);
splittedString = System.Convert.ToString(receivedStatusString).Split(Separator, System.StringSplitOptions.None);
Me.DueDate = splittedString[3].Replace("Campo00 =", "");
Me.lot = "L" + splittedString[5].Replace("Campo03 =", "");
' ### SOCKET CLOSING ###
if (ClientSocket.Connected) then ClientSocket.Close(); endif;
if (overallState == 3) then
if (errorState <> 0) then
Me.HMI.status = 3; ' Running with alarms
else
Me.HMI.status = 2; ' Running normally
endif;
elseif (overallState == 4) then
Me.HMI.status = -1; ' Error state
else
Me.HMI.status = 0; ' Idle or unknown
endif;
Me.HMI.recipes = System.String.Format("{0} {1}", Me.lot, Me.DueDate);
endif;
catch
LogError(error);
Me.HMI.status = -1;
Me.HMI.recipes = "";
endtry;
if (ClientSocket <> null) then
ClientSocket.Dispose();
ClientSocket = null;
endif;
Videojet Zipher Text Coms Protocol v1.21
View PDF