SPS S7 400 Informationen mithilfe von Java auslesen

Beiträge
3
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leute!

Bin mir nicht sicher, ob ich mit meiner Problemstellung hier richtig bin, möchte mein Problem aber trozdem mal in den Raum werfen. :rolleyes:

Ich muss im Rahmen eines Projekts (über Uni vermittelt) aus einer SPS S7 400 Daten auslesen. Dies soll mithilfe von Java durchgeführt werden.
Da es noch einige Zeit dauern wird, bis wir eine SPS zum testen bekommen, möchte ich zunächst fragen, ob es durch diverse Programme möglich ist, eine SPS zu simulieren (also so, dass mein Rechner denkt, es hängt eine SPS S7 400 dran). Wäre gut wenn es so etwas als freeware gäbe (was ich aber stark bezweifle)
Leider kenn ich mich im Gebiet der SPS noch nicht so wirklich gut aus, da ich in diesem Bereich noch keine Erfahrungen gesammelt habe.
Das Programm, dass über Java zu programmieren ist, soll zunächst Daten der SPS auslesen. Dies sollen Informationen über die Ein- und Ausgänge und der Bausteine sein. Wie genau dieses Problem gelöst wird, bleibt mir und meinem Uni-Kollegen überlassen. (Wissen nicht so ganz wo wir anfangen sollen)
Wäre wirklich sehr dankbar, wenn mir irgendjemand einen Tipp gäben könnte, wie wir diese Aufgabenstellung angehen könnten. Bzw. wär auch super wenn mir jemand sagen könnte, wo ich mich dafür überall einlesen muss.

:roll:
 
@Chefmech
Er will ja zunächst eine SPS simulieren, bevor er seine echte zum Testen bekommt.
Kann libnodave auch aus der Simu lesen ?
 
Fetch-Write Lösung in C

Tja, vielleicht hab ich da einen Tip für Euch, wie schon angesprochen, libnodave ist ja rein C/C++.

Aber vielleicht hilft euch dieser Weg.
In der SPS benutzt ihr einen Cp, ComProzessor für TCP/IP oder primitiver für eine Serielle Punkt-zu-Punkt Kopplung.

Für Seriell, Protokoll aus der doku beschaffen und los hacken ...

Für Tcp/IP Protokoll kann man RFC1006 über TCP/IP nehmen.

1. In der Netzzkonfig im S7 MAnager 2 Verbindungen anlegen.
2. auf der CP Adresse Port 2000, fetch passiver Verbindungsaufbau
3. auf der CP Adresse Port 2001, write passiver Verbindungsaufbau
4. Am Besten man sucht im S7-Programm seine Daten zusammen und stopft die auf ein Koppeldatenbaustein-Paar. Ein DB welcher extern gelesen wird (Status) und einer welcher extern geschrieben wird. Man kann auch Eingangs, Merker, ausgangs Daten damit abfragen, jedoch ist das im Demo / Test Programm nicht berücksichtigt.

5. Euer Java Programm so schreiben das Ihr mit TCP/IP mein kleines C Programm umsetzt und adaptiert. Der Demo code arbeitet unter Linux einwandfrei mit einer CP343-1 der Ersten Generation ...

Ich hab im Mom. noch nicht ausprobiert, ob das auch mit neuen CPU der "PN" Generation mit Verbindungen via "OpenConnect" noch funktioniert.
Mit einem CP343-1 oder CP443-1 aus der S7-400 serie sollte das so funktionieren.

Euer Schatten

Das C-Programm:
cp343.h Test:
Code:
#ifndef h_cp343
#define h_cp343

typedef struct
{
char sysid[2];                          // 0,1 "S5"
unsigned char headerlgt;                // 2
unsigned char idopcode;                 // 3
unsigned char idopcodelgt;              // 4
unsigned char opcode;                   // 5
unsigned char orgblock;                 // 6
unsigned char orglgt;                   // 7
unsigned char idorg;                    // 8
unsigned char dbnr;                     // 9
unsigned char start_msb;                // 0x0A - 10
unsigned char start_lsb;                // 0x0B - 11
unsigned char lgt_msb;                  // 0x0C - 12
unsigned char lgt_lsb;                  // 0x0D - 13
unsigned char empty;                    // 0x0E - 14
unsigned char empty_lgt;                // 0x0F - 15
} cp343header;

#define MAXBUF 1024*65
#endif

cp343.c Test:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include "cp343.h"

void hilfe(void);
void splash(void);
int  cp343_connect(char *host, int port, int v);
void cp343_release(int socket);
void cp343_standard(cp343header *d);
int  cp343_fetch(int s, cp343header *h, void *data, int v);
int  cp343_write(int s, cp343header *h, void *data, int v);
void cp343_dump(void *data, int n);
void cp343_dumpword(void *d, int n);
 
