RE: Software schreiben zum steuern von Loks?

#101 von ALWIM , 28.05.2015 19:36

Zitat
Was erwartest Du von einer Bibliothek?

Auf die Frage von KLVM und der Antwort habe ich mir im ersten Moment gedacht, es gibt Bibliotheken, die die Bitverschiebung übernehmen. Man gibt an, welche Funktion man haben will und die Bibliothek verschiebt dann die Bits entsprechend der Doku von Märklin. Diese hätte ich notfalls auf Basic umgeschrieben oder direkt eingebunden, falls es eine für Freebasic gibt.
Aber ich werde wie bisher weitermachen. Ohne eine Bibliothek. Mir fehlt ja nur noch die Geschwindigkeit als Rückmeldung! Alles andere funktioniert ja!

Zitat
Du kannst es ja gleich strukturiert angehen und die "Basisfunktionen" in eine Bibliothek (mit dokumentierter API ) auslagern und danach anderen Benutzern zur Verfügung stellen (gerne auch OpenSource!).

Bei mir gibt es alles nur in der WTFPL-Lizenz! Inclusive Quellcode.

Im Moment arbeite ich an einer genialen Funktion! Lokeingabeprogramm wird gestartet und man muss bisher sämtliche Daten der Lok eingeben. Da kam mir die Idee, die Lokadresse automatisch an mein Computerprogramm zu senden! Das geht! Sobald ich eine Lok im Menu der CS 2 auswähle wird die Adresse inclusive Funktionen an den Computer gesendet. Damit brauche ich die Adresse der Lok nicht mehr eingeben. Vielleicht wird der Lokname auch an den Computer gesendet? Das wäre schon genial! Bei einer MFX-Lok wird dann automatisch eine Adresse in mein Programm eingetragen, sobald diese von der CS 2 erkannt wird!


Mein letzter Zugang:
1x Lockdown...


ALWIM  
ALWIM
InterRegio (IR)
Beiträge: 219
Registriert am: 05.04.2014


RE: Software schreiben zum steuern von Loks?

#102 von ALWIM , 06.06.2015 01:08

Die Werte von 0-62 scheinen vielleicht doch zu stimmen? Wie ich da drauf komme?
Also:
Laut Can-Doku werden Geschwindigkeiten im gesamten System als 10 - Bit Werte behandelt. Alle 16 ändert sich der Wert. 16 als Hexadezimalzahl ergibt 10! Das sind dann jene 10-Bit Werte. Bloß wie komme ich von 0-62 auf die 0-1000?

Was anderes konnte ich bei Tests bisher nicht rausfinden?

