Machine Interface for Event Message Sending / Command Processing

EVENTLINK IM (for OS/2 / eComStation based Universal Through Hole Machines utilizing IMUPS)
EVENTLINK SM (for Windows based Universal Surface Mount Machines utilizing UPS+)
EVENTLINK IM/SM is designed as an application runnable directly on the Universal assembly machine.

It has three main features:

1. Event Messaging, sending event messages from the machine to a Windows PC through a STREAM-SOCKET (TCP/IP)

The number and types of the event messages are preselected by the IMUPS/UPS+ installation,
but extendible and configurable by the user.

2. Command Processing, receiving command from a Windows PC, returning results to the PC (both STREAM-SOCKETs on protocol TCP/IP).

3. Component Consumption Data Reporting, sends periodically the consumption data for components for the actual product program (through a STREAM-SOCKET (TCP/IP)

Two different sockets are used, EVENTLINK uses one socket as a client for sending data,
another one for receiving commands as a server. The PC as the communication partner does just as well: It sends commands as a socket client and receives data from EVENTLINK as a socket server.

Therefore, it can easily be integrated in any Windows application running on the PC.
The customer's Windows application just reads from and writes to a socket for machine communication,
EVENTLINK reconnects to the socket opened by the server before it writes.
If the socket has not yet been created, EVENTLINK spools the data for a period of time (time length for spooling is depending on the amount of data to be sent).
Whenever the connection is established, data are flowing in real time behavior.

1. Event Messaging

Format of Event Messaging

All records, sent and received, are closed by LF (Linefeed; ASCII 10)
The following format is used for the data transfer through the socket stream:
All at the machine generated event messages are sent out, unless EVENTLINK find a number
of event numbers listed in the EVLINK.CFG – file (EVENTLINK SM) or in the file EVENTS:CFG
(EVENTLINK IM).
Then only the listed events will send messages.

E:{eventnr};{id_maschine};{datetime};{eventtext}{cr}{lf}

E: - Indicator for an Event Message
eventnr - Event Identifikation Number as defined by UNIVERSAL
id_maschine - machine internal counter; only internally used
datetime - time stamp
eventtext - Event Message String as defined by UNIVERSAL

Sample:

E:  3014;0;03/19/2009 21:32:43;Machine palmed up
E:  1201;1;03/19/2009 21:32:43;Waiting for Interlocks to be restored
E: 3016;2;03/19/2009 21:32:43;Safety interlocks restored
E: 3004;0;03/19/2009 21:33:16;Updated circuit count for product  succeeded
E: 2015;3;03/19/2009 21:33:16;Dismiss error recovery screen
E: 3003;0;03/19/2009 21:33:16;Load of product AIRBAG succeeded
E: 1004;4;03/19/2009 21:33:16;Machine changed to Production Mode
E:51202;5;03/19/2009 21:33:17;Board Handling is waiting for interlock bypass off
E: 3005;0;03/19/2009 21:33:17;Clear management data succeeded
E: 2003;6;03/19/2009 21:33:17;Machine is ready to zero
E: 2004;7;03/19/2009 21:33:19;Machine zeroing in progress

2. Command Processing

Format of Machine Commands and Replies:

All records, sent and received, are closed by CR/LF (Carriage ReturnLinefeed; ASCII 13 / ASCII 10)

1. Command to machine

C{session_id}:{command}

C - Command indicator

{session_id} - command sequence; from 1 to max. 65535, next value starts from 1 again;
generated by PC-Application
- command to machine:

SH MA - return name of current active product program
NAMES - return list of available product programs stored on machine
GETFEEDERS - return list of component to feeder slot
assignments for the specified product program name

2. Machine Reply on Command:

D{session_id}:{reply}

D - indicates a data reply

{session_id} - session_id, as received by a PC command; keeps relation between command and reply
{reply} processed data as the reply on a PC command or the text 'EOT' to indicate end of block
or
NAK - command not accepted (replaces D:), error condition

Samples:

PC asks for current product name and sends:
C65531:SH MA{cr}{lf}
EVENTLINK replies current product name:
D65531:AIRBAG{cr}{lf}
D65531:EOT{cr}{lf}

PC asks for the list of stored products:
C65532:NAMES{cr}{lf}
EVENTLINK returns list of products, each product in a  separate line:
D65532:AIRBAG{cr}{lf}
D65532:ABS1{cr}{lf}
D65532:ABS2{cr}{lf}
D65532:RAINSENSOR{cr}{lf}
D65532:EOT{cr}{lf}

PC asks for component/feeder assignment for a product:
C65532:GETFEEDERS ABS1{cr}{lf}
EVENTLINK return assignment list, each assignment in a  separate line:

IM:
D{NR}:{COMPONENT ID};{FEEDERSLOT};{ROTATION AT SLOT};{COUNT TO PLACE}{cr}{lf}

D65532:4711471;7;0;6{cr}{lf}
D65532:4711768;11;0;1{cr}{lf}
D65532:4711447;19;0;1{cr}{lf}
D65532:4711455;22;0;1{cr}{lf}
D65532:EOT{cr}{lf}
SM:
D{NR}:{COMPONENT ID};{FEEDERSLOT},{TRACK};{ROTATION AT SLOT};{COUNT TO PLACE};{FEEDER TYPE}{cr}{lf}

D65532:4711471;7,1;0;6;E2412{cr}{lf}
D65532:4711768;11,1;0;1;E1208{cr}{lf}
D65532:4711447;19,1;0;1;E1204_PP{cr}{lf}
D65532:4711455;22,2;0;1;P0804_PP{cr}{lf}
D65532:EOT{cr}{lf}

All records, sent and received,
are closed by CR/LF
(Carriage ReturnLinefeed;
ASCII 13 / ASCII 10)

More Samples:

{cr}{lf} = Carriage Return/LineFeed,
ASCII 13 / ASCII 10

NAMES command
C1000:NAMES{cr}{lf}

NAMES reply
D1000:R4711991{cr}{lf}
D1000:R4711992{cr}{lf}
D1000:R4711993{cr}{lf}
D1000:R4711994{cr}{lf}
D1000:R4711994.test{cr}{lf}
D1000:TRANSFER{cr}{lf}
D1000:EOT{cr}{lf}

SH MA command
C2000:SH MA{cr}{lf}

SH MA reply
D2000:R4711992{cr}{lf}
D2000:EOT{cr}{lf}

GETFEEDERS command
C3000:GETFEEDERS R4711992{cr}{lf}

GETFEEDERS reply

for IM
D3000:4711471;7;0;6{cr}{lf}
D3000:4711768;11;0;1{cr}{lf}
D3000:4711447;19;0;1{cr}{lf}
D3000:4711455;22;0;1{cr}{lf}
D3000:EOT{cr}{lf}

for SM
D3000:4711471;7,1;0;6{cr}{lf}

D3000:4711768;11,1;0;1{cr}{lf}
D3000:4711447;19,1;0;1{cr}{lf}
D3000:4711455;22,2;0;1{cr}{lf}
D3000:EOT{cr}{lf}

D{NR}:{COMPONENT ID};{RefID-1}, ..,
{RefID-n};{FEEDERSLOT};
{ROTATION AT SLOT};
{COUNT TO PLACE}{cr}{lf}
- IM

D{NR>:{COMPONENT ID};{RefID-1}, ..,
{RefID-n};{FEEDERSLOT},{TRACK};
{ROTATION AT SLOT};
{COUNT TO PLACE}{cr}{lf}
- SM

3. Component Consumption Data Reporting

Periodically a consumption data set for components used for the actual product program
is sent out through the Stream Socket.
The data come every 15 minutes. The numbers are relative for the last period (delta).
In addition, a report is sent on product changeover.
All records with the same timestamp (datetime) beling to a data set.

Newer versions of IMUPS give consumption data on every BOARD-COMPLETE-Event.

Format of Consumption Report:

IM:
C:{datetime};{componentID};{feeder slot};{nr. picked};{nr. placed};{nr. mispicked};
{Boards since last Product Load}{cr}{lf}
SM:
C:{datetime};{componentID};{feeder slot},{track};{nr. picked};{nr. placed};{nr. mispicked}{cr}{lf}

Sample:

C:12.01.2011 11:15:03;1522795;8;55;55;0{cr}{lf}

As a precondition, the machines must be networkable on basis TCP/IP.

The IP-Address of the Windows PC as well as the two TCP-Port-Numbers
for the STREAM-SOCKET communication are to be set in the EVENTLINK configuration. All used TCP-Ports must be made available for use in the PC firewall.

EVENTLINK is designed being a STREAM client and server at the same time.
The server part is the command receiver, the client part sends data out as event messages, consumption data, ..

In order to communicate with EVENTLINK, a STREAM SOCKET Client/Server pair is needed.

Sample for a Stream Socket Client (Sender):

#include < stdio.h >
#include < stdlib.h >
#include < unistd.h >
#include < string.h >
#include < sys/types.h >
#include < sys/socket.h >
#include < netinet/in.h >
#include < netdb.h >

void error(const char *msg)
{
   perror(msg);
   exit(0);
}

int main(int argc, char *argv[])
{
   int sockfd, portno, n;
   struct sockaddr_in serv_addr;
   struct hostent *server;

   char buffer[256];
   if (argc < 3) {
      fprintf(stderr,"usage %s hostname port\n", argv[0]);
      exit(0);
   }
   portno = atoi(argv[2]);
   sockfd = socket(AF_INET, SOCK_STREAM, 0);
   if (sockfd < 0)
       error("ERROR opening socket");
   server = gethostbyname(argv[1]);
   if (server == NULL) {
       fprintf(stderr,"ERROR, no such host\n");
       exit(0);
   }
   bzero((char *) &serv_addr, sizeof(serv_addr));
   serv_addr.sin_family = AF_INET;
      (char *)&serv_addr.sin_addr.s_addr,
        server->h_length);
   serv_addr.sin_port = htons(portno);
   if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
       error("ERROR connecting");
   /* This message is sent out */
   /* ------------------------ */
   printf("Please enter the message: ");
   bzero(buffer,256);
   fgets(buffer,255,stdin);
   n = write(sockfd,buffer,strlen(buffer));
   if (n < 0)
        error("ERROR writing to socket");
   close(sockfd);
   return 0;
}

Sample for a Stream Socket Server (Receiver):

/* A simple server in the internet domain using TCP
  The port number is passed as an argument */
#include < stdio.h >
#include < stdlib.h >
#include < string.h >
#include < unistd.h >
#include < sys/types.h >
#include < sys/socket.h >
#include < netinet/in.h >

void error(const char *msg)
{
   perror(msg);
   exit(1);
}

int main(int argc, char *argv[])
{
    int sockfd, newsockfd, portno;
    socklen_t clilen;
    char buffer[256];
    struct sockaddr_in serv_addr, cli_addr;
    int n;
    if (argc < 2) {
        fprintf(stderr,"ERROR, no port provided\n");
        exit(1);
    }
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
       error("ERROR opening socket");
    bzero((char *) &serv_addr, sizeof(serv_addr));
    portno = atoi(argv[1]);
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);
    if (bind(sockfd, (struct sockaddr *) &serv_addr,
             sizeof(serv_addr)) < 0)
             error("ERROR on binding");
    listen(sockfd,5);
    clilen = sizeof(cli_addr);
    newsockfd = accept(sockfd,
                (struct sockaddr *) &cli_addr,
                &clilen);
    if (newsockfd < 0)
         error("ERROR on accept");
    bzero(buffer,256);
    n = read(newsockfd,buffer,255);
    if (n < 0) error("ERROR reading from socket");
    /* This message is received */
    /* ------------------------ */
    printf("Here is the message: %s\n",buffer);
        close(newsockfd);
    close(sockfd);
    return 0;
}
zurück
zurück
back
back