int main(int argc, char **argv)
{
  int fs, ws, v=1, fe=0, wr=0;
  static char *ziel=0;
  int wport=2000;
  int fport=2001;
  unsigned char fdb, wdb;
  char c;
  int  bytes=0, i;
  cp343header send;
  cp343header rec;
  void *data;
  unsigned char *l;
  unsigned char *h;

  data      = calloc(1, MAXBUF);
  ziel=calloc(1,1024);
  strcpy(ziel,"cp343");

  fdb=41; /* Standardmässig DB41 abfragen für Fetch */
  wdb=50; /* Standardmässig DB41 abfragen für Write */

  // Komandozeile Auswerten
  while((c=getopt(argc, argv, "hfwd:p:vF:W:"))>0) 
    { 
      switch(c)
    {
    case 'h': hilfe(); exit(0);     break;
    case 'd': strcpy(ziel, optarg); break;
    case 'p': fport=atoi(optarg);   break;      
    case 'v': v++;                  break;
    case 'f': fe++;                 break;
    case 'w': wr++;                 break;
    case 'F': fdb=atoi(optarg);     break;
    case 'W': wdb=atoi(optarg);     break;      
    default:  hilfe(); exit(0);     break;
    }
    }
      splash();
      printf("Vedrbinde mit: %s, Port: %d \n", ziel, fport);
  fs=cp343_connect(ziel, fport, v);
  if(!fs) 
    {
      printf("Fehler: Keine Verbindung zu %s:%d\n", ziel, fport);
      return(1);
    }
  printf ("Verbunden mit %s:%d\n", ziel, fport);

  printf("Verbinde mit: %s, Port: %d \n", ziel, wport);
  ws=cp343_connect(ziel, wport, v);
  if(!ws) 
    {
      printf("Fehler: Keine Verbindung zu %s:%d\n", ziel, wport);
      return(1);
    }
  printf ("Verbunden mit %s:%d\n", ziel, wport);
  // Bereite Empfangsdaten für FETCH vor
  cp343_standard(&rec);
  rec.opcode=5;
  rec.orgblock=3;
  rec.orglgt=8;
  rec.idorg=0x01;
  rec.dbnr=fdb;
  rec.start_msb=0;
  rec.start_lsb=0;
  rec.lgt_msb=0;
  rec.lgt_lsb=10;
  rec.empty=0xff;
  rec.empty_lgt=2;
  if(fe) cp343_fetch(fs, &rec, data, v);

  // Bereite Sendedaten für WRITE vor
  memset(data, 0, MAXBUF);
  cp343_standard(&send);
  send.opcode=3;
  send.orgblock=3;
  send.orglgt=8;
  send.idorg=0x01;
  send.dbnr=wdb;
  send.start_msb=0;
  send.start_lsb=0;
  send.lgt_msb=0;
  send.lgt_lsb=10;
  send.empty=0xff;
  send.empty_lgt=2;
  bytes=(256*send.lgt_msb + send.lgt_lsb)*2;

  // Daten erzeugen
  for(i=0; i<bytes; i=i+2)
    {
      l=data+i+1; h=data+i; *l=i/2;
    }

  if(wr) cp343_write(ws, &send, data, v);

  cp343_release(fs);
  if(v) printf ("Verbindung mit %s : %d getrennt\n", ziel, fport);
  cp343_release(ws);
  if(v) printf ("Verbindung mit %s : %d getrennt\n", ziel, wport);
  return(0);
}

int cp343_connect(char *cp, int port, int v)
{
  struct protoent     *protocol;
  struct hostent      *he;
  struct sockaddr_in  s7cp;
  int                 s;
  protocol = getprotobyname("TCP");
  if (!protocol)
    {
      printf("TCP Protokoll nicht verwendbar\n");
      return (0);
    }
  // Ereugen eines Sockets
  s = socket(AF_INET, SOCK_STREAM, protocol->p_proto);
  if(!s) 
    {
      printf("Fehler: Socket nicht anlegbar\n");
      return(0);
    }
  // Umrechnen des gegebenen Hostnamens via gethostbyname()
  if ((he = gethostbyname(cp)) == NULL)
    {
      printf("Fehler: Host nicht bestimmbar\n");      
      return(0);
    }
  // umkopieren der Adressdaten in die Socket Strukturen
  memcpy(&s7cp.sin_addr, he->h_addr_list[0], he->h_length);
  s7cp.sin_family = AF_INET;
  s7cp.sin_port = htons(port);
  // Connect ausführen zum Zielsystem
  if (connect(s, (struct sockaddr *)&s7cp, sizeof(s7cp)))
    {
      printf("Fehler: Connect \n");
      return(0);
    }
  return(s);
}

void cp343_release(int socket)
{
  close(socket);
}

/** Funktion: cp343_standard(cp343header *d)
 *  Einen cp343 Header mit Standard daten vorbelegen
 */
