RK512 Protokoll (Siemens)



  • Suche Routinen (Quellcode) für das Siemens Protokoll RK512.
    Wenn möglich Freeware.

    Gruß Rainer



  • Die Rechnerkopplung RK512 basiert auf dem DUST-Protokoll. Googel mal hierunter.
    Da müßte was zu finden sein.
    Soweit ich mich erinnere kommt am Anfang ein Heaser in dem der Datenbaustein, Datenwort, Länge der zu sendenden Daten und "AD" (wenn Du an die SPS sendest) steht. Ich meine, der ist irgendwie 10 Byte lang.

    Das besondere am Dust-Protokoll ist, dass es mit DLE endet aber im Datensatz auch DLEs vorkommen dürfen. Diese werden dann gedoppelt.

    Je nachdem ob du mit Checksumme oder ohne hast, nennt sich die Dust dann DUST3964R oder ohne R wenn keine Checksumme. Ohne Checksumme habe ich aber noch nie erlebt.



  • Hi,

    ich beschäftige mich zur Zeit auch damit. In den letzten Tagen ist auch ein Thread mit ähnlichem Inhalt aufggetaucht. Dort ging es um USB uns SPS, was ja auch interessant ist.

    Das Gebiet ist bei mir auch (fast) Neuland und möchte mich damit auch ein wenig mehr beschäftigen. Ich habe zwar Unterstütung von meinem Bruder (Elektromeister -> arbeitet mit WinCC, DasyLap (kotz) und kennt sich gut in der Siemens- und Elektrowelt aus), aber leider wenig Zeit, weshalb ich nur schleppend vorankomme.

    mit RK512 hab ich mich noch nicht beschäftigt. Du kannst aber, falls du es nicht sowie weisst, über OPC eine OCX- Verbindung aufbauen, was vielleicht etwas einfacher zu handhaben ist. Wahrscheinlich findet man im Internet auch Beispiele, wie man über isanet oder mpi (ich glaub 485) auf ne SPS rumtrampelt.

    Vielleicht konnen wir uns da noch austauschen und eventuell gemeinsam was erforschen. Das Protokoll RK512 interessiert mich auch 😉

    Bei Interesse an Zusammenarbeit schick mir doch bitte eine Mail.



  • @unreg:
    hast du schon mal sowas gemacht über RK512 ?

    Hast du eventell noch ein Beispiel irgend wo rumliegen ?


  • Mod

    Hallo

    mit RK habe ich vor einigen Jahren (>15) bei Siemens mal was gemacht
    (UNIX). Ich schau mal ob ich da noch was finde

    MfG
    Klaus



  • 👍

    danke !



  • So bin jetzt eingeloggt und nicht mehr unreg.

    Ich habe mir das Dust-Protokoll mal in C++ für den Builder geschrieben.
    Falls KlausB nichts findet, meldet Euch einfach nochmal. Dann muss ich bei mir mal suchen.

    Habe nochmals nachgesehen. Was in den Header gehört habe ich auch gefunden.
    Allerdings habe ich das nicht in C sondern in Forth, so daß ich es hier nur kurz erklären kann.

    Der Header besteht aus 10 Byte und wird vor den eigenltichen Nutzdaten geschickt.

    1. Byte: binär 0
    2. Byte: binär 0
    3. Byte: Ascii 'A' // hex 41 "Ausgabe Daten"
    4. Byte: Ascii 'D' // hex 44
    5. Byte: Zieldatenbaustein-Adresse
    6. Byte: Datenwort-Adresse
    7. Byte: Länge HB
    8. Byte: Länge LB
    9. Byte: binär 255 // hex FF
    10. Byte: binär 255 // hex FF

    Im 3. Byte stehe, wenn ich mich richtig erinnere, ein 'E' wenn die SPS sendet.
    Heisst dann wohl "Eingabe Daten"

    Byte 5 und 6 müssen mit dem SPS-Programmierer vorher abgesprochen werden.

    Byte 7 und 8 sind die Länge der einzelnen Nutzdaten. Wichtig: ohne das/die gedoppelte(n) DLE(s)

    Bei der Dust3964R wird die Checksumme als Exclusiv-Oder über alle (einschliesslich gedoppeltes DLE) gebildet.

    Als Startzeichen ist STX und Endezeichen ETX.
    Der Sendet sendet erst ein STX. Dann muss der Epfänger seine Bereitschaft mit einem DLE anzeigen. Erst danach kommen alle Daten bis ETX und Checksumme.
    Weenn der Empfänger alles richtig verstanden hat sendet er ein DLE, sonst ein NAK.
    Wobei mit "richtig verstanden" nur Checksumme und Protokoll gemeint ist. Der Datensatzinhalt, wie z.B. falsche Artikelnummer, ist hiermit nicht gemeint.

    Hoffe, dass es einigermassen verständlich erklärt ist.



  • Danke an alle,

    ich wollte aber noch anmerken das RK512 nicht das geleiche ist wie 3964R.

    @aheim: Wenn du noch etwas Quellcode hättest wäre es klasse.

    gruß rainer



  • RaKo schrieb:

    Danke an alle,

    ich wollte aber noch anmerken das RK512 nicht das geleiche ist wie 3964R.

    Das stimmt schon. Aber RK512 ist der Header. Dies sind ein paar Byte die vor den Nutzdaten geschickt werden. Aber alles im Dust3964-Protokoll.
    Daher bin ich der Meinung, daß RK512 nicht ohne Dust genannt werden kann.

    Nach Quellcode kann ich suchen. Dies wäre aber dann nur das Dust-Protokoll in C++.
    Zu RK 512 habe ich nur was in Forth. Denke nicht, daß Dir das weiterhilft.

    Wenn Du was zur Dust haben willst, dann melde Dich nochmal. Werde dann danach suchen.



  • supi 🙂



  • ich habe mir mal eine Klasse zur Datenübertragung über die serielle geschrieben.
    Die Teile, die für die Dust benötigt werden habe ich rauskopiert.
    Da ich die sowohl unterm gnu als auch BCB laufen haben wollte ist string und nicht AnsiString genommen worden.
    Falls Fragen sind meldet Euch einfach nochmal. Habe im Moment keine Zeit.

    case cpcDust3964R:        // Hier wird Start und Endezeichen 
                                  // und Art der Cheksummenberechnung festgelegt
        {
          cStartChar    = STX;
          cEndChar      = ETX;
          fCheckSum     = ccsXOR;
          bWithStartChar= false;
          bWithEndChar  = true;
          bWithAnswer   = true;
        }
    
    void  TCustomCommHandler::SendData(string& Str)
    {
      ClearReceiveBuffer();
      switch (fProtocol)
      {
        case cpcDust3964R : SendDust3964R(Str); break;
        default:       SendStxEtx(Str);
      }
    }                                                   
    
    string  TCustomCommHandler::ReceiveData()
    {
      string ReceiveData_result;
      switch (fProtocol)
      {
        case cpcDust3964R : ReceiveData_result = ReceiveDust3964R(); break;
        default:            ReceiveData_result = ReceiveStxEtx();
      }
      return ReceiveData_result;
    }
    
    string  TCustomCommHandler::ReceiveDust3964R()
    {
      string sCheckSumStr;
      int iRetryCnt,
      i,
      iSum;
      bool bDLEReceived,
      bSTXReceived;
      char cCheckSumRec;
      char cChr;
      string tmpString;
    
      string ReceiveDust3964R_result;
      iRetryCnt = 0;
      do {
        bSTXReceived = false;
        cChr = WaitForChar((char&)STX);
        if (iLastError == CE_OK)
          {
            bSTXReceived = true;
            SendChar((char&)DLE);
            bDLEReceived = false;
            ReceiveDust3964R_result  = "";
            sCheckSumStr = "";
            while ((iLastError==CE_OK) && !(bDLEReceived && (cChr==ETX)))
              {
                cChr = GetChar();
                if (iLastError == CE_OK)
                  {
                    sCheckSumStr = sCheckSumStr+cChr;
                    if (bDLEReceived)
                      {
                        if (cChr == DLE)
                          {
                            ReceiveDust3964R_result = ReceiveDust3964R_result+DLE;
                            bDLEReceived = false;
                          }
                      }
                    else
                      if (cChr==DLE)
                        bDLEReceived = true;
                      else
                        ReceiveDust3964R_result = ReceiveDust3964R_result+cChr;
                  }
              }
          }
    
        if (iLastError==CE_OK)
          {
            iSum = 0;
            for( i=0; i < (int) sCheckSumStr.length(); i ++)
              iSum = iSum ^ (int)sCheckSumStr[i];
            cCheckSumRec=WaitForChar((char&)NUL);
            if ((iLastError == CE_OK) && (iSum!=(int)cCheckSumRec))
              iLastError = CE_NAKTRANSMIT;
          }
        if (iLastError==CE_OK)
        {
            SendChar((char&)DLE);
        }
        else
          if (bSTXReceived)  SendChar((char&)NAK);
    
        if (iLastError!=CE_OK)
        {
          tmpString = "COMM-Error : ";
          #ifndef __BORLANDC__
            tmpString += IntToStr(iLastError);
          #else
            tmpString += IntToStr(iLastError).c_str();
          #endif
          WriteLog(tmpString,ltWrite);
    		}
        else
          WriteLog(ReceiveDust3964R_result,ltRead);
    
        iRetryCnt += 1;
      } while (!((iRetryCnt>iRetries) ||
            ((iLastError==CE_TIMEOUT) && ! bSTXReceived) ||
            (iLastError==CE_OK)));
      return ReceiveDust3964R_result;
    }
    
    void  TCustomCommHandler::SendDust3964R(string& Str )
    {
    	string sSendData;
      string sDupData;
      bool bWriteOK;
      char cChr;
      int i,iSum;
      string tmpString;
      DWORD dWrCount,
      iRetryCnt;
    
      sSendData ="";
      if (Str.length() >0)
        for( i=0; i < (int) Str.length(); i ++)
          if (Str[i]==DLE)
            sSendData = sSendData+DLE+DLE;
          else
            sSendData =sSendData+Str[i];
    
      sSendData=sSendData+DLE+ETX;
      iSum = 0;
      for( i=0; i < (int) sSendData.length(); i ++) iSum = iSum ^ (int)sSendData[i];
        sSendData = sSendData + char(iSum);
    
      iRetryCnt=0;
      do {
        SendChar(STX);
        cChr = WaitForChar(DLE);
        if ((iLastError==CE_OK) && (cChr==DLE))
        {
          if (cDupChar==NUL)
            bWriteOK=WriteFile(iCommId,sSendData.c_str(),sSendData.length(),&dWrCount,NULL);
          else
          {
            sDupData = "";
            for( i = 0; i < (int) sSendData.length(); i ++)
              if (sSendData[i] == cDupChar)
                sDupData = sDupData+cDupChar+cDupChar;
              else
                sDupData = sDupData+sSendData[i];
            bWriteOK=WriteFile(iCommId,sDupData.c_str(),sDupData.length(),&dWrCount,NULL);
          }
          if (bWriteOK)  iLastError = CE_OK; else iLastError = GetCommError();
          if ((iLastError == CE_OK) && bWithAnswer)
          {
        	tmpString  = DLE;
            tmpString += NAK;
            cChr = WaitForMultiChar(tmpString);
            if ((iLastError == CE_OK) && (cChr!=DLE))
            	iLastError = CE_NAKRECEIVED;
          }
        }
    
        if (iLastError!=CE_OK)
        {
          tmpString = "COMM-Error : ";
          #ifndef __BORLANDC__
            tmpString += IntToStr(iLastError);
          #else
            tmpString += IntToStr(iLastError).c_str();
          #endif
          WriteLog(tmpString,ltWrite);
        }
        else
          WriteLog(sSendData,ltWrite);
    
        iRetryCnt += 1;
      } while (!(((int)iRetryCnt> iRetries) || (iLastError==CE_OK)));
    }
    


  • Super!!!!

    Vielen Dank, werde ich sofort ausprobieren wenn ich wieder arbeiten bin.

    Gruß Rainer



  • Informationen über die Protokolle RK512 und 3964 können übrigens bei Siemens kostenlos 'runtergeladen werden. Unter www.ad.siemens.de finden sich alle möglichen Handbücher. Die Protokolle müßten z.B. beim CP524 beschrieben sein. BTW: Das Protokoll AS511 ist von Siemens nicht offen gelegt worden. Hat jemand dazu irgendwelche Dokumentationen?

    Rob'


Anmelden zum Antworten