Zum Programm:
Habe jetzt 3 Radiobutton programmiert, zur Auswahl der Decoderart! Einer ist für MM, der 2. Button ist für MFX und der 3. Button ist für DCC! Man gibt nur noch die Adresse der Lok ein. Diese kann automatisch an mein Programm gesendet werden. Bei meinem TGV ist das die Adresse 7. 7+&h4000=4007= Dezimal 16391. Eingabe einer Lok funktioniert bei meinem Programm jetzt wie folgt: Datei anlegen (falls nicht schon vorhanden), auf neue Lok klicken, in der CS 2 gewünschte Lok auswählen (oder MFX-Lok auf's Gleis stellen), Decoderart auswählen, Lokname eingeben, Funktionen auswählen, Dauerfunktion bzw. Momentfunktion bei den einzelnen Funktionen festlegen, speichern! Be einem früheren Programmentwurf musste ich die 16391 für meinen MFX-TGV eingeben, um fahren zu können. Jetzt reicht die Adresse 7 aus!

Als nächstes muss ich schauen, dass mein Programm Threadsafe gemacht wird. Hängt sich nach wie vor auf!

Sifa, Sifa, ..., Sifa-Zwangsbremsung! ...
Sifa, Sifa, ... i Sifad da glei oane!

Ich werde wahrscheinlich die Sifa mit einbauen. Ein paar Ideen habe ich schon noch.

Gruß
ALWIM


Mein letzter Zugang:
1x Lockdown...


ALWIM  
ALWIM
InterRegio (IR)
Beiträge: 219
Registriert am: 05.04.2014


RE: Software schreiben zum steuern von Loks?

#103 von joachimkr , 02.01.2020 19:43

Zitat von st-oldie im Beitrag Software schreiben zum steuern von Loks?

Teil 1: Aufbau der CAN Nachricht und Abbildung auf eine UDP Sendepuffer
....



Hallo liebe Mitforisten,

Zunächst ein großes Lob an Michael, für diese perfekte Aufschlüsselung von CAN Know-How!

Ich selbst suche nach dem Aufbau eines UDP Pakets, dass dem eines Gleisbesetztmelders entspricht.
Jetzt habe ich hier im Thread noch nicht alles verstanden, aber wenn jemand hierauf anspringt...
Ich will das UDP/CAN Gateway der CS2 oder CS3 nutzen, um per UDP Events der Gleisbesetztmelder einzuspeisen.
Also nicht den Polling-Mode, sondern Ereignisse von Wechseln (Besetzt und Frei).

Die Dokumentation der CS 2, in der das CAN Protokoll definiert ist, gibt mir keinen exakten Aufschluss über die Abbildung des CAN Frames der Besetztmeldungen auf die UDP Form. Hardware zum mitlesen ist nicht vorhanden, wohl aber eine CS3 (Leihgabe), die diese UDP Pakete bekommen und auswerten soll.

Auch die Wahl einer für den Test geeigneten 32-Bit Adresse für den Melder, welche in der CS3 dann eingetragen wird, ist mir unklar.
Die Tabellen, die Märklin angegeben hat, verstehe ich unzureichend.

Was Ihr voraussetzen dürft: Ich programmiere hauptberuflich und UDP verstehe ich bestens. Es mangelt aber an Wissen über die Märklin Technik der CAN / CS Ecke. Das CS2 CAN Dokument von Märklin liegt mir vor. Unter 5.2 ist das Rückmelde-Event beschrieben.
Es heißt, im UDP Protokoll werden immer 13 Bytes übertragen. Die Nutzdaten belegen die Bytes 6 bis 13. So bleiben 5 über, von denen 2 durch den Hash XOR aus der Geräte-UID belegt werden, also 3 für die Felder Prio, Command(Byte), Response(Bit), DLC - das DLC soll dem Byte 5 entsprechen.
Irgendwie geht das nicht auf, oder ?
Wenn Command ein Byte ist, bleiben 2. Wenn DLC ein Byte ist, nur 1 Byte Rest:
Für Prio und Response. Diese Bitfelder liegen auch auseinander.
Dass die Prio für Rückmelder den Wert 3 haben soll, habe ich gesehen.
Hab ich was übersehen ?

Viele Grüße,
Joachim


In jeder Hinsicht Technik-affin 😎


 
joachimkr
EuroCity (EC)
Beiträge: 1.126
Registriert am: 12.11.2015
Ort: Hamburg
Spurweite H0, G
Stromart AC, Digital


RE: Software schreiben zum steuern von Loks?

#104 von st-oldie , 04.01.2020 00:12

Hallo Joachim,

erst mal ein ganz großes Danke für dein Lob. Schön daß die die Infos soweit gefallen.

Zitat
Das CS2 CAN Dokument von Märklin liegt mir vor. Unter 5.2 ist das Rückmelde-Event beschrieben.
Es heißt, im UDP Protokoll werden immer 13 Bytes übertragen. Die Nutzdaten belegen die Bytes 6 bis 13. So bleiben 5 über, von denen 2 durch den Hash XOR aus der Geräte-UID belegt werden, also 3 für die Felder Prio, Command(Byte), Response(Bit), DLC - das DLC soll dem Byte 5 entsprechen.
Irgendwie geht das nicht auf, oder ?
Wenn Command ein Byte ist, bleiben 2. Wenn DLC ein Byte ist, nur 1 Byte Rest:
Für Prio und Response. Diese Bitfelder liegen auch auseinander.
Dass die Prio für Rückmelder den Wert 3 haben soll, habe ich gesehen.



Die Aufteilung geht schon auf. DLC ist ein Byte und liegt auf Byte Nr. 5. Die ersten 4 Bytes 1 - 4 entsprechen der Meldungskennung, die in der Märklin Doku in Kapitel 1.1 beschrieben ist. Auf dem CAN Bus ist das die CAN ID. Die Bitfelder für Command, Prio und Response liegen deshalb nicht auf Bytegrenzen.

Der Hash belegt 2 Bytes, das sind die untersten 2 Bytes der Meldungskennung und die Bytes 3-4 des UDP Packets. Im 17. Bit der Meldungskennung ist das Response Bit gespeichert. Damit liegt das Command Byte nicht im 2. Byte der UDP Daten sondern ist um 1 Bit verschoben.

Deshalb hab ich zuerst die CAN Id kodiert und dann den 32 Bit Integer in die ersten 4 Bytes geschrieben bzw. zuerst die ersten 4 Bytes in einen 32 Bit Integer geschrieben und dann dekodiert:

1
2
3
4
5
6
7
8
 
void DecodeId(unsigned long CanId, unsigned short *Hash, unsigned short *Response,
unsigned short *Comamnd, unsigned short *Prio)
{
*Hash = (CanId >> 0) & 0x0000ffff;
*Response = (CanId >> 16) & 0x00000001;
*Command = (CanId >> 17) & 0x000000ff;
*Prio = (CanId >> 25) & 0x00000003;
}
 



Welche Programmiersprache benutzt du denn? Ich hab die Funktionen für Märklin CAN zu einer Bibliothek zusammengefaßt, die man auch in anderen Projekten benutzen könnte.

Tschüß
Michael


st-oldie  
st-oldie
InterRegioExpress (IRE)
Beiträge: 458
Registriert am: 22.12.2009
Homepage: Link
Ort: Friedberg (Hessen)
Gleise Märklin K-Gleis
Spurweite H0
Steuerung Märklin Systems
Stromart Digital


RE: Software schreiben zum steuern von Loks?

#105 von joachimkr , 04.01.2020 01:06

Zitat

Hallo Joachim,
....

1
2
3
4
5
6
7
8
9
 

short *Hash, unsigned short *Response,
unsigned short *Comamnd, unsigned short *Prio)
{
*Hash = (CanId >> 0) & 0x0000ffff;
*Response = (CanId >> 16) & 0x00000001;
*Command = (CanId >> 17) & 0x000000ff;
*Prio = (CanId >> 25) & 0x00000003;
}
 