void cp343_standard(cp343header *d)
{
  memset(d, 0, sizeof(cp343header));
  d->sysid[0]='S';
  d->sysid[1]='5';
  d->headerlgt=16;
  d->idopcode=1;
  d->idopcodelgt=3;
  d->empty=0xff;
  d->empty_lgt=2;
}

int cp343_fetch(int s, cp343header *h, void *data, int v)
{
  int c=0;
  int b=0;
  void *bd=0;
  // Anfragetelegramm für FETCH schreiben
  b=sizeof(cp343header);
  memcpy(data, h, b);
  bd=data+b;
  c=write(s, data, b);
  printf("%d Fetch: Bytes geschrieben\n",c);
  if(v>1) cp343_dump(data, 0);


  // Status Antwort abholen
  printf("Versuche Antwortblock 16 Bytes zu lesen\n");
  //sync();
  memset(data, 0, sizeof(cp343header));
  c=read(s, data, 16);
  printf("%d Status Bytes gelesen\n",c);
  if(v>1) cp343_dump(data, 0);
      
  b=(256*h->lgt_msb + h->lgt_lsb)*2;
   memset(data, 0, MAXBUF);
  h=data;
  if((h->idorg) == 0 && v>1)
    {
      c=read(s, data, b);
      if(v>1) cp343_dumpword(data, b/2);
      printf("%c",c);
    }
  return(c);
}


int cp343_write(int s, cp343header *h, void *data, int v)
{
  int c=0;
  int b=0;
  void *bd=0;
  static void *buffer=0;
  if(!buffer) buffer=calloc(1, MAXBUF);
  
  // Anfragetelegramm für FETCH schreiben
  b=sizeof(cp343header);
  memcpy(buffer, h, b);
  bd=buffer+b;
  
  memcpy(bd, data, b);


  b+=sizeof(cp343header);
  c=write(s, buffer, b);
  if (v) printf("%d Write: Bytes geschrieben\n",c);
  if(v>1) 
      cp343_dump(data, 0);
  if(v>1) 
      cp343_dumpword(bd,(256*h->lgt_msb + h->lgt_lsb));


  // Status Antwort abholen
  if(v) printf("Versuche Antwortblock %u zu lesen\n", (unsigned char) sizeof(cp343header));
  memset(buffer, 0, MAXBUF);
  sync();
  c=read(s, buffer, sizeof(cp343header));
  h=buffer;
  if(v) printf("%d Status Bytes gelesen, Status: %c %c\n",c, h->idorg, h->dbnr);
  if(v>1) cp343_dump(buffer, 0);
  return(h->idorg);
}


void cp343_dump(void *d, int n)
{
  int i;
  unsigned char *c;
  if(!n)
    {
      printf("Ausgabe des Header\n");
      n=16;
    }
  else
    printf ("Ausgabe der Daten\n");
  
  for(i=0; i<n; i++)
    {
      c=d+i;
      if(*c >32) 
    printf("%02d 0x%02x: %03d 0x%02x %c\n",i, i, *c, *c, *c);
      else
    printf("%02d 0x%02x: %03d 0x%02x\n",i, i, *c, *c);
    }
}


/** Funktion: Daten Dumpen Bytes
 *
 */


void cp343_dumpword(void *d, int n)
{
  int i;
  unsigned char *h;
  unsigned char *l;
  printf ("Ausgabe der Daten\n");
  
  for(i=0; i<n*2; i=i+2)
    {
      h=d+i;
      l=d+i+1;
      printf("Word %02d 0x%02x:  0x%02x%02x\n", i/2, i/2, *h, *l);
    }
}


void splash()
{
  printf("==============================================\n");
  printf("  -_-_ Jojo's kleines cp343 Testprogramm _-_- \n");
  printf("  -_-_ (c) 2003 automatiX GmbH           _-_- \n");
  printf("  -_-_ http://www.automatix.de           _-_- \n");
  printf("==============================================\n");
}


/**
 *
 *
 */
void hilfe(void)
{
  splash();
  printf ("Hilfe:\n");
  printf ("Dies kleine Testprogramm versucht eine Verbindung zu einem\n");
  printf ("Siemens(tm) S7 CP343-1 Kommunikationsprozessor aufzubauen.\n");
  printf ("\n");
  printf ("Gebrauch:\n");
  printf ("cp343 [Optionen]\n");
  printf ("\n");
  printf ("Optionen sind\n");
  printf ("-v Anzeige von Rückmeldungen, mehrfach auffrufen, um detailiertere\n");
  printf ("   Meldungen zu erhalten\n");
  printf ("-p Protokoll, Standard ist TCP/IP\n");
  printf ("-d Zielrechner als FQDN, Name, keine 4-fache Dezimale\n");
  printf ("-f Löse eine FETCH Operation aus\n");
  printf ("-w Löse eine WRITE Operation aus\n");
  printf ("\n");  
}
 
Zurück
Oben