Seite 1 von 1

Rotorsteuerung Datenübergabe

Verfasst: Samstag 4. Oktober 2025, 12:30
von DK6WT
Hallo,
leider habe ich im Forum und in der Hilfe keine Antworten gefunden.
Gibt es eine Möglichkeit die AZ Richtung in Windows auszugeben, z.b. über UDP. Wäre eine schöne Sache.
Dann müsste auch nicht jede neue Rotorsteuerung da reinprogrammiert werden sondern die Hersteller
könnten die Daten von dort abgreifen.
Zum Hintergrund ich habe mir eine Rotorsteuerung gebaut und suche eine Möglichkeit die Daten UCXLog zu
entlocken.
Für N1MM habe ich es hinbekommen dort werden die Daten als XML über UDP ausgegeben (Port 12040).
Muss kein XML sein ein "AZ=034" über UDP wenn "Setze Rotor" gedrückt wird oder so würde reichen.... :-)
Für UCXLog habe ich hier leider nichts gefunden.
Aber vielleicht gibt es ja auch eine andere Möglichkeit ?

73, Stefan,DK6WT

Re: Rotorsteuerung Datenübergabe

Verfasst: Samstag 4. Oktober 2025, 19:51
von DL7UCX
Hallo Stefan,

die Ausgabe über UDP ist eine proprietäre N1MM interne Lösung nur zur Steuerung von "N1MM Rotor".

Ich kenne keinen Hersteller, der das verwendet. Die meisten nutzen ein COM-Port.
Bisher hat niemand sonst so eine UDP-Ausgabe gebraucht.

Ich überdenke mal, ob ich etwas ähnliches einbauen könnte ...

73 Ben

Re: Rotorsteuerung Datenübergabe

Verfasst: Sonntag 5. Oktober 2025, 16:33
von DL7UCX
Noch eine Frage:
Soll die UDP-Ausgabe wie bei anderen Rotoren nur beim Drücken auf den Knopf "Setze Rotor" erfolgen ?

73 Ben

Re: Rotorsteuerung Datenübergabe

Verfasst: Sonntag 5. Oktober 2025, 18:36
von DK6WT
Hallo,
vielen Dank für die Antworten.
Ja ich denke so wäre es am geschicktesten das die Daten bei Drücken des "Setze Rotor" Buttons als UDP rausgehen
würden.

Ich hatte nochmal nachgeschaut und DXLog bietet auch diese Funktion auch auf UDP Port 12040.
Für Ham Oficce habe ich leider nichts gefunden.
Aber ich finde die Idee smart wenn man hier eine Schnittstelle hat auf die über den Rechner zugegriffen werden
kann. Noch werden ja externe Steuergeräte eingesetzt über RS232 oder ähnliche Schnittstellen aber ich kann mir vorstellen,
das das in Zukunft über Ethernet und einer Software zu dem eigentlichen Rotor kommuniziert wird.
Bei Transceiver geht es ja auch in diese Richtung... die können ja teilweise auch nicht mehr ohne Rechner bedient werden.

Dann noch einen schönen Rest-Sonntag.
73, Stefan, DK6WT

Re: Rotorsteuerung Datenübergabe

Verfasst: Dienstag 7. Oktober 2025, 10:06
von DL7UCX
Hallo Stefan,

in Version 8.47 Beta 1 (uploaded) gibt es bei
Settings - Station - Other interfaces - Rotor control die neue Auswahl "UDP Port 12040".

Hilfe:
Rotor
...
"UDP Port 12040" gibt bei jedem Klick auf "Setze Rotor" (s.Haupt-Fenster) eine UDP-Message an 127.0.0.1 Port 12040 aus.
Bsp.:
<?xml version="1.0" encoding="utf-8"?>
<Rotor>
<app>UcxLog</app>
<Azimut>306</Azimut>
</Rotor>

Wenn aktuell keine Richtung angezeigt wird, fehlt die Zahl nach "Azimut".
73 Ben

Re: Rotorsteuerung Datenübergabe

Verfasst: Mittwoch 8. Oktober 2025, 11:43
von DK6WT
Hallo,
vielen lieben Dank funktioniert hervorragend !!!

Hier mein Code in C# falls es jemanden nützlich sein kann wie die Daten empfangen und ausgewertet
werden. Ich habe die Tele für N1MM und EA4TX/DXLog Format mit dran gelassen sonnst verseht es keiner.

private void StartUdpListener()
{
udpClient = new UdpClient(Int32.Parse(textBox3.Text)); // Port aus Textbox
udpListening = true;
udpListenerThread = new Thread(new ThreadStart(ListenForUdpMessages));
udpListenerThread.IsBackground = true;
udpListenerThread.Start();
}