Welche Programmiersprache benutzt du denn? Ich hab die Funktionen für Märklin CAN zu einer Bibliothek zusammengefaßt, die man auch in anderen Projekten benutzen könnte.

Tschüß
Michael



Hallo Michsel,
Um die Werte aus dem CAN Strom zu entnehmen, habe ich kein Problem.
Aber ich muss ja den UDP Strom erzeugen.
Soll das jetzt in Bitreihenfolge so auch über UDP angeliefert werden?
In Märklin's Doku heißt es, dass das DLC genau ein Byte wird.
Wenn ich das für bare Münze nehme, wo bleibt dann das Response und wo die Prio?
Oder setze ich die UDP Bytes genau so zusammen, wie Du sie oben dekodierst?

Ich nutze an der Stelle Java. Das liegt am genutzten Rahmen (Kura 4.1).
Der Code ist dann aber ziemlich ähnlich. Und komplex ist dieses Stück ja nicht, in Netzwerktechnik ist Java perfekt.

So ungefähr:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
  (pseudocode)
byte [] toUdp (short Hash, unsigned short Response,
unsigned short Command, unsigned short Prio)
{
int32 CanId; // der Veranschaulichung halber über int32
CanId = Hash & 0x0000ffff;
CanId |= (int32)((Response & 0x00000001) << 16);
CanId |= (int32)((Command & 0x000000ff) << 17);
CanId |= (int32)((Prio << 25) & 0x00000003);
// ohne Daten abgebildet:
byte [4] udp = new byte[4];
udp [3] = (byte) CanId >> 24;
udp [2] = (byte) CanId >> 16;
udp [1] = (byte) CanId >> 8;
udp [0] = (byte) CanId ; // >> 0;
// das Array zurückgeben, ohne Datenfeld
return udp;
}
 



