Status Türen aus TCP-Protokoll

Das Unterforum für Diskussionen rund um die Technik, Bedienung, Konfiguration usw. Das ist auch die erste Anlaufstelle für Bastler mit Fragen zu den Editoren.
Antworten
Nachricht
Autor
TobiPe
Beiträge: 6
Registriert: 01.10.2025 15:30:25
Aktuelle Projekte: Teil des Technik-Teams von tf-ausbildung.de
Handwerkliche und programmier-technische Unterstüzung im privaten Fahrpult-Simulatorbau
Wohnort: Neumünster

Status Türen aus TCP-Protokoll

#1 Beitrag von TobiPe »

Hallo zusammen,

wir haben in der Vergangenheit schon einige Fahrpulte umgebaut und sind Baureihenübergreifend immer wieder auf ein Problem gestoßen. Die Ausgaben, die über TCP an das Fahrpult gesendet werden, passen nicht mit den Führerstandsausgaben überein. Konkret geht es um Führerstände, die mehrere Türsysteme abbilden können. Hierbei werden teilweise Leuchtmelder angesteuert die nichts mit dem gewählten Türsystem zu tun haben.

Ich habe die Ausgaben nicht nur auf den Fahrpulten geprüft, sondern auch mit dem TCPClientDemoOutput64-Tool ausgewertet um Programmierfehler auszuschließen und habe verschiedene Situationen analysiert.

Beispiel TAV Leuchtmelder: Abgefragt wird hier der Knoten 0002.000A.0066.0013
TAV: Macht das was er soll (Türen zu: Dauerlicht, Türen auf: aus, Türen schließend: blinken)
SAT: Soll aus sein, ist aber bei Türen auf am blinken, sonst Dauerlicht.
TB0: Aus

Beispiel SAT Leuchtmelder: Abgefragt werden hier die Knoten 0002.000A.0066.(0005-0007+000C) je nachdem was Freigegeben wurde
TAV: Soll aus sein, blinkt aber bei offenen Türen und leuchtet dauerhaft wenn eine Richtung vorgewählt, aber noch nicht freigegeben wurde
SAT: Macht was er soll (Blinkt, wenn die Türen offen sind, sonst aus)
TB0: Soll aus sein, Leuchtet dauerhaft, sobald die Türen auf sind

Die Frage ist, wie sage ich dem Fahrpult, dass die jeweiligen Leuchtmelder nur angehen, wenn das Fahrzeug im jeweiligen Modus ist? Weil für den jeweiligen Modus macht er ja was er soll.
Der Punkt 0002.000A.0066.0001 gibt ja nur das System als Text aus. Das versteht der Arduino nicht und ist somit nicht zu gebrauchen.
Ich verstehe auch nicht, wieso die TCP-Ausgabe eine andere ist, wie das, was in der Führerstandsgrafik angezeigt wird. Da klappt das mit den Leuchtmeldern ja fehlerfrei (auch wenn die SAT-Geschichte ja nur eine Bildschirmeinblendung ist, da sich der LM außerhalb der Grafik befinden würde).

Vielleicht fragen wir auch einfach nur das falsche ab und die Lösung ist doch ganz simpel. Manchmal sieht man ja vor lauter Bäumen den Wald nicht.

Ich bin auf eure Ideen und Gedanken gespannt.

Es grüßt aus dem Norden der
-Tobi

