Hallo
Ich habe ein Problem mit dem Märklin CAN-Bus.
Ich habe als Ausgangspunkt das FreeBasic-Beispiel von DiegoGarcia verwendet, das ich ins VB.Net übersetzt habe.
Ich kann Stopp / Go senden und Geschwindigkeit von einer Lokomotive abfragen, aber wenn ich versuche, die Geschwindigkeit einzustellen, kann ich sehen, dass der CS2 nicht versteht, was ich meine.
Laut Märklin CAN CS2 Protokoll Ver. 2.0 Seite 30:
Geschwindigkeit muss als xx von 1000 angegeben werden.
In meinem Code ist:
DLC ist auf 6 eingestellt
Byte 2 gleich Protokoll MM2
Byte 3 gleich Lokomotiv-Adresse
Byte 4 (b4) und 5 (b5) gleich Geschwindigkeit
Testergebnisse
Dezimal 100: b4 = & H0 / b5 = & H64 OK
Dezimal 200: b4 = & H0 / b5 = & HC8 nicht OK
Dezimal 300: b4 = & H1 / b5 = & H2C OK
Dezimal 400: b4 = & H1 / b5 = & H90 nicht OK
Dezimal 500: b4 = & H1 / b5 = & HF4 nicht OK
Dezimal 600: b4 = & H2 / b5 = & H58 OK
Dezimal 700: b4 = & H2 / b5 = & HBC nicht OK
Dezimal 800: b4 = & H3 / b5 = & H20 OK
Dezimal 900: b4 = & H3 / b5 = & H84 nicht OK
Dezimal 1000: b4 = & H3 / b5 = & HE8 nicht OK
Ich habe versucht, die Geschwindigkeit als Hexadezimal und als Dezimal einzustellen. Gleiches Ergebnis.
Was muss ich tun, um die Geschwindigkeit richtig zu berechnen?
Danke im Voraus
Henrik
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
Private Sub Stummiforum(lokID As Byte, lokSpeed As Integer)
' - Packet size 13 Bytes
' - Bytes 1 bis 4 sind die Meldungskennung.
' - Byte 5 entspricht dem DLC der CAN-Meldung.
' - Bytes 6 - 13 sind die entsprechenden Nutzdaten. Dabei nicht benötigte Bytes sind mit 00 zu füllen.
Dim i As Integer ' als Laufvariable
Dim myDLC As Byte ' Anzahl der Datenbytes im CAN-Paket, 1 Byte (eigentlich nur ein Nibble)
Dim myPrio As Byte ' Priorität des befehls, 1 Nibble (4 Bits)
Dim myResponseBit As Byte ' wenn wir als PC-Programm senden, ist dieses Bit immer 0
Dim myStartWord As UShort ' die Kombination aus Prio, Command und Responsebit
Dim myUID As ULong ' Zieladresse des Objektes auf dem CAN, 32 Bits
Dim myHash As UShort ' unser Hash, 16 Bits
Dim myCommand As Byte ' unser Befehl, 8 Bits
Dim mySubCommand As Byte ' unser Unterbefehl, 8 Bits
Dim myDataBytes(7) As Byte ' array[0..7] Of Byte, immer genau 8 Bytes
Dim mySendingStr As String ' diese Zeichenkette werden wir über das UDP-Socket senden
Dim samletBytes As Byte()
Dim client As New UdpClient()
myPrio = 0 ' wir haben keine Priorität
'mySubCommand = 0 ' Stopp
myHash = &H4711 ' wie im Beispiel, kann aber auch &h0300 sein (als Minimum)
myUID = &H0 ' UID = 0 bedeutet: sende den Befehl an alle
For i = 0 To 7 ' Märklins Doku zählt auch von D0 .. D7
myDataBytes(i) = 0 ' init array
Next
myCommand = 8
myDLC = 6
myStartWord = ((myPrio << 12) + (myCommand) + (myResponseBit And 1) And &HFFFF)
myDataBytes(0) = ((myUID >> 24) And &HFF) ' Big Endian encoding
myDataBytes(1) = ((myUID >> 16) And &HFF)
myDataBytes(2) = ((myUID >> 8) And &HFF)
myDataBytes(3) = lokID
' bit nr. 2 = protocol (0 = MM2 / 40 = MFX / C0 = DCC
' bit nr. 3 = lok adresse
' bit nr. 4 og 5 = hastighed
' 00084711 6 00 00 08 03 03 20 Lok Geschwindigkeit SX1 Adr 3, V=0x0320=800 von 1024
' 00084711 6 00 00 08 03 00 A0 Lok Geschwindigkeit SX1 Adr 3, V=0x00A0=10 von 1024
' 00084711 6 00 00 40 01 03 20 Lok Geschwindigkeit mfx Adr 1, V=0x0320=800 von 1024
' 00084711 6 00 00 C0 03 01 20 Lok Geschwindigkeit DCC Adr 3
' 00084711 6 00 00 C0 03 00 A0 Lok Geschwindigkeit DCC Adr
Dim hexStr As String = lokSpeed.ToString("X4")
Dim b4 = "&H" & hexStr.Substring(0, 2)
Dim b5 = "&H" & hexStr.Substring(hexStr.Length - 2)
'Dim b4 As Integer = CInt("&H" & hexStr.Substring(0, 2))
'Dim b5 As Integer = CInt("&H" & hexStr.Substring(hexStr.Length - 2))
myDataBytes(4) = b4
myDataBytes(5) = b5
mySendingStr = Chr(myStartWord >> 8) + Chr(myStartWord And &HFF)
mySendingStr = mySendingStr + Chr((myHash >> 8) And &HFF) + Chr(myHash And &HFF) 'And &HFF) ' + Chr(myHash And &HFF)
mySendingStr = mySendingStr + Chr(myDLC And &HFF)
For i = 0 To 7
mySendingStr = mySendingStr + Chr(myDataBytes(i) And &HFF) ' wir gehen mit "AND &hFF" auf Nummer sicher...
Next
samletBytes = Encoding.ASCII.GetBytes(mySendingStr)
Dim toSend(12) As Byte
Array.Copy(samletBytes, 0, toSend, 0, 12)
client.Connect("192.168.1.250", 15731)
client.Send(toSend, toSend.Length)
client.Close()
End Sub