Die Ausgabe in das Netzwerk würde dann ab byte [0] erfolgen, die anderen Bytes kämen dann hinterher.
Aber ich komme jetzt nicht auf insgesamt 13 Stück!

Vielen Dank
Grüße
Joachim


In jeder Hinsicht Technik-affin 😎


 
joachimkr
EuroCity (EC)
Beiträge: 1.126
Registriert am: 12.11.2015
Ort: Hamburg
Spurweite H0, G
Stromart AC, Digital


RE: Software schreiben zum steuern von Loks?

#106 von st-oldie , 05.01.2020 18:45

Hallo Joachim,

Zitat
Soll das jetzt in Bitreihenfolge so auch über UDP angeliefert werden?
Wenn ich das für bare Münze nehme, wo bleibt dann das Response und wo die Prio?
Oder setze ich die UDP Bytes genau so zusammen, wie Du sie oben dekodierst?

So ungefähr:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
  (pseudocode)
byte [] toUdp (short Hash, unsigned short Response,
unsigned short Command, unsigned short Prio)
{
int32 CanId; // der Veranschaulichung halber über int32
CanId = Hash & 0x0000ffff;
CanId |= (int32)((Response & 0x00000001) << 16);
CanId |= (int32)((Command & 0x000000ff) << 17);
CanId |= (int32)((Prio << 25) & 0x00000003);
// ohne Daten abgebildet:
byte [4] udp = new byte[4];
udp [3] = (byte) CanId >> 24;
udp [2] = (byte) CanId >> 16;
udp [1] = (byte) CanId >> 8;
udp [0] = (byte) CanId ; // >> 0;
// das Array zurückgeben, ohne Datenfeld
return udp;
}
 




Ja, fast genau so. Du hast nur die Bytereihenfolge verdreht Wenn du dir den C Headerfile "can.h" anschaust, besteht ein Datenpaket, das von der socketCAN Schnittstelle gelesen wird, aus einem 32 Bit Integer (ID), einem Byte DLC und 8 Datenbytes. Märklin benutzt die ID als "Meldungskennung". Die padding Bytes kannst du ignorieren.

1
2
3
4
5
6
7
8
 
struct can_frame {
canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
__u8 can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
__u8 __pad; /* padding */
__u8 __res0; /* reserved / padding */
__u8 __res1; /* reserved / padding */
__u8 data[CAN_MAX_DLEN] __attribute__((aligned(8)));
};
 



Ein UDP Frame enthält also die Bytes, die die ID belegt, dann das DLC Byte und dann die Datenbytes. Die Bytes der ID sind in der Netzwerk Reihenfolge gespeichert, also big endian (motorola) order. Damit hast du dann aber auch genau die Bitreihenfolge für die ersten 4 Bytes, die Märklin für die Meldungskennung dokumentiert hat. Du müßtest noch deinen Pseudocode so modifizieren:

1
2
3
4
5
6
7
 
  (pseudocode)
...
udp [0] = (byte) CanId >> 24;
udp [1] = (byte) CanId >> 16;
udp [2] = (byte) CanId >> 8;
udp [3] = (byte) CanId ; // >> 0;
...
 



Zitat
In Märklin's Doku heißt es, dass das DLC genau ein Byte wird.

Die Ausgabe in das Netzwerk würde dann ab byte [0] erfolgen, die anderen Bytes kämen dann hinterher.
Aber ich komme jetzt nicht auf insgesamt 13 Stück!



Wenn du "byte" als den zu versendenden Puffer betrachtest, müßtest du in deinen "pseudocode" 13 Bytes und nicht 4 allozieren. Da du schon die CAN ID (Meldungskennung) kodiert hast, sind die Bytes byte[0] bis byte[3] mit der Märklin Meldungskennung beschrieben.

In byte[4] kommt die DLC, macht 5 Bytes.

In byte[5] bis byte[12] kommen die 8 Datenbytes, macht dann 13 Bytes.

Damit kommst du auf die 13 Bytes: 4 Byte Meldungskennung, 1 Byte DLC, 8 Datenbytes.