Benutzeravatar
Johannes
Beiträge: 3491
Registriert: 14.03.2009 22:36:06
Aktuelle Projekte: Zusitools (http://git.io/zusitools)

Re: Status Türen aus TCP-Protokoll

#2 Beitrag von Johannes »

TobiPe hat geschrieben: 04.11.2025 01:27:30 Der Punkt 0002.000A.0066.0001 gibt ja nur das System als Text aus. Das versteht der Arduino nicht und ist somit nicht zu gebrauchen.
Was ist denn hier genau das Problem?

TobiPe
Beiträge: 6
Registriert: 01.10.2025 15:30:25
Aktuelle Projekte: Teil des Technik-Teams von tf-ausbildung.de
Handwerkliche und programmier-technische Unterstüzung im privaten Fahrpult-Simulatorbau
Wohnort: Neumünster

Re: Status Türen aus TCP-Protokoll

#3 Beitrag von TobiPe »

Hallo,

der Arduino versteht das nicht, was aus dem Protokoll kommt. Ich vermute, weil da ein "ü" drin ist. Beim kompilieren und übertragen hat er nicht gemeckert, aber die Auswertung fand nicht statt. Codemäßig habe ich das so gelöst, dass das Türsystem eine Variable setzt. Bloß die bleibt immer auf 0.

Code: Alles auswählen

                if (dataGroup.i == 0x0001) {
                  if(nutzdata.s[13] == "Türsystem SAT") {tuerstat = 1;}
                  else if (nutzdata.s[13] == "Türsystem TAV") {tuerstat = 2;}
                  else tuerstat = 0;
                }
Oder muss an der Stelle der ASCII-Hexcode abgefragt werden? Oder ist die herangehensweise komplett falsch?
Wie gesagt, wir sind für Impulse offen.

Es grüßt
-Tobi

JonathanPilborough
Beiträge: 351
Registriert: 01.06.2015 14:11:25
Wohnort: BW Schöneweide

Re: Status Türen aus TCP-Protokoll

#4 Beitrag von JonathanPilborough »

Wenn nutzdata.s ein char* mit dem Inhalt ist, dann ist s[13] die vierzehnte byte/Character in diese String. In eine 13 Character String wird das in C immer 0, da nach dem Ende gibt es immer ein 0 um zu zeigen das ein kein Inhalt mehr gibt. Es könnte auch sein, dass bei einer direkt von Zusi stammenden String kein Terminator vorhanden ist. In diesem Fall liegt das vierzehnte Byte außerhalb der String und die Werte ist Zufall.

Für mehr Hintergrund würde ich dir raten, über die Funktion von arrays und "strings"(eigentlich nur byte-arrays) in C zu lesen.

Etwas wie folgendes sollte gehen:

Code: Alles auswählen

#include <string.h>

 if (dataGroup.i == 0x0001) {
    tuerstat = 0;
    if(13 == strlen(nutzdata.s)) //OK nur wenn .s ein 0-Terminator hat - wenn nicht die von Zusi gegebene Große prüfen
    {
        if(0 == strcmp(nutzdata.s[10],"SAT"))
            tuerstat = 1;
        else if(0 == strcmp(nutzdata.s[10],"TAV"))
            tuerstat = 2;          
    }         
}
Hier ist das Problem mit Umlauts vermieden, in dem man die ersten 10 bytes/Characters ignoriert. Wenn mann mit Umlauts umgehen muss, sie sind mit Windows-1252 encodiert, und ja muss mann die richtige HexCode nutzen.

Benutzeravatar
nonesense
Beiträge: 581
Registriert: 15.07.2006 12:50:10
Aktuelle Projekte: QDmi
Fahrpult Einheitsführerstand
Ludmilla
Wohnort: Köln
Kontaktdaten:

Re: Status Türen aus TCP-Protokoll

#5 Beitrag von nonesense »

Versuch es mal so:

Code: Alles auswählen

if (dataGroup.i == 0x0001) {
    if(nutzdata.s[13].indexOf("SAT") >= 0) tuerstat = 1;
    else if (nutzdata.s[13].indexOf("TAV") >=0) tuerstat = 2;
    else tuerstat = 0;
}
Mit indexOf kannst du prüfen, ob ein bestimmter Text innerhalb eines anderen Textes enthalten ist. In dem Fall "SAT" und "TAV". Der Teil "Türsystem" würde hierbei komplett bedeutungslos.
Siehe hier

Benutzeravatar
Johannes
Beiträge: 3491
Registriert: 14.03.2009 22:36:06
Aktuelle Projekte: Zusitools (http://git.io/zusitools)

Re: Status Türen aus TCP-Protokoll

#6 Beitrag von Johannes »

TobiPe hat geschrieben: 04.11.2025 13:05:56

Code: Alles auswählen

if(nutzdata.s[13] == "Türsystem SAT")
Du vergleichst hier zwei Zeiger, nicht den Inhalt zweier Strings. Für Stringvergleiche nimmt man in C z.B. "strncmp", wie die Kollegen schrieben.

Edit: Das gilt für C. Wenn Arduino da was Spezielles macht, dann ist mein Einwand bedeutungslos – dann würde ich auf das Encoding tippen.

Benutzeravatar
F. Schn.
Beiträge: 8015
Registriert: 24.10.2011 18:58:26

Re: Status Türen aus TCP-Protokoll

#7 Beitrag von F. Schn. »

In meinem Originalcode ist der Member nutzdata.s nicht vorhanden gewesen. Um die Aussagen genauer auf die Situation zuschneiden zu können, müsstest du daher die union nutzdata mal posten. Ansonsten sind, wie Johannes schon gesagt hat, C und Strings nicht ganz einfach. Auch ob der Code von nonesense funktioniert, oder welche der von JonathanPilborough aufgelisteten Alternativen zur Längenabfrage nötig sind, hängt entscheidend davon ab, wie die union aufgebaut ist, und wie der Code zwischen den Kommentaren "//ATTRIBUT" und "//AUSWERTUNG" aussieht.
Diese Signatur möchte folgendes bekannter machen: ZusiWiki · ZusiSK: Streckenprojekte · YouTube: Objektbau für Zusi · euirc: Zusi-Chat

TobiPe
Beiträge: 6
Registriert: 01.10.2025 15:30:25
Aktuelle Projekte: Teil des Technik-Teams von tf-ausbildung.de
Handwerkliche und programmier-technische Unterstüzung im privaten Fahrpult-Simulatorbau
Wohnort: Neumünster

Re: Status Türen aus TCP-Protokoll

#8 Beitrag von TobiPe »

Hallo zusammen,

vielen Dank schon mal für die vielen Ideen. Ich werde mir das auf jeden Fall testen, wenn ich wieder an das Fahrpult ran komme.
Die Ideen sind auf den ersten Blick nachvollziehbar. Ich komme ja ursprünglich aus der Automatisierungstechnik, da sind strings auch nicht immer einfach, deshalb habe ich mir schon gedacht, dass an meiner Idee was faul ist.

Aber Einfach wäre ja auch zu langweilig, dann wäre hier ja nichts los. :D

Ich gebe auf jeden Fall Rückmeldung, wenn was geklappt hat oder nicht.

Gruß aus dem Norden
-Tobi

Benutzeravatar
nonesense
Beiträge: 581
Registriert: 15.07.2006 12:50:10
Aktuelle Projekte: QDmi
Fahrpult Einheitsführerstand
Ludmilla
Wohnort: Köln
Kontaktdaten:

Re: Status Türen aus TCP-Protokoll

#9 Beitrag von nonesense »

Wenn du den Code zu Verfügung hast, solltest Du ihn schonmal hier posten, schon bevor du an das Fahrpult kommst. Denn die F.Schns Frage nach der Extrahierung des Strings aus dem TCP-Telegramm ist berechtigt. Über ein Union kann das eigentlich nicht gebildet werden.
Wenn du mit der Klärung dessen wartest, erst bis du ans Pult kommst, lässt du unnötig Zeit verstreichen.

TobiPe
Beiträge: 6
Registriert: 01.10.2025 15:30:25
Aktuelle Projekte: Teil des Technik-Teams von tf-ausbildung.de
Handwerkliche und programmier-technische Unterstüzung im privaten Fahrpult-Simulatorbau
Wohnort: Neumünster

Re: Status Türen aus TCP-Protokoll

#10 Beitrag von TobiPe »

Hallo,

ich kann ja mal den kompletten Code hier Posten:

Code: Alles auswählen

//Einbindung der Bibliotheken
#include <Dhcp.h>
#include <Dns.h>
#include <Ethernet.h>
#include <EthernetClient.h>
#include <EthernetServer.h>
#include <EthernetUdp.h>
#include <SPI.h>
#include <SwitecX25.h>

IPAddress ip(192, 168, 2, 12);                              //IP-Adresse vom Arduino Ethernet Shield
IPAddress server(192, 168, 2, 2);                          //IP-Adresse vom Zusi3-Rechner
byte mac[] = { 0x00, 0x1B, 0xB9, 0x84, 0xCB, 0x58 };           //MAC des Arduinos (fast frei wählbar)

// Byte Serie zum Verbindungsaufbau
uint8_t Anmeldung[] = { 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x2, 0x0, 0x4, 0x0, 0x0, 0x0, 0x2, 0x0, 0x2, 0x0, 0xA, 0x0,
             0x0, 0x0, 0x3, 0x0, 0x46, 0x61, 0x68, 0x72, 0x70, 0x75, 0x6C, 0x74, 0x5, 0x0, 0x0, 0x0, 0x4, 0x0, 0x32, 0x2E, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
            };
// Byte Serie der angeforderten Daten, die der Server senden soll
uint8_t Abfrage[] = { 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0xA, 0x0,
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x2, 0x0,  // Druck Hauptluftleitung
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x3, 0x0,  // Druck Bremszylinder
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x4, 0x0,  // Druck Hauptluftbehälter
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0xf, 0x0,  // Motordrehzahl 1/min
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1a, 0x0, // LM Getriebe
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1b, 0x0, // LM Schleudern
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1e, 0x0, // LM H-Bremse
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x20, 0x0, // LM Hochabbremsung
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x5e, 0x0, // Druck Zeitbehälter
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x64, 0x0, // SIFA
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x66, 0x0, // Türen
                      0xFF, 0xFF, 0xFF, 0xFF,
                      0xFF, 0xFF, 0xFF, 0xFF,
                      0xFF, 0xFF, 0xFF, 0xFF
                    };

EthernetClient client;

union //Datentyp zur Abfrage des Knotens
{
  byte b[4];
  int i;
} dataLng;

union
{
  byte b[2];
  int16_t i;
} dataGroup;

int ebene = 0;
int16_t ebene1Status = 0;
int16_t ebene2Status = 0;
int16_t ebene3Status = 0;
int16_t ebene4Status = 0;
 
int count;// Testvariable für TEST LED blinken
int tuerstat = 0; // Variable für Status Türsystem
int tuerfrgb = 0; // Variable für Ausstiegsseite

//Festlegung der PINs als Variable

int lmwsss = 22;
int lmslgl = 23;
int lmgest = 24;
int lmvm40 = 25;
int lmmost = 26;
int lmv130 = 27;
int lmsifa = 28;
int lmdynb = 29;
int lmhabr = 30;
int lmzev0 = 31;
int lmttav = 32;
int lmtsat = 33;

// LED blink initalisieren
int ledState = LOW;
unsigned long previousMillis = 0;
const long interval = 500;

union
{
  byte b[4];
  float f;
  int i;
  int16_t i16;
  char s[13];
} nutzdata;

#define MAX_NUTZDATA 4

uint8_t clientForceRead()
{
  while (!client.available()) {}
  return client.read();
}

SwitecX25 motorHL(315*3, 2,3,5,6);
SwitecX25 motorHBL(315*3, 8,9,11,12);
SwitecX25 motorC(315*3, 42,44,46,48);
SwitecX25 motorOL(315*3, 43,45,47,49);

int val = 0;

//Start
void setup() {
 // Aus und Eingänge festlegen
 pinMode(lmwsss, OUTPUT); //Ausgang LM Wende- u. Stufenschaltstörung
 pinMode(lmslgl, OUTPUT); //Ausgang LM Schleudern/Gleiten
 pinMode(lmgest, OUTPUT); //Ausgang LM Getriebestörung
 pinMode(lmvm40, OUTPUT); //Ausgang LM Vmax 40
 pinMode(lmmost, OUTPUT); //Ausgang LM Motorstörung
 pinMode(lmv130, OUTPUT); //Ausgang LM Vmax 130
 pinMode(lmsifa, OUTPUT); //Ausgang LM Sifa
 pinMode(lmdynb, OUTPUT); //Ausgang LM H-Bremse
 pinMode(lmhabr, OUTPUT); //Ausgang LM Hochabbremsung
 pinMode(lmzev0, OUTPUT); //Ausgang LM Heizung aus
 pinMode(lmttav, OUTPUT); //Ausgang LM TAV
 pinMode(lmtsat, OUTPUT); //Ausgang LM SAT

 //Netzwerk und serielle Verbindung aufbauen
 Ethernet.begin(mac, ip);                 // Zuordnung von IP und MAC an das Shield
 Serial.begin(115200);                    // serielle Schnittstelle am USB Anschluss für Debugging

 while (!Serial) {
  ;                                       // auf die serielle Schnittstelle warten
 }

 delay(1000);                             // Zeit, dass sich das Ethernet Shield initialisiert (1000ms)
 Serial.println("verbinden...");          // Meldung an den seriellen Monitor

 if (client.connect(server, 1436)) {      // Sobald die Verbindung steht erfolgt die Meldung auf den Monitor
  Serial.println("Verbunden!");           // Meldung verbunden
  Serial.println(ip);                     // ip Client (PC) auf dem Monitor ausgeben
  Serial.println(server);                 // ip Server (Zusi3) auf dem Monitor ausgeben
 }
 else {
  Serial.println("Verbindung Fehlgeschlagen");               // Falls die Verbindung nicht klappt erfolgt die Meldung auf den Monitor
 }

 // Byte Serien zum Zusi Server schreiben
 client.write (Anmeldung, 59);
 client.write (Abfrage, 118);              // *** Vorsicht !!! *** Muss der tatsaechlichen Anzahl von Bytes in der Serie "Abfrage" s.o. entsprechen

 // Schrittmotoren Auf 0 setzen
 motorHL.zero();
 motorHBL.zero();
 motorC.zero();
 motorOL.zero();
 motorHL.setPosition(0);
 motorHBL.setPosition(0);
 motorC.setPosition(0);
 motorOL.setPosition(0);

}

void(* resetFunc) (void) = 0;              // Reset Funktion war nur für einen Test gedacht, wird nicht benötigt




//Endlosschleife
void loop() {
  // put your main code here, to run repeatedly:
 if (client.available()) {
 
   dataLng.b[0] = clientForceRead();
   dataLng.b[1] = clientForceRead();
   dataLng.b[2] = clientForceRead();
   dataLng.b[3] = clientForceRead();
   motorHL.update();
   motorHBL.update();
   motorC.update();
   motorOL.update();   

   
   if (dataLng.i == 0) { //BEGINN KNOTEN
      ebene++;
      dataGroup.b[0] = clientForceRead();
      dataGroup.b[1] = clientForceRead();
      if (ebene == 1) {
         ebene1Status = dataGroup.i;
      } else if (ebene == 2) {
         ebene2Status = dataGroup.i;
      } else if (ebene == 3) {
         ebene3Status = dataGroup.i;
      } else if (ebene == 4) {
         ebene4Status = dataGroup.i;
      }
     
   } else if (dataLng.i == -1) { //ENDE KNOTEN
      ebene--;
     
      if (ebene < 0) { //AUSNAHMEFEHLER: Sollte nicht auftreten, Hilfsweise Arduino neustarten
        resetFunc ();
      }
   } else if (dataLng.i == 1)  { //AUSNAHMEFEHLER: Sollte nicht auftreten, Hilfsweise Arduino neustarten
        resetFunc ();
     
   } else { //ATTRIBUT
      dataGroup.b[0] = clientForceRead();
      dataGroup.b[1] = clientForceRead();
      nutzdata.i = 0;                           //Löschen der Nutzdaten Variable
      for(int i = 0; i < dataLng.i - 2; i++) {  //Schleife zum Auslesen der Nutzdaten
         byte b = clientForceRead();               
         if (i < MAX_NUTZDATA) {
            nutzdata.b[i] = b;
         }
      }
     
      //AUSWERTUNG
      if ((ebene >= 1) && (ebene1Status == 0x0001)) { //VERBINDUNGSAUFBAU
      } else if ((ebene >= 1) && (ebene1Status == 0x0002)) { //FAHRPULT
         if ((ebene >= 2) && (ebene2Status == 0x000A)) { //FST-DATA
            if ((ebene >= 3) && (ebene3Status == 0x0022)) { //NBÜ-DATA
            } else if ((ebene >= 3) && (ebene3Status == 0x0064)) { //SIFA
               if (ebene == 3) {
                  if (dataGroup.i == 0x0002) { // Status Sifa-Leuchtmelder
                     if (nutzdata.b[0] == 1) {digitalWrite(lmsifa, HIGH);}    //SIFA Leuchtmelder einschalten
                     if (nutzdata.b[0] == 0) {digitalWrite(lmsifa, LOW);}     //SIFA Leuchtmelder ausschalten
                  } 
               }
            } else if ((ebene >= 3) && (ebene3Status == 0x0066)) { //Türsystem
              if (dataGroup.i == 0x0001) {
                  if(nutzdata.s[13] == "Türsystem SAT") {tuerstat = 1;}
                  else if (nutzdata.s[13] == "Türsystem TAV") {tuerstat = 2;}
                  else tuerstat = 0;
              } else if (dataGroup.i == 0x0005) {
                  if(nutzdata.b[0] == 0) {tuerfrgb = 0;}
                  if(nutzdata.b[0] == 1) {tuerfrgb = 1;}
                  if(nutzdata.b[0] == 2) {tuerfrgb = 2;}
                  if(nutzdata.b[0] == 3) {tuerfrgb = 3;}
              } else if (dataGroup.i == 0x0006) {
                  if((nutzdata.f > 0.5) && (tuerstat == 1) && (tuerfrgb = 1)) {analogWrite(lmtsat, HIGH);}
                  if((nutzdata.f <= 0.5) && (tuerstat == 1) && (tuerfrgb = 1)) {analogWrite(lmtsat, LOW);}
              } else if (dataGroup.i == 0x0007) {
                  if((nutzdata.f > 0.5) && (tuerstat == 1) && (tuerfrgb = 2)) {analogWrite(lmtsat, HIGH);}
                  if((nutzdata.f <= 0.5) && (tuerstat == 1) && (tuerfrgb = 2)) {analogWrite(lmtsat, LOW);}
              } else if (dataGroup.i == 0x000C) {
                  if((nutzdata.f > 0.5) && (tuerstat == 1) && (tuerfrgb = 3)) {analogWrite(lmtsat, HIGH);}
                  if((nutzdata.f <= 0.5) && (tuerstat == 1) && (tuerfrgb = 3)) {analogWrite(lmtsat, LOW);}
              } else if (dataGroup.i == 0x0013) {
                  if((nutzdata.b[0] == 0) && (tuerstat == 2)) {analogWrite(lmttav, LOW);}
                  if((nutzdata.b[0] == 1) && (tuerstat == 2)) {analogWrite(lmttav, HIGH);}
                  if((nutzdata.b[0] == 2) && (tuerstat == 2) && (ledState == HIGH)) {analogWrite(lmttav, HIGH);}
              }
            } if (ebene == 2) {
               if (dataGroup.i == 0x0002) {   // Hauptluftleitung in bar
                  float HLDruck = nutzdata.f;
                  int hlstep;
                  if (HLDruck <= 0) {hlstep = 0;}
                  else if (HLDruck <= 1) {hlstep = roundf(HLDruck / 1 * 64);}
                  else if (HLDruck <= 2) {hlstep = roundf(64 + (HLDruck - 1) / 1 * 81);}
                  else if (HLDruck <= 3) {hlstep = roundf(145 + (HLDruck - 2) / 1 * 84);}
                  else if (HLDruck <= 4) {hlstep = roundf(229 + (HLDruck - 3) / 1 * 81);}
                  else if (HLDruck <= 5) {hlstep = roundf(310 + (HLDruck - 4) / 1 * 84);}
                  else if (HLDruck <= 6) {hlstep = roundf(394 + (HLDruck - 5) / 1 * 81);}
                  else if (HLDruck <= 8) {hlstep = roundf(475 + (HLDruck - 6) / 2 * 168);}
                  else if (HLDruck <= 10) {hlstep = roundf(643 + (HLDruck - 8) / 2 * 162);}
                  else if (HLDruck > 10) {hlstep = 700;}
                  motorHL.setPosition(hlstep);
                  // Serial.println(HLDruck);
                  // Serial.println(hlstep);
               }  if (dataGroup.i == 0x0003) {          // Bremszylinderdruck in bar
                  float CDruck = nutzdata.f;
                  int cstep;
                  if (CDruck <= 0) {cstep = 0;}
                  else if (CDruck <= 1) {cstep = roundf(CDruck / 1 * 57);}
                  else if (CDruck <= 4) {cstep = roundf(57 + (CDruck - 1) / 3 * 213);}
                  else if (CDruck <= 5) {cstep = roundf(270 + (CDruck - 4) / 1 * 65);}
                  else if (CDruck <= 6) {cstep = roundf(335 + (CDruck - 5) / 1 * 71);}
                  else if (CDruck <= 7) {cstep = roundf(406 + (CDruck - 6) / 1 * 68);}
                  else if (CDruck <= 8) {cstep = roundf(474 + (CDruck - 7) / 1 * 65);}
                  else if (CDruck <= 9) {cstep = roundf(539 + (CDruck - 8) / 1 * 68);}
                  else if (CDruck <= 12) {cstep = roundf(607 + (CDruck - 9) / 3 * 195);}
                  else if (CDruck > 12) {cstep = 850;}
                  motorC.setPosition(cstep);
               } if (dataGroup.i == 0x0004) {   // Hauptluftbehaelter in bar
                  float HBDruck = nutzdata.f;
                  int hbstep;
                  if (HBDruck <= 0) {hbstep = 0;}
                  else if (HBDruck <= 1) {hbstep = roundf(HBDruck / 1 * 57);}
                  else if (HBDruck <= 4) {hbstep = roundf(57 + (HBDruck - 1) / 3 * 213);}
                  else if (HBDruck <= 5) {hbstep = roundf(270 + (HBDruck - 4) / 1 * 65);}
                  else if (HBDruck <= 6) {hbstep = roundf(335 + (HBDruck - 5) / 1 * 71);}
                  else if (HBDruck <= 7) {hbstep = roundf(406 + (HBDruck - 6) / 1 * 68);}
                  else if (HBDruck <= 8) {hbstep = roundf(474 + (HBDruck - 7) / 1 * 65);}
                  else if (HBDruck <= 9) {hbstep = roundf(539 + (HBDruck - 8) / 1 * 68);}
                  else if (HBDruck <= 12) {hbstep = roundf(607 + (HBDruck - 9) / 3 * 195);}
                  else if (HBDruck > 12) {hbstep = 850;}
                  motorHBL.setPosition(hbstep);
               } if (dataGroup.i == 0x000F) {        //Motordrehzahl
                  float RPM = nutzdata.f;
                  if (RPM <= 200) {digitalWrite(lmv130, HIGH);}
                  else if (RPM > 200) {digitalWrite(lmv130, LOW);}
               } if (dataGroup.i == 0x001A) {        // Leuchtmelder Getriebe
                  if(nutzdata.f > 0.5) {digitalWrite(lmgest, HIGH);}
                  else {digitalWrite(lmgest, LOW);}
               } if (dataGroup.i == 0x001B) {        // Leuchtmelder Schleudern
                  if(nutzdata.f > 0.5) {digitalWrite(lmslgl, HIGH);}
                  else {digitalWrite(lmslgl, LOW);}
               } if (dataGroup.i == 0x001E) {        // Leuchtmelder H-Bremse (aktuell ohne weitere Auswertung)
                  if(nutzdata.f > 0.5) {digitalWrite(lmdynb, HIGH);}
                  else {digitalWrite(lmdynb, LOW);}
               } if (dataGroup.i == 0x0020) {        // Leuchtmelder Hochabbremsung
                  if(nutzdata.f > 0.5) {digitalWrite(lmhabr, HIGH);}
                  else {digitalWrite(lmhabr, LOW);}
               } if (dataGroup.i == 0x005E) {        // Anzeige Zeitbehälter
                  float OLDruck = nutzdata.f;
                  int olstep;
                  if (OLDruck <= 0) {olstep = 0;}
                  else if (OLDruck <= 0.1) {olstep = roundf(OLDruck / 0.1 * 35);}
                  else if (OLDruck <= 0.8) {olstep = roundf(35 + (OLDruck - 0.1) / 0.7 * 371);}
                  else if (OLDruck <= 1.6) {olstep = roundf(406 + (OLDruck - 0.8) / 0.8 * 400);}
                  else if (OLDruck > 1.6) {olstep = 866;}
                  motorOL.setPosition(olstep);
               }  
            }
         }
      }
   }
 }
  

 // wenn der Server getrennt wird, stoppt der Client und gibt seriell eine Meldung ab:
 if (!client.connected()) {
  Serial.println();
  Serial.println("Verbindung abgebrochen");
  client.stop();
  // mache nichts: warte 29s
  delay(29000);
  resetFunc ();
 }  
}

Die Änderungen habe ich jetzt noch nicht eingepflegt.
Aber ich denke es hilft, einmal das Gesamtbild zu zeigen.

Gruß aus dem Norden
-Tobi

Benutzeravatar
F. Schn.
Beiträge: 8015
Registriert: 24.10.2011 18:58:26

Re: Status Türen aus TCP-Protokoll

#11 Beitrag von F. Schn. »

char s[13]; wird nur die ersten 4 Bytes belegen, da du MAX_NUTZDATA weiterhin auf 4 gesetzt hast.
Die oberen 0 Bytes von s werden nicht auf 0 gesetzt.
Du hast keine Null-Terminierung, sondern ein String mit einer char-Länge von dataLng.i - 2. (Nicht zu verwechseln mit der Zeichenlänge, die nicht so einfach definiert werden kann.)
Der String ist Aufgrund des Zusi-Protokolles ANSI. Welche Codierung ein "Testülmlaut"-String in C hat, ist schwer bis nicht vorherzusehen.
Im übrigen gilt damit im Wesentlichen die Aussage von JonathanPilborough.

Ich würde es in Anlehnung an die Vorschläge oben daher so vorschlagen (ohne jetzt probiert zu haben, ob es geht):

Code: Alles auswählen

union
{
  byte b[13+1];
  float f;
  int i;
  int16_t i16;
} nutzdata;

#define MAX_NUTZDATA 13

Code: Alles auswählen

   } else { //ATTRIBUT
      dataGroup.b[0] = clientForceRead();
      dataGroup.b[1] = clientForceRead();
      for(int i = 0; i < MAX_NUTZDATA + 1; i++) {  //Löschen der Nutzdaten Variable
         nutzdata.b[i] = 0;              
      }
      for(int i = 0; i < dataLng.i - 2; i++) {  //Schleife zum Auslesen der Nutzdaten
         byte b = clientForceRead();               
         if (i < MAX_NUTZDATA) {
            nutzdata.b[i] = b;
         }
      }
     
      //AUSWERTUNG

Code: Alles auswählen

            } else if ((ebene >= 3) && (ebene3Status == 0x0066)) { //Türsystem
              if (dataGroup.i == 0x0001) {
                  if(13 != dataLng.i - 2) {tuerstat = 0;}
                  else if (0 == strcmp(nutzdata.b[10],"SAT")) {tuerstat = 1;}
                  else if (0 == strcmp(nutzdata.s[10],"TAV")) {tuerstat = 2;}
                  else tuerstat = 0;
              } else if (dataGroup.i == 0x0005) {
Diese Signatur möchte folgendes bekannter machen: ZusiWiki · ZusiSK: Streckenprojekte · YouTube: Objektbau für Zusi · euirc: Zusi-Chat

TobiPe
Beiträge: 6
Registriert: 01.10.2025 15:30:25
Aktuelle Projekte: Teil des Technik-Teams von tf-ausbildung.de
Handwerkliche und programmier-technische Unterstüzung im privaten Fahrpult-Simulatorbau
Wohnort: Neumünster

Re: Status Türen aus TCP-Protokoll

#12 Beitrag von TobiPe »

Hallo in die Runde,

ich bin jetzt am Pult. Da habe ich jetzt mal den letzten Vorschlag von F. Schn. umgesetzt. Da passiert nun gar nichts mehr bei SAT und TAV.

Hier zum nachvollziehen der komplette Code:

Code: Alles auswählen

//Einbindung der Bibliotheken
#include <Dhcp.h>
#include <Dns.h>
#include <Ethernet.h>
#include <EthernetClient.h>
#include <EthernetServer.h>
#include <EthernetUdp.h>
#include <SPI.h>
#include <SwitecX25.h>

IPAddress ip(192, 168, 2, 12);                              //IP-Adresse vom Arduino Ethernet Shield
IPAddress server(192, 168, 2, 2);                          //IP-Adresse vom Zusi3-Rechner
byte mac[] = { 0x00, 0x1B, 0xB9, 0x84, 0xCB, 0x58 };           //MAC des Arduinos (fast frei wählbar)

// Byte Serie zum Verbindungsaufbau
uint8_t Anmeldung[] = { 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x2, 0x0, 0x4, 0x0, 0x0, 0x0, 0x2, 0x0, 0x2, 0x0, 0xA, 0x0,
             0x0, 0x0, 0x3, 0x0, 0x46, 0x61, 0x68, 0x72, 0x70, 0x75, 0x6C, 0x74, 0x5, 0x0, 0x0, 0x0, 0x4, 0x0, 0x32, 0x2E, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
            };
// Byte Serie der angeforderten Daten, die der Server senden soll
uint8_t Abfrage[] = { 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0xA, 0x0,
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x2, 0x0,  // Druck Hauptluftleitung
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x3, 0x0,  // Druck Bremszylinder
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x4, 0x0,  // Druck Hauptluftbehälter
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0xf, 0x0,  // Motordrehzahl 1/min
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1a, 0x0, // LM Getriebe
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1b, 0x0, // LM Schleudern
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1e, 0x0, // LM H-Bremse
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x20, 0x0, // LM Hochabbremsung
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x5e, 0x0, // Druck Zeitbehälter
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x64, 0x0, // SIFA
                      0x4, 0x0, 0x0, 0x0, 0x1, 0x0, 0x66, 0x0, // Türen
                      0xFF, 0xFF, 0xFF, 0xFF,
                      0xFF, 0xFF, 0xFF, 0xFF,
                      0xFF, 0xFF, 0xFF, 0xFF
                    };

EthernetClient client;

union //Datentyp zur Abfrage des Knotens
{
  byte b[4];
  int i;
} dataLng;

union
{
  byte b[2];
  int16_t i;
} dataGroup;

int ebene = 0;
int16_t ebene1Status = 0;
int16_t ebene2Status = 0;
int16_t ebene3Status = 0;
int16_t ebene4Status = 0;
 
int count;// Testvariable für TEST LED blinken
int tuerstat = 0; // Variable für Status Türsystem
int tuerfrgb = 0; // Variable für Ausstiegsseite

//Festlegung der PINs als Variable

int lmwsss = 22;
int lmslgl = 23;
int lmgest = 24;
int lmvm40 = 25;
int lmmost = 26;
int lmv130 = 27;
int lmsifa = 28;
int lmdynb = 29;
int lmhabr = 30;
int lmzev0 = 31;
int lmttav = 32;
int lmtsat = 33;

// LED blink initalisieren
int ledState = LOW;
unsigned long previousMillis = 0;
const long interval = 500;

union
{
  byte b[13+1];
  float f;
  int i;
  int16_t i16;
} nutzdata;

#define MAX_NUTZDATA 13

uint8_t clientForceRead()
{
  while (!client.available()) {}
  return client.read();
}

SwitecX25 motorHL(315*3, 2,3,5,6);
SwitecX25 motorHBL(315*3, 8,9,11,12);
SwitecX25 motorC(315*3, 42,44,46,48);
SwitecX25 motorOL(315*3, 43,45,47,49);

int val = 0;

//Start
void setup() {
 // Aus und Eingänge festlegen
 pinMode(lmwsss, OUTPUT); //Ausgang LM Wende- u. Stufenschaltstörung
 pinMode(lmslgl, OUTPUT); //Ausgang LM Schleudern/Gleiten
 pinMode(lmgest, OUTPUT); //Ausgang LM Getriebestörung
 pinMode(lmvm40, OUTPUT); //Ausgang LM Vmax 40
 pinMode(lmmost, OUTPUT); //Ausgang LM Motorstörung
 pinMode(lmv130, OUTPUT); //Ausgang LM Vmax 130
 pinMode(lmsifa, OUTPUT); //Ausgang LM Sifa
 pinMode(lmdynb, OUTPUT); //Ausgang LM H-Bremse
 pinMode(lmhabr, OUTPUT); //Ausgang LM Hochabbremsung
 pinMode(lmzev0, OUTPUT); //Ausgang LM Heizung aus
 pinMode(lmttav, OUTPUT); //Ausgang LM TAV
 pinMode(lmtsat, OUTPUT); //Ausgang LM SAT

 //Netzwerk und serielle Verbindung aufbauen
 Ethernet.begin(mac, ip);                 // Zuordnung von IP und MAC an das Shield
 Serial.begin(115200);                    // serielle Schnittstelle am USB Anschluss für Debugging

 while (!Serial) {
  ;                                       // auf die serielle Schnittstelle warten
 }

 delay(1000);                             // Zeit, dass sich das Ethernet Shield initialisiert (1000ms)
 Serial.println("verbinden...");          // Meldung an den seriellen Monitor

 if (client.connect(server, 1436)) {      // Sobald die Verbindung steht erfolgt die Meldung auf den Monitor
  Serial.println("Verbunden!");           // Meldung verbunden
  Serial.println(ip);                     // ip Client (PC) auf dem Monitor ausgeben
  Serial.println(server);                 // ip Server (Zusi3) auf dem Monitor ausgeben
 }
 else {
  Serial.println("Verbindung Fehlgeschlagen");               // Falls die Verbindung nicht klappt erfolgt die Meldung auf den Monitor
 }

 // Byte Serien zum Zusi Server schreiben
 client.write (Anmeldung, 59);
 client.write (Abfrage, 118);              // *** Vorsicht !!! *** Muss der tatsaechlichen Anzahl von Bytes in der Serie "Abfrage" s.o. entsprechen

 // Schrittmotoren Auf 0 setzen
 motorHL.zero();
 motorHBL.zero();
 motorC.zero();
 motorOL.zero();
 motorHL.setPosition(0);
 motorHBL.setPosition(0);
 motorC.setPosition(0);
 motorOL.setPosition(0);

}

void(* resetFunc) (void) = 0;              // Reset Funktion war nur für einen Test gedacht, wird nicht benötigt




//Endlosschleife
void loop() {
  // put your main code here, to run repeatedly:
 if (client.available()) {
 
   dataLng.b[0] = clientForceRead();
   dataLng.b[1] = clientForceRead();
   dataLng.b[2] = clientForceRead();
   dataLng.b[3] = clientForceRead();
   motorHL.update();
   motorHBL.update();
   motorC.update();
   motorOL.update();   

   
   if (dataLng.i == 0) { //BEGINN KNOTEN
      ebene++;
      dataGroup.b[0] = clientForceRead();
      dataGroup.b[1] = clientForceRead();
      if (ebene == 1) {
         ebene1Status = dataGroup.i;
      } else if (ebene == 2) {
         ebene2Status = dataGroup.i;
      } else if (ebene == 3) {
         ebene3Status = dataGroup.i;
      } else if (ebene == 4) {
         ebene4Status = dataGroup.i;
      }
     
   } else if (dataLng.i == -1) { //ENDE KNOTEN
      ebene--;
     
      if (ebene < 0) { //AUSNAHMEFEHLER: Sollte nicht auftreten, Hilfsweise Arduino neustarten
        resetFunc ();
      }
   } else if (dataLng.i == 1)  { //AUSNAHMEFEHLER: Sollte nicht auftreten, Hilfsweise Arduino neustarten
        resetFunc ();
     
   } else { //ATTRIBUT
      dataGroup.b[0] = clientForceRead();
      dataGroup.b[1] = clientForceRead();
      for(int i = 0; i < MAX_NUTZDATA + 1; i++) {  //Löschen der Nutzdaten Variable
         nutzdata.b[i] = 0;              
      }
      for(int i = 0; i < dataLng.i - 2; i++) {  //Schleife zum Auslesen der Nutzdaten
         byte b = clientForceRead();               
         if (i < MAX_NUTZDATA) {
            nutzdata.b[i] = b;
         }
      }
     
      //AUSWERTUNG
      if ((ebene >= 1) && (ebene1Status == 0x0001)) { //VERBINDUNGSAUFBAU
      } else if ((ebene >= 1) && (ebene1Status == 0x0002)) { //FAHRPULT
         if ((ebene >= 2) && (ebene2Status == 0x000A)) { //FST-DATA
            if ((ebene >= 3) && (ebene3Status == 0x0022)) { //NBÜ-DATA
            } else if ((ebene >= 3) && (ebene3Status == 0x0064)) { //SIFA
               if (ebene == 3) {
                  if (dataGroup.i == 0x0002) { // Status Sifa-Leuchtmelder
                     if (nutzdata.b[0] == 1) {digitalWrite(lmsifa, HIGH);}    //SIFA Leuchtmelder einschalten
                     if (nutzdata.b[0] == 0) {digitalWrite(lmsifa, LOW);}     //SIFA Leuchtmelder ausschalten
                  } 
               }
            } else if ((ebene >= 3) && (ebene3Status == 0x0066)) { //Türsystem
              if (dataGroup.i == 0x0001) {
                  if(13 != dataLng.i - 2) {tuerstat = 0;}
                  else if (0 == strcmp(nutzdata.b[10],"SAT")) {tuerstat = 1;}
                  else if (0 == strcmp(nutzdata.b[10],"TAV")) {tuerstat = 2;}
                  else tuerstat = 0;
              } else if (dataGroup.i == 0x0005) {
                  if(nutzdata.b[0] == 0) {tuerfrgb = 0;}
                  if(nutzdata.b[0] == 1) {tuerfrgb = 1;}
                  if(nutzdata.b[0] == 2) {tuerfrgb = 2;}
                  if(nutzdata.b[0] == 3) {tuerfrgb = 3;}
              } else if (dataGroup.i == 0x0006) {
                  if((nutzdata.f > 0.5) && (tuerstat == 1) && (tuerfrgb = 1)) {analogWrite(lmtsat, HIGH);}
                  if((nutzdata.f <= 0.5) && (tuerstat == 1) && (tuerfrgb = 1)) {analogWrite(lmtsat, LOW);}
              } else if (dataGroup.i == 0x0007) {
                  if((nutzdata.f > 0.5) && (tuerstat == 1) && (tuerfrgb = 2)) {analogWrite(lmtsat, HIGH);}
                  if((nutzdata.f <= 0.5) && (tuerstat == 1) && (tuerfrgb = 2)) {analogWrite(lmtsat, LOW);}
              } else if (dataGroup.i == 0x000C) {
                  if((nutzdata.f > 0.5) && (tuerstat == 1) && (tuerfrgb = 3)) {analogWrite(lmtsat, HIGH);}
                  if((nutzdata.f <= 0.5) && (tuerstat == 1) && (tuerfrgb = 3)) {analogWrite(lmtsat, LOW);}
              } else if (dataGroup.i == 0x0013) {
                  if((nutzdata.b[0] == 0) && (tuerstat == 2)) {analogWrite(lmttav, LOW);}
                  if((nutzdata.b[0] == 1) && (tuerstat == 2)) {analogWrite(lmttav, HIGH);}
                  if((nutzdata.b[0] == 2) && (tuerstat == 2) && (ledState == HIGH)) {analogWrite(lmttav, HIGH);}
              }
            } if (ebene == 2) {
               if (dataGroup.i == 0x0002) {   // Hauptluftleitung in bar
                  float HLDruck = nutzdata.f;
                  int hlstep;
                  if (HLDruck <= 0) {hlstep = 0;}
                  else if (HLDruck <= 1) {hlstep = roundf(HLDruck / 1 * 64);}
                  else if (HLDruck <= 2) {hlstep = roundf(64 + (HLDruck - 1) / 1 * 81);}
                  else if (HLDruck <= 3) {hlstep = roundf(145 + (HLDruck - 2) / 1 * 84);}
                  else if (HLDruck <= 4) {hlstep = roundf(229 + (HLDruck - 3) / 1 * 81);}
                  else if (HLDruck <= 5) {hlstep = roundf(310 + (HLDruck - 4) / 1 * 84);}
                  else if (HLDruck <= 6) {hlstep = roundf(394 + (HLDruck - 5) / 1 * 81);}
                  else if (HLDruck <= 8) {hlstep = roundf(475 + (HLDruck - 6) / 2 * 168);}
                  else if (HLDruck <= 10) {hlstep = roundf(643 + (HLDruck - 8) / 2 * 162);}
                  else if (HLDruck > 10) {hlstep = 700;}
                  motorHL.setPosition(hlstep);
                  // Serial.println(HLDruck);
                  // Serial.println(hlstep);
               }  if (dataGroup.i == 0x0003) {          // Bremszylinderdruck in bar
                  float CDruck = nutzdata.f;
                  int cstep;
                  if (CDruck <= 0) {cstep = 0;}
                  else if (CDruck <= 1) {cstep = roundf(CDruck / 1 * 57);}
                  else if (CDruck <= 4) {cstep = roundf(57 + (CDruck - 1) / 3 * 213);}
                  else if (CDruck <= 5) {cstep = roundf(270 + (CDruck - 4) / 1 * 65);}
                  else if (CDruck <= 6) {cstep = roundf(335 + (CDruck - 5) / 1 * 71);}
                  else if (CDruck <= 7) {cstep = roundf(406 + (CDruck - 6) / 1 * 68);}
                  else if (CDruck <= 8) {cstep = roundf(474 + (CDruck - 7) / 1 * 65);}
                  else if (CDruck <= 9) {cstep = roundf(539 + (CDruck - 8) / 1 * 68);}
                  else if (CDruck <= 12) {cstep = roundf(607 + (CDruck - 9) / 3 * 195);}
                  else if (CDruck > 12) {cstep = 850;}
                  motorC.setPosition(cstep);
               } if (dataGroup.i == 0x0004) {   // Hauptluftbehaelter in bar
                  float HBDruck = nutzdata.f;
                  int hbstep;
                  if (HBDruck <= 0) {hbstep = 0;}
                  else if (HBDruck <= 1) {hbstep = roundf(HBDruck / 1 * 57);}
                  else if (HBDruck <= 4) {hbstep = roundf(57 + (HBDruck - 1) / 3 * 213);}
                  else if (HBDruck <= 5) {hbstep = roundf(270 + (HBDruck - 4) / 1 * 65);}
                  else if (HBDruck <= 6) {hbstep = roundf(335 + (HBDruck - 5) / 1 * 71);}
                  else if (HBDruck <= 7) {hbstep = roundf(406 + (HBDruck - 6) / 1 * 68);}
                  else if (HBDruck <= 8) {hbstep = roundf(474 + (HBDruck - 7) / 1 * 65);}
                  else if (HBDruck <= 9) {hbstep = roundf(539 + (HBDruck - 8) / 1 * 68);}
                  else if (HBDruck <= 12) {hbstep = roundf(607 + (HBDruck - 9) / 3 * 195);}
                  else if (HBDruck > 12) {hbstep = 850;}
                  motorHBL.setPosition(hbstep);
               } if (dataGroup.i == 0x000F) {        //Motordrehzahl
                  float RPM = nutzdata.f;
                  if (RPM <= 200) {digitalWrite(lmv130, HIGH);}
                  else if (RPM > 200) {digitalWrite(lmv130, LOW);}
               } if (dataGroup.i == 0x001A) {        // Leuchtmelder Getriebe
                  if(nutzdata.f > 0.5) {digitalWrite(lmgest, HIGH);}
                  else {digitalWrite(lmgest, LOW);}
               } if (dataGroup.i == 0x001B) {        // Leuchtmelder Schleudern
                  if(nutzdata.f > 0.5) {digitalWrite(lmslgl, HIGH);}
                  else {digitalWrite(lmslgl, LOW);}
               } if (dataGroup.i == 0x001E) {        // Leuchtmelder H-Bremse (aktuell ohne weitere Auswertung)
                  if(nutzdata.f > 0.5) {digitalWrite(lmdynb, HIGH);}
                  else {digitalWrite(lmdynb, LOW);}
               } if (dataGroup.i == 0x0020) {        // Leuchtmelder Hochabbremsung
                  if(nutzdata.f > 0.5) {digitalWrite(lmhabr, HIGH);}
                  else {digitalWrite(lmhabr, LOW);}
               } if (dataGroup.i == 0x005E) {        // Anzeige Zeitbehälter
                  float OLDruck = nutzdata.f;
                  int olstep;
                  if (OLDruck <= 0) {olstep = 0;}
                  else if (OLDruck <= 0.1) {olstep = roundf(OLDruck / 0.1 * 35);}
                  else if (OLDruck <= 0.8) {olstep = roundf(35 + (OLDruck - 0.1) / 0.7 * 371);}
                  else if (OLDruck <= 1.6) {olstep = roundf(406 + (OLDruck - 0.8) / 0.8 * 400);}
                  else if (OLDruck > 1.6) {olstep = 866;}
                  motorOL.setPosition(olstep);
               }  
            }
         }
      }
   }
 }
  

 // wenn der Server getrennt wird, stoppt der Client und gibt seriell eine Meldung ab:
 if (!client.connected()) {
  Serial.println();
  Serial.println("Verbindung abgebrochen");
  client.stop();
  // mache nichts: warte 29s
  delay(29000);
  resetFunc ();
 }  
}
Ich bin auf weitere Ideen gespannt.

Gruß aus dem Nordem

-Tobi

Benutzeravatar
F. Schn.
Beiträge: 8015
Registriert: 24.10.2011 18:58:26

Re: Status Türen aus TCP-Protokoll

#13 Beitrag von F. Schn. »

TobiPe hat geschrieben: 07.11.2025 13:30:10 Ich bin auf weitere Ideen gespannt.
Naja, jetzt erst mal das übliche: Was bedeutet "gar nix", eine Debug-Ausgabe (im Extremfall eine Debug-LED) verwenden, um festzustellen, welchen Wert tuerstat hat; darüber nachdenken, welchen Wert du für tuerstat bei deinem Zug erwartest; wenn tuerstat 0 ist, du aber einen anderen Wert erwartest, prüfen, ob der Code überhaupt aufgerufen wurde (ob der Code den If-Block (dataGroup.i == 0x0002) überhaupt je betreten hat); prüfen, wie lange dataLng.i - 2 bei deinem Zug tatsächlich ist, und welche Länge du eigentlich erwartest; prüfen, welchen wert strcmp ausgibt.

PS: Und wenn es am strcmp liegt, würde ich noch mal in die Doku schauen, ob man nutzdata.b[10] wirklich ohne & an strcmp übergeben kann. Das habe ich jetzt "blind" von Jonathan abgeschrieben.
Diese Signatur möchte folgendes bekannter machen: ZusiWiki · ZusiSK: Streckenprojekte · YouTube: Objektbau für Zusi · euirc: Zusi-Chat

Antworten