Anlage mit C# steuern
Anlage mit C# steuern
Ich habe eine Frage und zwar habe ich eine Modellbahn mit einem Märklin Interface. Ich bin gerade dabei ein eigens Programm für die Steuerung dieser Anlage in C# zu schreiben.
Das manuelle wählen der Weichen und Loks funktioniert auch schon ganz gut.
Nun zu meiner Frage weiß jemand von euch wie das mit der Rückmeldung unter C# funktioniert ich habe nämlich bereits einiges versucht. Aber leider hat nichts zum Erfolggeführt.
Würde mich sehr über ein Antwort freuen. Wenn jemand Problem mit der Ansteuerung der Weichen oder Loks hat kann er sich gerne auch bei mir melden ich werde dann versuchen zu helfen.
Das manuelle wählen der Weichen und Loks funktioniert auch schon ganz gut.
Nun zu meiner Frage weiß jemand von euch wie das mit der Rückmeldung unter C# funktioniert ich habe nämlich bereits einiges versucht. Aber leider hat nichts zum Erfolggeführt.
Würde mich sehr über ein Antwort freuen. Wenn jemand Problem mit der Ansteuerung der Weichen oder Loks hat kann er sich gerne auch bei mir melden ich werde dann versuchen zu helfen.
- Flashbanger
- Forumane
- Beiträge: 366
- Registriert: Samstag 29. Juli 2006, 22:57
- Kontaktdaten:
Wenn du ein Märklin 6050 /6051 hast, dann geht dies so:
entweder du rufst alle rückmelder bis zu einem Modul ab. Dann sendest du
129...159 auf der seriellen Schnittstelle. Wie das unter C# geht weis ich nicht.
Ein beispiel: Du willst bis zum 5. S88 auslesen. Dann musst du
Also 133 Nach dem senden musst du auf empfangen schalten. Du wirst dann 10 Bytes auf der Schnittstelle bekommen.
Das erste Bit des ersten Bytes ist auch der 1. Kontakt am 1. S88. Das 1. Bit im 2. Byte ist der 9. Kontakt im ersten S88. usw. usw.
Die andere Möglichkeit ist das auslesen eines einzelnen Rückmelders.
Dazu musst du die zahlen 192...223 senden. Dann wieder auf Empfang schalten und die Zwei Bytes auslesen.
Gruß Flashbanger
entweder du rufst alle rückmelder bis zu einem Modul ab. Dann sendest du
129...159 auf der seriellen Schnittstelle. Wie das unter C# geht weis ich nicht.
Ein beispiel: Du willst bis zum 5. S88 auslesen. Dann musst du
Code: Alles auswählen
129 + 5 - 1
Das erste Bit des ersten Bytes ist auch der 1. Kontakt am 1. S88. Das 1. Bit im 2. Byte ist der 9. Kontakt im ersten S88. usw. usw.
Die andere Möglichkeit ist das auslesen eines einzelnen Rückmelders.
Dazu musst du die zahlen 192...223 senden. Dann wieder auf Empfang schalten und die Zwei Bytes auslesen.
Gruß Flashbanger
MfG Flashbanger
______________________
CU+6050 + C-Gleis
Software: TC4.7 oder
MBSS v 0.1 beta
______________________
CU+6050 + C-Gleis
Software: TC4.7 oder
MBSS v 0.1 beta
- HaNull
- Forumane
- Beiträge: 4381
- Registriert: Freitag 2. Februar 2007, 01:47
- Wohnort: Rhein-Sieg-Kreis
Wieviel weißt Du denn schon?leinad hat geschrieben:Das eigentliche Problem ist wie es in C# geht.
Ich habe mal F1 gedrückt und "System.IO.Ports Namespace" gefunden.
Und wenn Du bei www.google.de nach "new SerialDataReceivedEventHandler" (einschl. Anführungszeichen) suchen lässt, findest Du auch Beispielcode.
Mit Google nach Beispielen suchen ...
HTH - sonst bitte Frage präzisieren.
████████ Gruß aus NRW
████████ Thomas
████████ Multi-MISTler: 1. Siegburg (RSK) - 2. Köln rrh. - 3. Rheinbreitbach
████████ Thomas
████████ Multi-MISTler: 1. Siegburg (RSK) - 2. Köln rrh. - 3. Rheinbreitbach
- Flashbanger
- Forumane
- Beiträge: 366
- Registriert: Samstag 29. Juli 2006, 22:57
- Kontaktdaten:
Wird zum Beispiel durch einen Timer ausgelösst:
public string []C = new string[32];
public string []D = new string [32];
public int anzahl = 2;
public int[] Kontakt = new int[400];//noch nicht der entgültige wert
serialPort1.Open();
serialPort1.Write(new byte[] { (byte)(128 + anzahl) }, 0, 1);
System.Threading.Thread.Sleep(5);
B = Convert.ToString(serialPort1.BytesToRead);
do
{
j++;
textBox3.Text=(Convert.ToString(j));
C[j] = Convert.ToString(serialPort1.ReadByte());
D[j] = Convert.ToString(serialPort1.ReadByte());
Aswerten(j, Convert.ToInt32(C[j]), Convert.ToInt32(D[j]));
} while (j <= anzahl-1);
serialPort1.Close();
public void Auswerten(int rückmeldeModulNummer, int I, int K)
{
int J = 16*(rückmeldeModulNummer -1); //Nummer des Rückmeldemoduls
if (I >= 128)
{
Kontakt[1 + J] = 1;
I = I - 128;
}
else
Kontakt[1 + J] = 0;
if (I >= 64)
{
Kontakt[2 + J] = 1;
I = I - 64;
}
else
Kontakt[2 + J] = 0;
if (I >= 32)
{
Kontakt[3 + J] = 1;
I = I - 32;
}
else
Kontakt[3 + J] = 0;
if (I >= 16)
{
Kontakt[4 + J] = 1;
I = I - 16;
}
else
Kontakt[4 + J] = 0;
if (I >=
{
Kontakt[5 + J] = 1;
I = I - 8;
}
else
Kontakt[5 + J] = 0;
if (I >= 4)
{
Kontakt[6 + J] = 1;
I = I - 4;
}
else
Kontakt[6 + J] = 0;
if (I >= 2)
{
Kontakt[7 + J] = 1;
I = I - 2;
}
else
Kontakt[7 + J] = 0;
if (I >= 1)
{
Kontakt[8 + J] = 1;
I = I - 1;
}
else
Kontakt[8 + J] = 0;
if (K >= 128)
{
Kontakt[9 + J] = 1;
K = K - 128;
}
else
Kontakt[9 + J] = 0;
if (K >= 64)
{
Kontakt[10 + J] = 1;
K = K - 64;
}
else
Kontakt[10 + J] = 0;
if (K >= 32)
{
Kontakt[11 + J] = 1;
K = K - 32;
}
else
Kontakt[11 + J] = 0;
if (K >= 16)
{
Kontakt[12 + J] = 1;
K = K - 16;
}
else
Kontakt[12 + J] = 0;
if (K >=
{
Kontakt[13 + J] = 1;
K = K - 8;
}
else
Kontakt[13 + J] = 0;
if (K >= 4)
{
Kontakt[14 + J] = 1;
K = K - 4;
}
else
Kontakt[14 + J] = 0;
if (K >= 2)
{
Kontakt[15 + J] = 1;
K = K - 2;
}
else
Kontakt[15 + J] = 0;
if (K >= 1)
{
Kontakt[16 + J] = 1;
K = K - 1;
}
else
Kontakt[16 + J] = 0;
Anzeigen();
}
Ich hoffe ihr kommt mit dem Code Ausschnit klar.
Wenn jemand einen besseren Forschlag oder eine Frage hat kann er sich ruhig melden.
public string []C = new string[32];
public string []D = new string [32];
public int anzahl = 2;
public int[] Kontakt = new int[400];//noch nicht der entgültige wert
serialPort1.Open();
serialPort1.Write(new byte[] { (byte)(128 + anzahl) }, 0, 1);
System.Threading.Thread.Sleep(5);
B = Convert.ToString(serialPort1.BytesToRead);
do
{
j++;
textBox3.Text=(Convert.ToString(j));
C[j] = Convert.ToString(serialPort1.ReadByte());
D[j] = Convert.ToString(serialPort1.ReadByte());
Aswerten(j, Convert.ToInt32(C[j]), Convert.ToInt32(D[j]));
} while (j <= anzahl-1);
serialPort1.Close();
public void Auswerten(int rückmeldeModulNummer, int I, int K)
{
int J = 16*(rückmeldeModulNummer -1); //Nummer des Rückmeldemoduls
if (I >= 128)
{
Kontakt[1 + J] = 1;
I = I - 128;
}
else
Kontakt[1 + J] = 0;
if (I >= 64)
{
Kontakt[2 + J] = 1;
I = I - 64;
}
else
Kontakt[2 + J] = 0;
if (I >= 32)
{
Kontakt[3 + J] = 1;
I = I - 32;
}
else
Kontakt[3 + J] = 0;
if (I >= 16)
{
Kontakt[4 + J] = 1;
I = I - 16;
}
else
Kontakt[4 + J] = 0;
if (I >=
{
Kontakt[5 + J] = 1;
I = I - 8;
}
else
Kontakt[5 + J] = 0;
if (I >= 4)
{
Kontakt[6 + J] = 1;
I = I - 4;
}
else
Kontakt[6 + J] = 0;
if (I >= 2)
{
Kontakt[7 + J] = 1;
I = I - 2;
}
else
Kontakt[7 + J] = 0;
if (I >= 1)
{
Kontakt[8 + J] = 1;
I = I - 1;
}
else
Kontakt[8 + J] = 0;
if (K >= 128)
{
Kontakt[9 + J] = 1;
K = K - 128;
}
else
Kontakt[9 + J] = 0;
if (K >= 64)
{
Kontakt[10 + J] = 1;
K = K - 64;
}
else
Kontakt[10 + J] = 0;
if (K >= 32)
{
Kontakt[11 + J] = 1;
K = K - 32;
}
else
Kontakt[11 + J] = 0;
if (K >= 16)
{
Kontakt[12 + J] = 1;
K = K - 16;
}
else
Kontakt[12 + J] = 0;
if (K >=
{
Kontakt[13 + J] = 1;
K = K - 8;
}
else
Kontakt[13 + J] = 0;
if (K >= 4)
{
Kontakt[14 + J] = 1;
K = K - 4;
}
else
Kontakt[14 + J] = 0;
if (K >= 2)
{
Kontakt[15 + J] = 1;
K = K - 2;
}
else
Kontakt[15 + J] = 0;
if (K >= 1)
{
Kontakt[16 + J] = 1;
K = K - 1;
}
else
Kontakt[16 + J] = 0;
Anzeigen();
}
Ich hoffe ihr kommt mit dem Code Ausschnit klar.
Wenn jemand einen besseren Forschlag oder eine Frage hat kann er sich ruhig melden.
- HaNull
- Forumane
- Beiträge: 4381
- Registriert: Freitag 2. Februar 2007, 01:47
- Wohnort: Rhein-Sieg-Kreis
Hallo!
Danke für das Veröffentlichen Deiner Lösung; vielleicht programmiere ich irgendwann auch etwas in dieser Richtung.
"new SerialDataReceivedEventHandler" scheint mir da ein besserer Ansatz.
Mein PC ist recht leise - es sei denn, Programme treiben die CPU mit busy waiting zu Rekordtemperaturen und den Lüfter auf Hochtouren ...
BTW: wenn Du dein Listing zwischen [_QUOTE] und [/QUOTE_] (jeweils ohne Unterstriche) packst, dann bleiben die Leerzeichen (Einrückungen) erhalten.
Danke für das Veröffentlichen Deiner Lösung; vielleicht programmiere ich irgendwann auch etwas in dieser Richtung.
Das sieht ein bißchen nach "busy waiting" aus.leinad hat geschrieben:System.Threading.Thread.Sleep(5);
"new SerialDataReceivedEventHandler" scheint mir da ein besserer Ansatz.
Mein PC ist recht leise - es sei denn, Programme treiben die CPU mit busy waiting zu Rekordtemperaturen und den Lüfter auf Hochtouren ...
BTW: wenn Du dein Listing zwischen [_QUOTE] und [/QUOTE_] (jeweils ohne Unterstriche) packst, dann bleiben die Leerzeichen (Einrückungen) erhalten.
████████ Gruß aus NRW
████████ Thomas
████████ Multi-MISTler: 1. Siegburg (RSK) - 2. Köln rrh. - 3. Rheinbreitbach
████████ Thomas
████████ Multi-MISTler: 1. Siegburg (RSK) - 2. Köln rrh. - 3. Rheinbreitbach
- Peter Müller
- Forumane
- Beiträge: 4291
- Registriert: Dienstag 25. Januar 2005, 12:43
... seit wann darf man denn Smilies im Sourcecode verwenden?else
Kontakt[4 + J] = 0;
if (I >=
{
Kontakt[5 + J] = 1;
I = I - 8;
Grüße, Peter
Bei campact.de per E-Mail abstimmen: 49-Euro-Ticket retten! ... das haben Stand 25.08.2023 um 20:45 Uhr schon 115.000 Menschen getan.
Und Aktionen bei campact.de wirken, siehe Wikipedia, da wird darüber berichtet.
Bei campact.de per E-Mail abstimmen: 49-Euro-Ticket retten! ... das haben Stand 25.08.2023 um 20:45 Uhr schon 115.000 Menschen getan.
Und Aktionen bei campact.de wirken, siehe Wikipedia, da wird darüber berichtet.
- HaNull
- Forumane
- Beiträge: 4381
- Registriert: Freitag 2. Februar 2007, 01:47
- Wohnort: Rhein-Sieg-Kreis
Hier mal der Beitrag von leinad als Code formatiert (ohne Smilies):
Code: Alles auswählen
Wird zum Beispiel durch einen Timer ausgelösst:
public string []C = new string[32];
public string []D = new string [32];
public int anzahl = 2;
public int[] Kontakt = new int[400];//noch nicht der entgültige wert
serialPort1.Open();
serialPort1.Write(new byte[] { (byte)(128 + anzahl) }, 0, 1);
System.Threading.Thread.Sleep(5);
B = Convert.ToString(serialPort1.BytesToRead);
do
{
j++;
textBox3.Text=(Convert.ToString(j));
C[j] = Convert.ToString(serialPort1.ReadByte());
D[j] = Convert.ToString(serialPort1.ReadByte());
Auswerten(j, Convert.ToInt32(C[j]), Convert.ToInt32(D[j]));
} while (j <= anzahl-1);
serialPort1.Close();
public void Auswerten(int rückmeldeModulNummer, int I, int K)
{
int J = 16 * (rückmeldeModulNummer - 1); //Nummer des Rückmeldemoduls
if (I >= 128)
{
Kontakt[1 + J] = 1;
I = I - 128;
}
else
Kontakt[1 + J] = 0;
if (I >= 64)
{
Kontakt[2 + J] = 1;
I = I - 64;
}
else
Kontakt[2 + J] = 0;
if (I >= 32)
{
Kontakt[3 + J] = 1;
I = I - 32;
}
else
Kontakt[3 + J] = 0;
if (I >= 16)
{
Kontakt[4 + J] = 1;
I = I - 16;
}
else
Kontakt[4 + J] = 0;
if (I >= 8)
{
Kontakt[5 + J] = 1;
I = I - 8;
}
else
Kontakt[5 + J] = 0;
if (I >= 4)
{
Kontakt[6 + J] = 1;
I = I - 4;
}
else
Kontakt[6 + J] = 0;
if (I >= 2)
{
Kontakt[7 + J] = 1;
I = I - 2;
}
else
Kontakt[7 + J] = 0;
if (I >= 1)
{
Kontakt[8 + J] = 1;
I = I - 1;
}
else
Kontakt[8 + J] = 0;
if (K >= 128)
{
Kontakt[9 + J] = 1;
K = K - 128;
}
else
Kontakt[9 + J] = 0;
if (K >= 64)
{
Kontakt[10 + J] = 1;
K = K - 64;
}
else
Kontakt[10 + J] = 0;
if (K >= 32)
{
Kontakt[11 + J] = 1;
K = K - 32;
}
else
Kontakt[11 + J] = 0;
if (K >= 16)
{
Kontakt[12 + J] = 1;
K = K - 16;
}
else
Kontakt[12 + J] = 0;
if (K >= 8)
{
Kontakt[13 + J] = 1;
K = K - 8;
}
else
Kontakt[13 + J] = 0;
if (K >= 4)
{
Kontakt[14 + J] = 1;
K = K - 4;
}
else
Kontakt[14 + J] = 0;
if (K >= 2)
{
Kontakt[15 + J] = 1;
K = K - 2;
}
else
Kontakt[15 + J] = 0;
if (K >= 1)
{
Kontakt[16 + J] = 1;
K = K - 1;
}
else
Kontakt[16 + J] = 0;
Anzeigen();
}
Ich hoffe ihr kommt mit dem Code Ausschnit klar.
Wenn jemand einen besseren Forschlag oder eine Frage hat kann er sich ruhig melden.
████████ Gruß aus NRW
████████ Thomas
████████ Multi-MISTler: 1. Siegburg (RSK) - 2. Köln rrh. - 3. Rheinbreitbach
████████ Thomas
████████ Multi-MISTler: 1. Siegburg (RSK) - 2. Köln rrh. - 3. Rheinbreitbach
Ist das der Wert der Wartezeit zwischen 2 Timerereignissen zum Auslesen der S88? Dann ist diese Zeit zu lang. Um zeitnah die S88 abzufragen muss man unter 1 Sek bleiben. Ich lasse alle 501mS die S88 abfragen.h-zero hat geschrieben:Hier mal der Beitrag von leinad als Code formatiert (ohne Smilies):Code: Alles auswählen
Wird zum Beispiel durch einen Timer ausgelösst: System.Threading.Thread.Sleep(5);
In VB6 bedeutet der Befehl "Sleep" dass dieses Programm für die angegebene Zeit schlafen gelegt wird. Das ist gefährlich, da während dieser Zeit keine Programmausführung erfolgt, also auch kein Befehl an das Interface gesendet wird.
BB
Danke das ihr die Smillies raus getan hab ich hatte am Wochenende leider keine Zeit um da zu erledigen.
Nun zu deiner Frage:
Nein das ist nur einen kurze Unterbrechung zwischen dem schreiben und lesen der Schnittstelle. Zudem sind das nur 5/1000 Sekunden.
Denn Timer habe ich direkt in der Form definiert.
Mich freut das so viele Interesse an diesem Thema haben.
Nun zu deiner Frage:
Nein das ist nur einen kurze Unterbrechung zwischen dem schreiben und lesen der Schnittstelle. Zudem sind das nur 5/1000 Sekunden.
Denn Timer habe ich direkt in der Form definiert.
Mich freut das so viele Interesse an diesem Thema haben.
Das funktioniert sehr gut.
Wenn ich die 5/1000 funktioniert es nicht ich denke nämlich dass das eher mit der Ansteuerung der Schnittstelle etwas zu tun hat und nicht mit dem Interface.
Aber das ist nur eine Vermutung du kannst es ja mal Probieren.
Oder wenn jemand eine andere Idee hat warum es so sein muss kann er sich auch gerne melden.
Wenn ich die 5/1000 funktioniert es nicht ich denke nämlich dass das eher mit der Ansteuerung der Schnittstelle etwas zu tun hat und nicht mit dem Interface.
Aber das ist nur eine Vermutung du kannst es ja mal Probieren.
Oder wenn jemand eine andere Idee hat warum es so sein muss kann er sich auch gerne melden.
Also, mit diesem Satz kann ich nun gar nichts anfangen. Funktioniert das Programm nun oder nicht? Welches Interface hast Du denn nun?leinad hat geschrieben:Das funktioniert sehr gut.
Wenn ich die 5/1000 funktioniert es nicht ich denke nämlich dass das eher mit der Ansteuerung der Schnittstelle etwas zu tun hat und nicht mit dem Interface.
BB
Moin,
@h-zero: gerade Sleep() Funktionen sollten keine CPU-Last erzeugen, sondern den Thread für die Zeit schlafenlegen, vor allem wenn es von MS im .NET bereitgestellt wird.
@leinad: warum das Sleep()?
Eigentlich gehören Lesen und Schreiben doch in zwei verschiedene Funktionen, die in unterschiedlichen Threads laufen, zumindest sollten die das wenn du ihne Events arbeitest.
Gruß
Hannes
@h-zero: gerade Sleep() Funktionen sollten keine CPU-Last erzeugen, sondern den Thread für die Zeit schlafenlegen, vor allem wenn es von MS im .NET bereitgestellt wird.
@leinad: warum das Sleep()?
Eigentlich gehören Lesen und Schreiben doch in zwei verschiedene Funktionen, die in unterschiedlichen Threads laufen, zumindest sollten die das wenn du ihne Events arbeitest.
Gruß
Hannes
- HaNull
- Forumane
- Beiträge: 4381
- Registriert: Freitag 2. Februar 2007, 01:47
- Wohnort: Rhein-Sieg-Kreis
Hallo!
Mit Sleep(5) wird die Funktion 200mal pro Sekunde ausgeführt - das ist nicht viel, aber viel schlechter als das Warten auf ein Event ...Oysos hat geschrieben:@h-zero: gerade Sleep() Funktionen sollten keine CPU-Last erzeugen, sondern den Thread für die Zeit schlafenlegen, vor allem wenn es von MS im .NET bereitgestellt wird.
████████ Gruß aus NRW
████████ Thomas
████████ Multi-MISTler: 1. Siegburg (RSK) - 2. Köln rrh. - 3. Rheinbreitbach
████████ Thomas
████████ Multi-MISTler: 1. Siegburg (RSK) - 2. Köln rrh. - 3. Rheinbreitbach