Ärgerlicherweise zählt C ja immer ab 0, was der "natürlichen" Zählweise widerspricht. Und was leicht zu einer Fehlinterpretation führen kann. Ich hab ja auch immer vom ersten Byte, ... gesprochen. Das erste Byte ist ja byte[0], was hier im Forum die Leute verwirren könnte, die nicht in C programmieren. Vielleicht hab ich das auch nicht immer eindeutig genug beschrieben, um solche Verwirrungen zu vermeiden.

Zitat
Ich nutze an der Stelle Java. Das liegt am genutzten Rahmen (Kura 4.1).
Der Code ist dann aber ziemlich ähnlich. Und komplex ist dieses Stück ja nicht, in Netzwerktechnik ist Java perfekt.



Dann hast du wahrscheinlich mit Bitoperationen weniger zu tun. Du kannst ja wahrscheinlich auf einer etwas höheren Abstraktionsebene programmieren? Ich schreibe Software für Embedded Systems. Beim Zugriff auf Register der Hardware kommen Bitoperationen regelmäßig vor. Aber dann lassen sich die Libs meines mrsystem nicht so leicht in dein Projekt integrieren.

Tschüß
Michael


st-oldie  
st-oldie
InterRegioExpress (IRE)
Beiträge: 458
Registriert am: 22.12.2009
Homepage: Link
Ort: Friedberg (Hessen)
Gleise Märklin K-Gleis
Spurweite H0
Steuerung Märklin Systems
Stromart Digital


RE: Software schreiben zum steuern von Loks?

#107 von joachimkr , 05.01.2020 20:10

Zitat

....
Dann hast du wahrscheinlich mit Bitoperationen weniger zu tun. Du kannst ja wahrscheinlich auf einer etwas höheren Abstraktionsebene programmieren?
Tschüß
Michael



Hallo Michael,

Da war aber kein Bit-Fehler drin, oder ?
Die Frage, welches Byte zuerst gesendet wird, entscheidet. Ich kontrolliere das nochmal. Aber die Bytes müssten in sich ja nun eigentlich stimmen. Die Menge ist nun auch geklärt. Das war auch so gemeint, dass mit new dann auch 13 angelegt werden. Dass es mit dem DLC dann in der Menge stimmt, war mir entgangen.

In den 80er Jahren durfte ich Mengen von Assembler schreiben, dann noch größere in C, dann Unmengen C++, dann Verilog, seit 1998 Unmengen Java und minimale Mengen C#.

Vielen Dank für die Mühe, das genau anzuschauen!
Viele Grüße
Joachim


In jeder Hinsicht Technik-affin 😎


 
joachimkr
EuroCity (EC)
Beiträge: 1.126
Registriert am: 12.11.2015
Ort: Hamburg
Spurweite H0, G
Stromart AC, Digital


RE: Software schreiben zum steuern von Loks?

#108 von st-oldie , 05.01.2020 21:42

Hi Joachim,

Zitat
Die Frage, welches Byte zuerst gesendet wird, entscheidet. Ich kontrolliere das nochmal.



Im Kapitel 1.2.7 der Märkin Doku steht, daß das UDP Paket mit 4 Bytes CAN ID in big-endian bzw. Network Order beginnt. Mit der falschen Reihenfolge erkennt man dann das Kommando nicht.

Zitat
Aber die Bytes müssten in sich ja nun eigentlich stimmen.



Ich denke, daß die Bytes an sich stimmen, also die Bits richtig geshiftet werden. Da ist in deinem Codeschnipsel nichts aufgefallen.

Zitat
Die Menge ist nun auch geklärt. Das war auch so gemeint, dass mit new dann auch 13 angelegt werden. Dass es mit dem DLC dann in der Menge stimmt, war mir entgangen.



Kann passieren. Ich muß auch aufpassen, daß sich da nicht mal eben schnell Flüchtigkeitsfehler einschleichen, wenn ich mal eben so einen Beitrag schreibe.

Zitat
In den 80er Jahren durfte ich Mengen von Assembler schreiben, dann noch größere in C, dann Unmengen C++, dann Verilog, seit 1998 Unmengen Java und minimale Mengen C#.