private void ListenForUdpMessages()
{
string logText = "";

// Thread-sicher den aktuell gewählten Logprogramm-Text holen
this.Invoke((MethodInvoker)(() =>
{
logText = comboBoxLogProgramm.Text;
}));

IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);

// Auswahl, welches Logformat aktiv ist
switch (logText)
{
case "UCXLog / N1MM / EA4TX":
while (udpListening)
{
try
{
byte[] data = udpClient.Receive(ref remoteEP);
string xmlString = Encoding.UTF8.GetString(data);

// Automatisch erkennen, welches Log gesendet hat
if (xmlString.Contains("<N1MMRotor>"))
{
ParseN1mmRotor(xmlString);
}
else if (xmlString.Contains("<Rotor>") && xmlString.Contains("<app>UcxLog</app>"))
{
ParseUcxLogRotor(xmlString);
}
else if (xmlString.Contains("<EA4TX>"))
{
ParseEa4txRotor(xmlString);
}
}
catch (Exception ex)
{
Console.WriteLine("UDP Error: " + ex.Message);
}
}
break;

case "N1MM":
while (udpListening)
{
try
{
byte[] data = udpClient.Receive(ref remoteEP);
string xmlString = Encoding.UTF8.GetString(data);
if (xmlString.Contains("<N1MMRotor>"))
ParseN1mmRotor(xmlString);
}
catch (Exception ex)
{
Console.WriteLine("UDP Error (N1MM): " + ex.Message);
}
}
break;

case "UCXLog":
while (udpListening)
{
try
{
byte[] data = udpClient.Receive(ref remoteEP);
string xmlString = Encoding.UTF8.GetString(data);
if (xmlString.Contains("<Rotor>") && xmlString.Contains("<app>UcxLog</app>"))
ParseUcxLogRotor(xmlString);
}
catch (Exception ex)
{
Console.WriteLine("UDP Error (UCXLog): " + ex.Message);
}
}
break;

case "EA4TX / DXLog":
while (udpListening)
{
try
{
byte[] data = udpClient.Receive(ref remoteEP);
string xmlString = Encoding.UTF8.GetString(data);
if (xmlString.Contains("<EA4TX>"))
ParseEa4txRotor(xmlString);
}
catch (Exception ex)
{
Console.WriteLine("UDP Error (EA4TX): " + ex.Message);
}
}
break;

default:
Console.WriteLine("Unbekanntes Logformat ausgewählt: " + logText);
break;
}
}

private void ParseN1mmRotor(string xml)
{
try
{
XDocument doc = XDocument.Parse(xml);
var goaziElement = doc.Descendants("goazi").FirstOrDefault();
if (goaziElement != null)
{
double az = double.Parse(goaziElement.Value, System.Globalization.CultureInfo.InvariantCulture);
this.Invoke((MethodInvoker)delegate
{
tBoxDataIN3.Text = "Azimuth: " + az.ToString("F1") + "° (N1MM)";
SetRotor(true, az.ToString("F1"));
rotorDial.Update();
});
}
}
catch (Exception ex)
{
Console.WriteLine("XML Parse Error (N1MM): " + ex.Message);
}
}

private void ParseUcxLogRotor(string xml)
{
try
{
XDocument doc = XDocument.Parse(xml);
var azimutElement = doc.Descendants("Azimut").FirstOrDefault();
if (azimutElement != null)
{
double az = double.Parse(azimutElement.Value, System.Globalization.CultureInfo.InvariantCulture);
this.Invoke((MethodInvoker)delegate
{
tBoxDataIN3.Text = "Azimuth: " + az.ToString("F1") + "° (UCXLog)";
SetRotor(true, az.ToString("F1"));
rotorDial.Update();
});
}
else
{
Console.WriteLine("UCXLog: Kein Azimut-Wert empfangen");
}
}
catch (Exception ex)
{
Console.WriteLine("XML Parse Error (UCXLog): " + ex.Message);
}
}

private void ParseEa4txRotor(string xml)
{
try
{
XDocument doc = XDocument.Parse(xml);
var azimuthElement = doc.Descendants("AZIMUTH").FirstOrDefault();
if (azimuthElement != null)
{
double az = double.Parse(azimuthElement.Value, System.Globalization.CultureInfo.InvariantCulture);
this.Invoke((MethodInvoker)delegate
{
tBoxDataIN3.Text = "Azimuth: " + az.ToString("F1") + "° (DXLog / EA4TX)";
SetRotor(true, az.ToString("F1"));
rotorDial.Update();
});
}
}
catch (Exception ex)
{
Console.WriteLine("XML Parse Error (EA4TX/DXLog): " + ex.Message);
}
}

Nochmals vielen vielen Dank für die tolle und sehr schnelle Unterstützung.
Da kann der nächste Contest kommen :-)

73, Stefan, DK6WT