Hallo Forum, ich tüftle schon seit Stunden an der Ansteuerung eines Modbus Devices von Vögtlin Instruments ... grrr Also, ich habe auf dem Bus mal gelauscht und folgende Sequenz herausgefiltert, die auch, wenn ich die direkt aus VB6 sende einwandfrei funktioniert: 01;10;00;06;00;02;04;3E;99;99;9A;44;79 01 Slave 10 Kommando 00 Startadr. Hi 06 Startadr. low 00 Anzahl Register Highbyte 02 Anzahl Register Lowbyte 04 Anzahl der zu sendenden Bytes (2x 16-Bit) 3E; 99; 99; 9A 4 Bytes einer Single Variablen, = 0,3 44 ; 79 Checksumme ... CRC16 Und in den letzten Beiden liegt der Hund begraben. Die werden in umgekehrter Reihenfolge geschickt, soviel hab ich in der Doku gefunden, aber die Generierung klemmt einfach. Bis zu diesem Code bin ich schon gekommen: Public Function CRC16(ar() As Byte, lbuf As Byte) As Integer Dim CRC1 As Long Dim b As Boolean Dim i As Long, j As Byte, Odd As Boolean CRC16 = -1 For i = 0 To lbuf CRC16 = (CRC16 And &HFF00) Or ((CRC16 And 255) Xor ar(i)) For j = 1 To 8 Odd = CRC16 And 1 CRC16 = ((CRC16 And &HFFFE) \ 2) And &H7FFF 'shift right If Odd Then CRC16 = &HA001 Xor CRC16 Next 'Debug.Print CStr(i) + " " + Hex(ar(i)) + " " + Hex(CRC16) Next End Function Aber der Rückgabewert passt nicht: 9F26 ... oder halt Protokollkonform 26; 9F Hat von Euch schon jemand Erfahrungen mit den Reglern und / oder hat nen Tip für mich?
AAAAAAAARRRGH ... nach dem Absenden den Fehler gesehen ... --> For i = 0 To lbuf Da isster Mein Array fängt bei 1 an ....grrrrrrr Dieser Code funktioniert ... falls den mal noch jemand brauchen sollte: Public Function CRC16(ar() As Byte, lbuf As Byte) As Integer Dim CRC1 As Long Dim b As Boolean Dim i As Long, j As Byte, Odd As Boolean CRC16 = -1 For i = 1 To lbuf CRC16 = (CRC16 And &HFF00) Or ((CRC16 And 255) Xor ar(i)) For j = 1 To 8 Odd = CRC16 And 1 CRC16 = ((CRC16 And &HFFFE) \ 2) And &H7FFF 'shift right If Odd Then CRC16 = &HA001 Xor CRC16 Next 'Debug.Print CStr(i) + " " + Hex(ar(i)) + " " + Hex(CRC16) Next End Function
ich habe die Routine mal in C übersetzt (nicht optimiert)
1 | unsigned int crc_16 (unsigned char buffer[],int bufferlen) |
2 | { |
3 | unsigned int CRC=0xffff ; |
4 | unsigned char i,j; |
5 | bit odd; |
6 | for (i=1;bufferlen;i++) // for i= 1 to bufferlen |
7 | { |
8 | CRC=(CRC & 0xFF00)|((CRC & 0xFF)^buffer[i]); // CRC = (CRC And &HFF00) Or ((CRC And 255) Xor bufferlen (i)) |
9 | for (j=1;8;j++) // For j = 1 To 8 |
10 | { |
11 | odd = CRC & 1; // Odd = CRC And 1 |
12 | CRC = ((CRC & 0xFFFE) / 2) & 0x7FFF ; // CRC = ((CRC And &HFFFE) \ 2) And &H7FFF 'shift right |
13 | if (odd) // If Odd |
14 | { // Then |
15 | CRC = 0xA001 ^ CRC; // CRC = &HA001 Xor CRC |
16 | }; // Endif |
17 | } // Next j |
18 | } //Next i |
19 | return CRC; |
20 | } |
Hi Ich habe gesehen, dass der Eintrag zwar schon einige Monate her ist, aber kannst du mir vielleicht beim Code helfen? Ich versuche seit Juli schon einen einfachen Motor anzusteuern (also gernauer gesagt den Frequenzumrichter). Allerdings scheitere ich kläglich. Ich meinte, mittlerweile den Syntax draussen zu haben. Aber über die Schnittstelle läuft nichts. Oder falls da doch was läuft, ist es nur Mist. Wenn ich die Bauteile für das Telegramm (Adresse, Befehl, Register, Werte) zusammenstelle und versuche den CRC16-Wert zu errechnen, erhalte ich, glaube ich zumindest, einen Wert. Aber dann kann ich die Kette nicht verknüpfen und erhalte dementsprechend keine Antwort. Jetzt weiss ich nicht, ob ich die Kette korrekt erstellt habe, die Zeichen richtig an die Schnittstelle übergeben werden und wie ich das ganze verkette. Einige Schwierigkeiten, bei denen ich für Rat sehr dankbar wäre. Ich hoffe, du kannst und möchtest mir helfen. Danke Chris
Hast Du evtl. nen Link zu der Bedienungsanleitung von dem Teil?? Schau mal ob es zu dem FU evtl. vom Hersteller ne Software gibt, dann kannst Du mal auf dem Bus mitloggen was da hin und her geht, das kann schonmal zum Eingrenzen ob die Kommunikation prinzipiell läuft oder schon in der Schnittstelle der Wurm drinnen ist, gut sein.
Hi Ich habe einen Link gefunden. http://www.spoerk.at/wp-content/uploads/2011/05/V1000_QSG_DE_TOGP_C710606_15C_3_0.pdf Dummerweise musste ich das Teil gestern zurückgeben. Ich kann nur noch theoretisch daran arbeiten. Muss erst wieder etwas Geld aufbringen, um das Teil noch einmal mieten zu können oder eines zu kaufen. Aber das will ich erst, wenn ich weiss, dass das Telegramm auch funktionieren würde. Chris
Hi, wozu dient eigentlich die Zeile CRC=(CRC & 0xFF00)|((CRC & 0xFF)^buffer[i]); Es werden doch ohnehin nur die "unteren" 8 bit verarbeitet?! In einem anderen Beispiel (http://www.camillebauer.com/src/download/Modbus_Grundlagen.pdf, Seite 3) fand ich stattdessen crc = ((crc^data) | 0xFF00) & (crc | 0x00FF); dessen Sinn sich mir auch nicht richtig erschließt. Gerade aus (crc | 0x00ff) ergibt sich doch für die hier relevanten Bits immer 0xFF? Warum also reicht nicht (crc^data)?
Jeff schrieb: > Gerade aus (crc | 0x00ff) ergibt sich doch für die hier relevanten > Bits immer 0xFF? Das siehst Du falsch. Die relevanten Bits stecken bei den | Verknüpfungen hinter den 00 und der Rest muss auf FF stehen damit bei der nachfolgenden & Verknüpfung die Daten nicht auf Null gebügelt werden.
:
Bearbeitet durch User
Hmmm, okay. So gesehen hast Du recht, auch wenn ich den zitierten Satz anders gemeint, doch leider missverständlich formuliert habe. Der Kern aber bleibt: Warum ist (crc^data) (bzw. (crc^buffer[i])) nicht ausreichend? In welchen Fällen also müssen die beiden Bytes im Int16 explizit separat behandelt werden?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.