Einführung in Kommunikation mit seriellem Gerät und .dll

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 33 Antworten in diesem Thema. Der letzte Beitrag () ist von Eddolino.

    Einführung in Kommunikation mit seriellem Gerät und .dll

    Hallo Freunde,

    also ich habe mich hier angemeldet weil ich nicht genau weiß wo ich anfangen soll.

    Ich habe ein Ultraschall Gerät, welches über USB (Seriell) kommuniziert. Mit dem Gerät wird eine .dll mitgeliefert, mit welcher man mit dem Gerät interagieren soll.
    (und eine kleine Anleitung mit Beispielen für C#).

    Das größte was ich bisher programmiert habe war mit Robotern und SPS (also grundlegende Pascal Geschichten) (und noch etwas homeassistant und javascript aber da muss man ja nicht viel machen).

    Also prinzipiell habe ich keine Ahnung wie ich mit VB.NET umgehe bzw. etwas erstelle, was dann mit meiner Sonde interagiert.

    Mein Ziel ist es, mit dem Gerät zu kommunizieren (also Parameter an das Gerät und Messergebnisse laufend zurück).
    Ich würde das über eine GUI Steuern. Die Messergebnisse sollen dann an eine InfluxDB gesendet werden.

    Jetzt habe ich folgende relevante Ausschnitte aus der DLL Dokumentation:

    RegisterCallback
    If realtime data is required then pass in a call back function to the DLL that is called each time a new set of data values are received. To do this, use the

    Quellcode

    1. public void RegisterCallback(DataReceived callback)


    OpenSerialConnection
    To begin communicating to the connected instrument call this function providing it with the COM port number that the instrument is connected to:

    Quellcode

    1. public bool OpenSerialConnection(Int32 com_port_number)


    CloseSerialConnection
    Closes the serial port.

    Quellcode

    1. public void CloseSerialConnection()


    ETherRealtimeClass
    The constructor of the class. This is called on creation of the object. There are 2 versions depending on whether the DLL is to handle memory management or the calling application. The variable data_type must be one of the following values:
    public const int REALTIME_DATA_RAW = 0x40;
    public const int REALTIME_DATA_POSTPROCESS = 0x50;
    public const int SINGLE_CHAN_POST = 0x70;
    public const int CONDUCTIVITY = 0x90;
    The call if the application is handling and creating memory:

    Quellcode

    1. public ETherRealtimeClass(Int32[][] x1, Int32[][] y1, Int32[][] x2, Int32[][] y2, Int32[][] xMix, Int32[][] yMix, , Int32 arrays, Int32 size_of_arrays, Int32 data_type)


    WriteToInstrument
    This allows commands to be sent directly to the Instrument and not interfered to by the DLL.The downside is that the command must be thoroughly understood and formatted correctly, so use at your peril!If the Port is Closed then FALSE is returned.

    Quellcode

    1. public bool WriteToInstrument(byte first_byte, byte second_byte, string command)




    Versteht einer von euch den Ablauf von der Kommunikation?


    Ich denke folgendes bzw am Ende nochmal ein ganzer Code von mir (aber das funktioniert nicht) :
    1. Ich baue über OpenSerialConnection eine Verbindung mit dem Gerät auf.
    (Ich glaube das ist geschenkt also einfach z.b. in einem Button den Befehl mit dem Com-Port in Klammern)

    2. Ich erhalte irgendwie Daten von dem Gerät ?
    Es gibt die Funktion RegisterDataCallback (aber das ist in der Dokumentation garnicht erwähnt sondern kann ich die nur in der DLL sehen).

    Also wenn ich eine Variable deklariere als EtherRealtimeClass.DataReceived dann kann ich die als Parameter in meiner Callback Funktion verwenden.
    Aber wie komme ich dann an x1 und y1 ran (das sind meine relevanten werte, die werden auch oben in der etherrealtimeclass deklariert und sind auch in der DataReceived drin)?

    Außerdem müsste man laut der Dokumentation dem Gerät die Art der Daten sagen, welche es kommunizieren soll. In meinem Fall wäre das immer der Single_CHAN_POST bzw. 0x70.

    Also folgendes habe ich jetzt:

    VB.NET-Quellcode

    1. Imports ETherCheckDataAcq
    2. Public Class Form1
    3. Public Ether As ETherCheckDataAcq.ETherRealtimeClass
    4. Public Measurements As ETherCheckDataAcq.ETherRealtimeClass.DataReceived
    5. Public Sub btnConnect_Click(sender As Object, e As EventArgs) Handles btnConnect.Click
    6. Ether.RegisterDataCallback(Measurements)
    7. Ether.OpenSerialConnection(4)
    8. End Sub
    9. End Class



    Aber hier weiß ich jetzt nichtmehr weiter. Theoretisch brauche ich x1 und y1 von meiner Measurements Variable, allerdings komme ich da nicht ran.
    Wenn ich Measurements als Sub definiere bekomme ich auch nur Fehlermeldungen.




    Weiter besteht dann die Frage, wie ich Werte an das Gerät sende.
    Theoretisch müsste das ja sein:
    public bool WriteToInstrument(byte first_byte, byte second_byte, string command)

    Kann ich jetzt die beiden Bytes am Anfang einfach als Wert eintragen?
    Also laut einer zweiten Doku muss der first_byte immer 0x01 sein, reicht es wenn ich hier 1 schreibe? (ist das überhaupt richtig?)
    und folgemäßig 0 wenn das second_byte 0x00 sein soll?

    Also dann müsste folgendes funktionieren oder? (das teste ich gleich):

    VB.NET-Quellcode

    1. Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
    2. Ether.WriteToInstrument(1, 0, "<FREQUENCY>" & txtFrequency.Text & "</FREQUENCY>")
    3. End Sub



    Das Beispiel in C# vom Entwickler ist folgendes:

    C#-Quellcode

    1. using ETherCheckDataAcq;
    2. namespace test_app
    3. {
    4. public partial class Form1 : Form
    5. {
    6. ETherRealtimeClass ether;
    7. public Form1()
    8. {
    9. ether = new ETherRealtimeClass(0, 0x70);
    10. InitializeComponent();
    11. ether.RegisterDataCallback(NewRealtimeData);
    12. ether.RegisterFileCallback(NewFileData);
    13. ether.RegisterProgressCallback(ProgressBarValue);
    14. bool result = ether.OpenSerialConnection(32);
    15. }
    16. public void NewRealtimeData(Int32 X1, Int32 Y1, Int32 X2, Int32 Y2, Int32 Xmix_or_percent, Int32 Ymix_or_percent, Int32 Theta_or_status_X, Int32 Radius_or_status_Y)
    17. {
    18. int ian = X1;
    19. }
    20. public void NewFileData(string full_filename)
    21. {
    22. //A new file has been received by the DLL. The provided value is the full path of
    23. // where this file is.
    24. }
    25. public void ProgressBarValue(double bar_percentage)
    26. {
    27. //Set the progress bar to the provided percentage, 0 to 100.
    28. }
    29. }
    30. }


    Aber das ist für mich keine wirkliche hilfe, wenn ich das ding so 1:1 reinkopiere bekomme ich schon fehler.

    Ich wollte jetzt die Dokumentation nicht direkt veröffentlichen (ich weiß ehrlich gesagt nicht wie der Hersteller dazu stehen würde) aber ich kann euch die natürlich per PN zur Verfügung stellen wenn Sie jemand sehen will.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Eddolino“ ()

    Willkommen im Forum. :thumbup:

    Eddolino schrieb:

    bekomme ich schon fehler.
    Bei Deinem obersten "Quellcode" sind leider Befehle und Kommentar nicht zu unterscheiden.
    Vielleicht postest Du mal den Code, bei dem die Fehler auftreten und die Fehlermeldung dazu.
    Vielleicht kommen wir da weiter.
    Und:
    Fang klein an. Nicht Befehle senden und Messwerte empfangen, sondern zunächst Öffnen und Beenden der Kommunikation.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Vollzitat des direkten Vorposts an dieser Stelle entfernt ~VaporiZed

    Hallo :)

    Okay also Befehle und Kommentare sind getrennt.

    Der Punkt mit dem Öffnen und Beenden der Kommunikation ist ein guter Anfang, weil das auch nicht funktioniert :)

    Folgendes Programm aktuell:

    VB.NET-Quellcode

    1. Imports ETherCheckDataAcq
    2. Public Class Form1
    3. Public Ether As ETherCheckDataAcq.ETherRealtimeClass
    4. Public Sub btnConnect_Click(sender As Object, e As EventArgs) Handles btnConnect.Click
    5. Ether.OpenSerialConnection("4")
    6. End Sub
    7. Private Sub btnDisconnect_Click(sender As Object, e As EventArgs) Handles btnDisconnect.Click
    8. Ether.CloseSerialConnection()
    9. End Sub
    10. End Class


    Die Fehlermeldung ist folgendes, mit Verweis auf Ether.OpenSerialConnection(4)

    Quellcode

    1. System.NullReferenceException: 'Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.'
    2. Ether was Nothing.


    Also der Com Port (4) stimmt definitiv (da passiert auch nichts wenn ich z.b. 6 reinschreibe).
    Die Kommunikation funktioniert über das Programm vom Hersteller, also Treibertechnisch usw. funktioniert auch alles.

    Das Problem existiert auch, wenn ich

    Quellcode

    1. Ether.RegisterDataCallback(Measurements)
    vor den OpenSerialConnection schiebe, dann auch mit dieser Zeile und nicht mit der OpenSerialConnection.

    Also liegt der Fehler nicht an OpenSerialConnection aber ich finde auch keine Lösung, wenn ich Ether.OpenSerialConnection(4) = TRUE mache kommt der Fehler "Expression is a value and therefore cannot be the target of an assignment"

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „VaporiZed“ ()

    Vollzitat des direkten Vorposts an dieser Stelle entfernt ~VaporiZed

    Vielen Dank!

    Allerdings nimmt er das dann nicht weil BC30516 Overload resolution failed because no accessible 'New' accepts this number of arguments.
    (also laut internet ist das weil ich einzelne Variablen mit unterschiedlichen Typen deklariert habe und er nicht weiß welche er nehmen soll?)


    Also folgendermaßen sieht es dann aus:

    VB.NET-Quellcode

    1. Imports ETherCheckDataAcq
    2. Public Class Form1
    3. Public Ether As New ETherCheckDataAcq.ETherRealtimeClass
    4. Public Sub btnConnect_Click(sender As Object, e As EventArgs) Handles btnConnect.Click
    5. Ether.OpenSerialConnection(4)
    6. End Sub
    7. Public Sub btnDisconnect_Click(sender As Object, e As EventArgs) Handles btnDisconnect.Click
    8. Ether.CloseSerialConnection()
    9. End Sub
    10. End Class

    (wobei es egal ist ob ich ETherCheckDataAcq.ETherRealtimeClass oder nur EtherRealtimeClass nehme oder?)

    Das steht in der .dll falls das irgendeinen Sinn macht:

    VB.NET-Quellcode

    1. public ETherRealtimeClass(int[][] x1, int[][] y1, int[][] x2, int[][] y2, int[][] xMix, int[][] yMix, int arrays, int size_of_arrays, int data_type)
    2. {
    3. if (data_type == 64 || data_type == 80 || data_type == 112 || data_type == 144)
    4. {
    5. requested_data_type = data_type;
    6. }
    7. if (x1 != null)
    8. {
    9. x_coords_ch1 = x1;
    10. }
    11. if (y1 != null)
    12. {
    13. y_coords_ch1 = y1;
    14. }
    15. if (x2 != null)
    16. {
    17. x_coords_ch2 = x2;
    18. }
    19. if (y2 != null)
    20. {
    21. y_coords_ch2 = y2;
    22. }
    23. if (xMix != null)
    24. {
    25. x_coords_chMix = xMix;
    26. }
    27. if (yMix != null)
    28. {
    29. y_coords_chMix = yMix;
    30. }
    31. number_of_elements = size_of_arrays;
    32. number_of_arrays = arrays;
    33. }
    34. public ETherRealtimeClass(int size_of_arrays, int data_type)
    35. {
    36. number_of_elements = size_of_arrays;
    37. if (size_of_arrays == 0)
    38. {
    39. if (logging)
    40. {
    41. log_file.WriteLine("Class constructed with 0 length Array (callback?).");
    42. }
    43. return;
    44. }
    45. if (data_type == 64 || data_type == 80 || data_type == 112 || data_type == 144)
    46. {
    47. requested_data_type = data_type;
    48. }
    49. number_of_arrays = 4;
    50. x_coords_ch1 = new int[number_of_arrays][];
    51. x_coords_ch2 = new int[number_of_arrays][];
    52. y_coords_ch1 = new int[number_of_arrays][];
    53. y_coords_ch2 = new int[number_of_arrays][];
    54. x_coords_chMix = new int[number_of_arrays][];
    55. y_coords_chMix = new int[number_of_arrays][];
    56. for (int i = 0; i < number_of_arrays; i++)
    57. {
    58. x_coords_ch1[i] = new int[size_of_arrays];
    59. y_coords_ch1[i] = new int[size_of_arrays];
    60. x_coords_ch2[i] = new int[size_of_arrays];
    61. y_coords_ch2[i] = new int[size_of_arrays];
    62. x_coords_chMix[i] = new int[size_of_arrays];
    63. y_coords_chMix[i] = new int[size_of_arrays];
    64. }
    65. if (logging)
    66. {
    67. log_file.WriteLine("Class constructed.");
    68. }
    69. }


    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „VaporiZed“ ()

    Willkommen im Forum.

    Anmerkung als Moderator: Keine Vollzitate anderer Posts verwenden, vor allem nicht der direkten Vorposts. Danke
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Jo den Konstruktor (das ist das New) scheint es nicht parameterlos zu geben.
    Public Ether As New ETherCheckDataAcq.ETherRealtimeClass(a, b, c, ...) statt
    Public Ether As New ETherCheckDataAcq.ETherRealtimeClass
    wobei a,b,c die Parameter/Variablen sind die du angeben musst. Und da ist nun die Frage weißt du welche Parameter er da haben will?
    Sprich weißt du was x1, y1, xMix, size_of_arrays, ... sein soll? Das steht sonst vielleicht in der Beschreibung zu der .dll.
    Damit scheint der sich zu konfigurieren. x_coords_ch1 Koordinaten von einem Kanal?
    Die dll präsentiert dir zwei mögliche Konstruktoren. Bei dem zweiten musst du nur size_of_arrays und data_type angeben. Das würde ich erstmal probieren.

    (Is übrigens dasselbe was du in deinem eigenen Bild siehst, nur c# statt vb.net)


    Eddolino schrieb:

    wobei es egal ist ob ich ETherCheckDataAcq.ETherRealtimeClass oder nur EtherRealtimeClass nehme oder?
    Wenn EtherCheckDataAcq ein Namespace ist kann man den als Import einfügen, dann kann man das weglassen, jo. Einfach mal probieren, falls du das nicht hast meckert er da.

    Dieser Beitrag wurde bereits 8 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Okay also Vielen Dank!

    mit der deklaration von x1 und y1 hat es geklappt (also das sind die einzigen relevanten daten).
    Ich glaube die Arrays und data Type sind nicht live messdaten sondern das wird zwischengespeichert und dann abgerufen.

    Und nach dem Connect verbindet er sich auch bzw. funktioniert eine If Schleife mit dem Connected, welche nicht funktioniert wenn ich die If Schleife vor das Ether.Openserialconnection setze

    Ich habe gleich auch herausgefunden, wie ich meine Parameter an das Gerät schicke (also manche), das funktioniert soweit, dass sich das Surren des Geräts verändert wenn ich die Frequenz höher stelle.

    Folgender Code aktuell:

    VB.NET-Quellcode

    1. Imports ETherCheckDataAcq
    2. Public Class Form1
    3. Dim x1 As Int32
    4. Dim y1 As Int32
    5. Public Ether As New ETherCheckDataAcq.ETherRealtimeClass(x1, y1)
    6. Public Measurements As New ETherCheckDataAcq.ETherRealtimeClass.DataReceived(AddressOf Verarbeitung)
    7. Public Sub btnConnect_Click(sender As Object, e As EventArgs) Handles btnConnect.Click
    8. txtX.ReadOnly = True
    9. txtY.ReadOnly = True
    10. Ether.OpenSerialConnection(4)
    11. Ether.RegisterDataCallback(Measurements)
    12. If Ether.IsUSBConnected() Then
    13. MsgBox("Connected")
    14. End If
    15. End Sub
    16. Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
    17. Ether.WriteToInstrument(1, 0, "<FREQUENCY>" & txtFrequency.Text & "</FREQUENCY>")
    18. End Sub
    19. Public Sub btnDisconnect_Click(sender As Object, e As EventArgs) Handles btnDisconnect.Click
    20. Ether.CloseSerialConnection()
    21. If Ether.IsUSBConnected() = False Then
    22. MsgBox("Disconnected")
    23. End If
    24. End Sub
    25. Public Sub Verarbeitung()
    26. txtX.Text = x1
    27. txtY.Text = y1
    28. End Sub
    29. Private Sub btnUSBParam_Click(sender As Object, e As EventArgs) Handles btnUSBParam.Click
    30. Ether.WriteToInstrument(0, 1, <USB_OUTPUT>7</USB_OUTPUT>)
    31. End Sub
    32. Private Sub btnReadSettings_Click(sender As Object, e As EventArgs) Handles btnReadSettings.Click
    33. txtBox.Text = Ether.GetError
    34. End Sub
    35. End Class


    Was jetzt noch nicht funktioniert ist das Auslesen von Messergebnissen.
    ALso ich habe folgende Variable:

    Quellcode

    1. Public Measurements As New ETherCheckDataAcq.ETherRealtimeClass.DataReceived(AddressOf Verarbeitung)


    dann soll er nachdem er die Verbindung aufgebaut hat den Callback starten:

    Quellcode

    1. Ether.RegisterDataCallback(Measurements)


    und dazu meine Methode:

    Quellcode

    1. Public Sub Verarbeitung()
    2. txtX.Text = x1
    3. txtY.Text = y1
    4. End Sub


    Aber das Textfeld wird nie beschrieben bzw. auch nicht aufgerufen (Msgbox)
    Wenn ich einen eigenen Button hinzufüge, welcher den Sub Verarbeitung aufruft, schreibt er nur 0 in txtX und txtY.
    Ich bin mir eigentlich sicher, dass es an dieser callback geschichte liegt (weil ich das auch nicht 100% verstehe). Was denkt ihr?
    Also da musst du nochmal genau schauen. Der Konstruktor mit zwei Parametern nimmt size_of_array und data_type und nix anderes. Wenn du so wie du es machst x1 und y1 angibst, bedeutet das, dass du dem Ether sagst x1 ist dein size_of_array und y1 ist dein data_type. In deinem speziellen Fall sind die außerdem beide 0, denn du hast ja nichts anderes vorher x1 und y1 zugewiesen.

    Desweiteren verändert Ether diese x1 und y1 auch definitiv nicht, aber das ist nochmal n ganz anderes Thema...Und ich bin nicht sicher ob das Sinn macht sich da reinzuvertiefen, weil die Spezifikationen der dll da mindestens so relevant sind wie diese Basics. (Also hat ersma nix mit Callback zu tun, dass da 0 rauskommt)
    Aber da fische ich auch im Trüben ich weiß nicht was x1 y1, usw. sein soll. Bei der Bedienung einer bestimmten dll kann ich dir nicht wirklich helfen
    @Eddolino Vielleicht solltest Du zunächst ein wenig mit der .NET-Programmierung warm werden.
    Programmiere mal ein paar einfache Sachen, damit Du und wir das selbe Vokabular verwenden (z.B. Instanzen).
    Gugst Du
    [Sammelthread] Programmieren, aber was? (Programmideen)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @EddolinoAm Ende des Dokuments "ETherRealtime DLL Instructions v2.2(1)" war ein Stück Code, den habe ich mal etwas überarbeitet.
    Füge die Form in Dein Projekt ein und probiere aus, was passiert.
    Finde zunächst heraus, welches SerialPort von Deinem Gerät benutzt wird.
    Form1.zip
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo,

    also sorry das hier nichtsmehr kam direkt, ich habe es geschafft eine Kommunikation aufzubauen :thumbsup:

    Vielen Dank auf jeden Fall für die ganze Hilfe das hätte niemals sonst funktioniert!

    Also ich habe jetzt ein Ablauf welcher nach Bedarf BEfehle sendet und X/Y empfängt.

    Jetzt bin ich gerade dabei, die ganzen restlichen Funktionen zu programmieren.

    Hierzu noch eine Frage (hat jetzt nicht direkt was mit der seriellen Verbindung zu tun).
    Insgesamt sendet das Paket laut dem offiziellen Programm ~16.000 Pakete pro Sekunde (ich denke das wird bei meinem Programm ähnlich sein).
    Der PC wird hier relativ gering ausgelastet also das ist kein Problem.
    Ich hatte ursprünglich vor, das ganze an eine Datenbank zu speichern, welche auf meinem Server läuft (also PC am Schreibtisch mit Messgerät, Server mit Datenbank ein Stock höher Verbunden über Netzwerk).
    Zum probieren hatte ich die InfluxDB aufgesetzt. (ich denke das passt eigentlich ganz gut).

    Mein Problem ist jetzt das mein PC komplett überlastet wird wenn ich die 16.000 X/Y Werte an die Datenbank sende (also CPU Auslastung 100%).
    (und das ist wenn ich die Messwerte direkt in die DB schreibe ohne irgendein Programm dazwischen.

    Jetzt bin ich mir nicht sicher, welche Alternativen sinnvoll sind. Ich denke es gibt folgende Möglichkeiten aber da weiß ich nicht was sinnvoll ist:
    1. Einen fließenden Mittelwert, welcher die Paketmenge etwas reduziert (ich denke ~1.000 Pakete werden immernoch gut genug sein aber das müsste ich noch testen).
    2. Irgendeinen Mittelmann, welcher die Daten möglicherweise ressourcenschonender annimmt und dann langsamer in die DB schreibt
    (also z.b. sowas wie Redis oder Apache Kafka?)
    3. Das ganze erst in ein schlankeres Format wandeln und das dann in die Datenbank verarbeiten
    (also soetwas wie MQTT oder RabbitMQ mit z.b. Mosquitto als Broker und Telegraf für die Verarbeitung).
    4. Eine lokale InfluxDB mit einer Routine, welche die lokalen Messwerte regelmäßig auf eine Zentrale Datenbank synchronisiert
    (aber da weiß ich nicht ob das überhaupt was bringt für die CPU Auslastung).
    5. Die Daten komprimiert und als Batch in die Datenbank schicken, aber da bin ich mir nicht sicher wie das mit dem Batch läuft.
    (aber das probiere ich nächste Woche aus)

    Am Ende sollte das ganze für 4 PCs/Geräte funktionieren, also ~64.000 Pakete pro Sekunde (unkompromiert).

    Was denkt ihr wäre die beste / einfachste Lösung?


    Und dann wollte ich noch fragen, ob ihr gute Tipps habt für zwei Diagramme von dem X/Y Wert.
    Die erste sollte quasi ein Kartesisches Koordinatensystem sein, wo die X/Y Werte der z.b. letzten 30sek geplottet werden und die Punkte nacheinander mit einer Linie verbunden werden.
    (also neuer Punkt wird mit einer Linie verbunden zum vorherig letzten Punkt usw. und der älteste Punkt vor 30Sek verschwindet).

    Das zweite ein Liniendiagramm, mit einer X-Achse (für die Zeit in Sekunden) und 2 Y Werten mit eigenen Skalen (also dass die Linien grob übereinander sind obwohl die Werte z.b. X=300 und Y=1600 sind).
    Da geht es darum zu sehen wie sich z.b. der X-Wert verhält und ob dieser irgendwann stark ausschlägt oder nicht, wie X/Y zueinander stehen wäre da egal.
    @Eddolino Was sind das für 16000 Werte?
    Sind die es Wert, in einer DB gespeichert zu werden?
    Lässt sich da iwas verdünnen (nicht komprimieren), also verarbeiten eine "Essenz" rausholen?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Am besten zeigst du uns erstmal wie nun die Messwerte bei dir vorliegen, also im Programm/Code
    Sind X und Y nun Integer()()?
    Dann wäre auch mal ein Beispiel für X und Y hilfreich.

    Eddolino schrieb:

    sendet das Paket laut dem offiziellen Programm ~16.000 Pakete pro Sekunde
    Das Paket sendet Pakete? Wie viele Sekunden geht eine Messung?
    Frage "lässt sich eine Essenz aus der Messung rausholen?"
    @RodFromGermany
    Naja das Problem ist, dass meine eigentliche Messung quasi die Abweichung zum bevorigen Messwert war.
    Also z.b. hatte ich ja geschrieben X=300 und Y=1600 und wenn ich jetzt einen Fehler messe dann entwickelt sich X z.b. bis 800 und dann langsam wieder zurück (ich weiß nicht wie ich das dokumentieren kann ohne jeden einzelnen Messpunkt abzuspeichern aber bestimmt baut sich das dann auf von 300 -> 310 -> 380 -> usw. bis es bei 800 ist in schnellen Schritten). Also ich kann nicht einfach sagen z.b. jeden 10. Punkt sondern müsste vermutlich einen laufenden durchschnitt bilden und dann selbst prüfen wieviele Werte ich gleichzeitig zusammenfassen kann.

    Frage "X/Y Integer? , Beispiel dafür? Wie lange geht eine Messung?"
    @Haudruferzappeltnoch
    Sorry das Gerät sendet Pakete (zumindest nennt der Hersteller die Dinger Pakete). Ein Ergebnis ist was in die EtherRealtimeClass kommt also (int[][] x1, int[][] y1, int[][] x2, int[][] y2, int[][] xMix, int[][] yMix) wobei ich davon nur x1 und y1 brauche.
    Ich glaube die Messung läuft in dem Gerät permanent und das Gerät sendet einfach den aktuellen Messwert laufend, bei 16.000 Paketen sind das dann ~62 Mikrosek.

    Also X und Y sind jeweils ein Int32 und ein Messwert ist zum Beispiel 543 (egal für X oder Y). Meistens sind das 3 oder 4 stellige Bereiche und bei einem Messfehler kann es 6-Stellig werden.


    @VaporiZed Sorry! hab es nochmal überarbeitet

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Eddolino“ ()

    Eddolino schrieb:

    bei 16.000 Paketen sind das dann ~62 Mikrosek.
    Das ist echt eine Datenflut.
    Mit welcher lonkreten Aufgabenstellung gehst Du an die Daten ran?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Alles sehr verwirrend. Das ist c# int[][] x1, int[][] y1 und bedeutet in vb so viel wie x1 as Integer()(), y1 as Integer()()
    Nun heißen diese Klammern, dass es sich um ein Array von Arrays handelt. Ist dir bekannt was ein Array ist?
    Also ein Integer Array Array ist nicht dasselbe wie ein Integer.

    Wie sieht denn nun der Code aus, der das hinzukriegen scheint?
    Ach ja und was sagt dir x=300 und y=1600? Das muss ja eine Bedeutung haben bevor du es in die Datenbank schreibst. Aber ich denke ein einzelner Messwert, wenn er alle 62 µs kommt, wird keine große Bedeutung haben.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    @RodFromGermany
    "Mit welcher lonkreten Aufgabenstellung gehst Du an die Daten ran? "

    Archivierung bzw. Rückverfolgung. Es gäbe theoretisch die Alternative, nur meine digitalen Signale abzuspeichern (also z.b. die Konfiguration und dann wann es tatsächliche einen Alarm gab das als Bool zu speichern in der DB) aber die konkrete Messung zu speichern wäre natürlich etwas schicker.


    @Haudruferzappeltnoch
    Ja das hatte ich vergessen zu erwähnen, mein Programm läuft jetzt in C# (also ich denke das könnte man problemlos in VB.Net ändern aber aktuell läuft es so).

    Dann bzgl. dem Array:
    Also wenn ich die Dokumentation von der DLL richtig verstanden habe, gibt es zwei Möglichkeiten mit dem Gerät zu kommunizieren. Entweder gibt die dll direkt die aktuellen Werte aus (also X1, Y1) oder speichert die Messwerte in einem Array ab und man ruft dieses Array dann von der DLL ab (und dann bekommt man die Größe des Arrays (also Anzahl Zeilen) und die Arrays zurück).
    Ich habe dir gerade auch nochmal kurz die ganze Dokumentation von mir geschickt vielleicht hilft das.

    Also in meinem Programm wird aber die Anzahl an Arrays auf 0 gesetzt und dann wird bei einem Abruf einfach nur der aktuelle Wert übergeben (also X1, Y1).

    Und dann noch zu den Messwerten:
    Ja also das ist eine Einheitslose Zahl welche so auch nichts bedeutet. Betrachtet wird nur die Änderung (also wie sich der Graph dazu verändert (Richtung, Form)) und die Amplitude dieser.
    Ich würde z.b. noch einen Alarm einprogrammieren, dass wenn sich der Messwert z.b. bei X=300 einpendelt ich einen Alarm bekomme bei X=400.
    Wenn ich jetzt ein anderes Messteil überprüfe, kann der Messwert bei gleichen Parametern bei X=500 ohne Alarm sein, der Alarm würde ich dann z.b. bei X=600 setzen (die Werte sind jetzt nur Beispielhaft, bei welcher Höhe der Alarm dann gesetzt wird kommt auf den Einzelfall an).

    C#-Quellcode

    1. using ETherCheckDataAcq;
    2. using System;
    3. using System.Threading;
    4. using System.Windows.Forms;
    5. namespace YourNamespace
    6. {
    7. public partial class Form1 : Form
    8. {
    9. private ETherRealtimeClass ether;
    10. public int ComPort;
    11. public string Message = "";
    12. public Form1()
    13. {
    14. InitializeComponent();
    15. ether = new ETherRealtimeClass(0, 0x70);
    16. // Register callback for real-time data
    17. ether.RegisterDataCallback(NewRealtimeData);
    18. }
    19. private void NewRealtimeData(Int32 X1, Int32 Y1, Int32 X2, Int32 Y2, Int32 Xmix_or_percent, Int32 Ymix_or_percent, Int32 Theta_or_status_X, Int32 Radius_or_status_Y)
    20. {
    21. // Invoke für die Anzeige im UI
    22. Invoke((MethodInvoker)delegate
    23. {
    24. txtX.Text = X1.ToString();
    25. txtY.Text = Y1.ToString();
    26. });
    27. }
    28. private void btnTransmit_Click(object sender, EventArgs e)
    29. {
    30. // Das überträgt bei Bedarf die Konfiguration ans Gerät und zeigt die jeweils in Messageboxen, ist bis jetzt nur ein "Grundgerüst"
    31. Message = "<GAIN_X>" + Convert.ToInt32(txtGainX.Text) * 10 + "</GAIN_X>";
    32. ether.WriteToInstrument(1, 0, Message);
    33. MessageBox.Show(Message);
    34. Message = "<GAIN_Y>" + Convert.ToInt32(txtGainY.Text) * 10 + "</GAIN_Y>";
    35. ether.WriteToInstrument(1, 0, Message);
    36. MessageBox.Show(Message);
    37. Message = "<FREQUENCY>" + Convert.ToInt32(txtFrequency.Text) * 1000 + "</FREQUENCY>";
    38. ether.WriteToInstrument(1, 0, Message);
    39. MessageBox.Show(Message);
    40. Message = "<PHASE>" + Convert.ToInt32(txtPhase.Text) * 100 + "</PHASE>";
    41. ether.WriteToInstrument(1, 0, Message);
    42. MessageBox.Show(Message);
    43. Message = "<FILTER_LP>" + Convert.ToInt32(txtLowPass.Text) * 100 + "</FILTER_LP>";
    44. ether.WriteToInstrument(1, 0, Message);
    45. MessageBox.Show(Message);
    46. Message = "<FILTER_HP>" + Convert.ToInt32(txtHighpass.Text) * 100 + "</FILTER_HP>";
    47. ether.WriteToInstrument(1, 0, Message);
    48. MessageBox.Show(Message);
    49. }
    50. private void btnConnect_Click_1(object sender, EventArgs e)
    51. {
    52. ComPort = int.Parse(txtComPort.Text);
    53. OpenSerialConnection();
    54. }
    55. private void btnDisconnect_Click_1(object sender, EventArgs e)
    56. {
    57. ether.CloseSerialConnection();
    58. MessageBox.Show("Verbindung Getrennt");
    59. }
    60. private void OpenSerialConnection()
    61. {
    62. bool result = ether.OpenSerialConnection(ComPort);
    63. if (result)
    64. {
    65. }
    66. else
    67. {
    68. MessageBox.Show("Verbindungsaufbau nicht möglich");
    69. }
    70. ether.WriteToInstrument(1, 0, "<USB_OUTPUT>0</USB_OUTPUT>");
    71. ether.WriteToInstrument(1, 0, "<USB_OUTPUT>7</USB_OUTPUT>");
    72. }
    73. private void btnSave_Click(object sender, EventArgs e)
    74. {
    75. WindowsFormsApp2.Properties.Settings.Default.ComPort = int.Parse(txtComPort.Text);
    76. ComPort = WindowsFormsApp2.Properties.Settings.Default.ComPort;
    77. WindowsFormsApp2.Properties.Settings.Default.Save();
    78. }
    79. }
    80. }


    CodeTags korrigiert; bitte zukünftig darauf achten, das richtige CodeHighlighting zu verwenden ~VaporiZed

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    Eddolino schrieb:

    MessageBox.Show(Message);
    Das ist kontraproduktiv.
    Gib die Messages z.B. in einer ListBox aus, das ist schneller und überschaubar.
    Wieviel Speicherbedarf pro Zeiteinheit fällt da an?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Gut der kann also beides.
    Für mich hört sich das so an: Du hälst da ein Ding vors Gerät und dann gibts n Fehler oder nicht.
    Da schreibst du nicht die ganze Ermittlung in die Datenbank, sondern das Teil und Fehler Ja/Nein.

    C#-Quellcode

    1. txtX.Text = X1.ToString();
    2. txtY.Text = Y1.ToString();
    Was ich an deinem Code sehe ist, dass da scheinbar dann zwei Textboxen flackern, du sagst ja alle 62 µs kommt da ein Wert...Ist das so? Soll das so?

    Was deinen Fehler angeht, in die Funktion schmeißt du alle x rein. Zurück kommt True wenn ein Wert 1,2mal so groß ist wie der bisherige Mittelwert, ansonsten False und der Mittelwert wird mit den "korrekten" Daten weiter verarbeitet:

    C#-Quellcode

    1. private int countx;
    2. private double _MittelX;
    3. private double factor = 1.2;
    4. private bool IsError(int newX)
    5. {
    6. countx += 1;
    7. if (_MittelX == 0)
    8. {
    9. _MittelX = newX;
    10. return false;
    11. }
    12. if (_MittelX * factor < newX)
    13. return true;
    14. _MittelX = (_MittelX * (countx - 1) + newX) / countx;
    15. return false;
    16. }
    MittelX musste zwischendurch aber mal zurücksetzen, wenn du eine neue Messung beginnst. Also irgendwie ein Kommando "jetzt gehts los" brauchste bei der Kommunikation auch noch.