Na dann kannst du das ja alles aus dem Ärmel schütteln

Zitat
Vielen Dank für die Mühe, das genau anzuschauen!



Kein Problem. Wenn man Code erstellt hat, ist man manchmal "betriebsblind". Das kenen ich auch. Dann kann ein außenstehender leichter den Gedankenfehler finden. Ansonsten freut es mich, auch mal weiterhelfen zu können.

Tschüß
Michael


st-oldie  
st-oldie
InterRegioExpress (IRE)
Beiträge: 458
Registriert am: 22.12.2009
Homepage: Link
Ort: Friedberg (Hessen)
Gleise Märklin K-Gleis
Spurweite H0
Steuerung Märklin Systems
Stromart Digital


RE: Software schreiben zum steuern von Loks?

#109 von joachimkr , 06.01.2020 02:49

Zitat

Hallo Joachim,

1
2
3
4
5
6
7
 
  (pseudocode)
...
udp [0] = (byte) CanId >> 24;
udp [1] = (byte) CanId >> 16;
udp [2] = (byte) CanId >> 8;
udp [3] = (byte) CanId ; // >> 0;
...
 


Tschüß
Michael




Das war tatsächlich ein Flüchtigkeitsfehler von mir. Die Reihenfolge startete sogar korrekt.
Danke, Michael!


In jeder Hinsicht Technik-affin 😎


 
joachimkr
EuroCity (EC)
Beiträge: 1.126
Registriert am: 12.11.2015
Ort: Hamburg
Spurweite H0, G
Stromart AC, Digital


RE: Software schreiben zum steuern von Loks?

#110 von st-oldie , 06.01.2020 20:40

Hallo Joachim,

schön, freut mich daß es jetzt geht.

Tschüß
Michael


st-oldie  
st-oldie
InterRegioExpress (IRE)
Beiträge: 458
Registriert am: 22.12.2009
Homepage: Link
Ort: Friedberg (Hessen)
Gleise Märklin K-Gleis
Spurweite H0
Steuerung Märklin Systems
Stromart Digital


RE: Software schreiben zum steuern von Loks?

#111 von joachimkr , 07.01.2020 14:34

Zitat

schön, freut mich daß es jetzt geht.



So weit ist es noch nicht...Habe den Code noch nicht am Start. Aber die Grundlage, zu verstehen was man tut, ist nun da


In jeder Hinsicht Technik-affin 😎


 
joachimkr
EuroCity (EC)
Beiträge: 1.126
Registriert am: 12.11.2015
Ort: Hamburg
Spurweite H0, G
Stromart AC, Digital


RE: Software schreiben zum steuern von Loks?

#112 von joachimkr , 16.01.2020 15:18

Hallo,
Ich musste jetzt unterbrechen. Ein Auftrag verschlägt mich nächste Woche komplett ins Ausland, die Arbeiten müssen ruhen. Die Leihgabe, eine nagelneue CS3 plus (schickes Teil) schicke ich wegen der Unterbrechung nun zurück.
Stunden habe ich damit verbracht, in der CS3 einen Reed-Kontakt (ist egal, als was er interpretiert wird) im Gleisplan einzufügen.
Allerdings bin ich zunächst daran gescheitert, eine Adresse so zu produzieren, dass sie diesem Kontakt zugeordnet wird.
Nach Beschreibung hätte der Kontakt kurz aufleuchten müssen, um mir die Akzeptanz anzuzeigen. Hat er aber nicht...
Ich hatte einfach noch zu wenig Zeit, irgendwo (wo ?) weiter zu buddeln.
Wie man aus den Parametern der Kontakte eine Adresse berechnet, habe ich nicht gefunden / verstanden.

Viele Grüße,
Joachim


In jeder Hinsicht Technik-affin 😎


 
joachimkr
EuroCity (EC)
Beiträge: 1.126
Registriert am: 12.11.2015
Ort: Hamburg
Spurweite H0, G
Stromart AC, Digital


   


  • Ähnliche Themen
    Antworten
    Zugriffe
    Letzter Beitrag
Xobor Einfach ein eigenes Forum erstellen
Datenschutz