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.

    @RodFromGermany
    Ja die ganzen Messageboxen sind noch für die Diagnose drin ich denke das lösche ich zeitnah raus das war nur für die Überprüfung von den Werten.
    Sonst benötige ich eigentlich keine Mitteilung wenn ich z.b. Werte schicke o.ä.

    Ich bin mir nicht sicher was du meinst mit Speicherbedarf pro Zeiteinheit?

    Theoretisch müsste entweder ein Mittelwert ausgerechnet werden und den kann ich abspeichern oder es gibt eine möglichkeit die Werte direkt abzuspeichern.
    (dass z.b. ein Broker die Möglichkeit hat soviele Werte anzunehmen und die dann langsam wieder abgeben).


    @Haudruferzappeltnoch
    Ja ich tendiere aktuell auch dazu nur die Fehler abzuspeichern weil ich jetzt auch nichts gefunden habe was sicher die Werte abspeichern kann ohne Probleme.
    Die Textboxen kannst du hier sehen:


    Warum die Messwerte so flackern (also von ~480 auf eine hohe sechsstellige Zahl) kann ich aktuell auch nicht sagen aber das kann auch was mit meiner Testspule zusammenhängen, das ist auf jeden Fall nicht immer so.
    (aber da frage ich die Tage den Entwickler nochmal).
    Man sieht auf jeden Fall im Gif wie die Werte angezeigt werden und das Programm eigentlich ganz gut damit klarkommt.

    Vielen Dank für den Code das probiere ich gleich aus!


    Habt ihr eigentlich sonst noch gute Gedanken für die X/Y Diagramme ?
    Ich habe v0.lvcharts.com/ das hier gefunden, kennt ihr das ?

    Eddolino schrieb:

    Ich bin mir nicht sicher was du meinst mit Speicherbedarf pro Zeiteinheit?
    Du redest von einer Datenbank.
    Wie wächst die Größe der DB mit der Zeit 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!
    Im Moment schreibt er ja noch nix in die db

    Es gibt die Klasse Chart, damit lässt sich schon einiges machen. Ob die Datenflut dafür ein Problem darstellen könnte weiß ich nicht.
    Was das resetten der Mittelwertaufnahme angeht, eventuell sollte man die Error-Funktion auch einfach so anpassen, dass der sich nach N Messwerten selbst resettet. Alternativ sagste beim Verbinden _MittelX = 0;
    Achso.
    Naja dadurch das der PC quasi direkt überlastet wenn ich die Datenbank einbaue gehe ich davon aus, dass da auf jeden Fall Messwerte verloren gehen.

    Also ich habe das ganze jetzt mal in eine csv geschoben und das geht performance technisch ganz gut.
    Mit dem Timestamp sind das aber wieso auch immer nur 990 Messpunkte pro Sekunde.

    Als CSV Datei wären das aber auch pro Gerät ~44Gb pro Tag also ich glaube schon alleine deswegen kann man den Gedanken verwerfen (auch überhaupt die Influx Geschichte solange nicht nur Alarme gespeichert werden).
    Ich dachte ursprünglich dass das eigentlich nicht so viel Speicher benötigen würde.
    Ich bleibe glaube ich vorerst dabei nur die Alarme abzuspeichern und die Messwerte werden einfach nur für x Sekunden im Diagramm angezeigt und danach verworfen.


    Ich arbeite mal an meinen restlichen Funktionen und melde mich dann nochmal vielen vielen Dank bisher!
    Vielleicht solltest Du mal mit ein paar Leuten bei euch reden, was Ihr ühaupt wollt und wie es weitergehen soll.
    Wenn Du "im eigenen Saft kochst", kann das schnell vor die Hose gehen.
    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!
    Also ein Plan bzw. Ziele habe ich schon da wissen wir prinzipiell wos lang geht.

    Die Geschichte mit der Datenbank ist nur weil das aktuell nicht geht und eben interessant gewesen wäre.
    Ich bin schon zufrieden wenn ich die Alarme in die Datenbank bekomme :)

    Das Gerät wird zur Qualitätsprüfung eingesetzt also das läuft nicht 24/7 (ich hab aus versehen "Tag" geschrieben aber Arbeitstag gemeint)
    Die zeitliche Auflösung ist halt vom Gerät gegeben, aber das irgendwie mit einem Durchschnitt zu begrenzen wird denke ich nichts bringen weil ich dann immernoch mega viele Daten habe und das mir nicht direkt was bringt.

    Wenn ich am Ende fertig bin mache ich mir vielleicht noch irgendwie einen Ablauf, dass er sich z.b. 5000 Werte Speichert und wenn der höchste Punkt vom Fehler in der Mitte ist speichert er die 5000 ab und dann kann ich mir zumindest die Fehler im nachhinein nochmal anschauen.
    Qualitätprüfung verbinde ich mit einzelnen zu prüfenden Objekten. Ein Objekt wäre für mich dann eine Messung, das heißt dazwischen schmeiß ich schonmal alles grundsätzliches weg.

    Mache ich tatsächlich auch so, ich kriege hier von einer Quelle alle 100 Sekunden einen Temperaturwert. Die internen Messgeräte messen natürlich durchgehend die Temperatur; nur abgegriffen wird halt alle 100 Sekunden weil das absolut ausreicht an zeitlicher Auflösung (eine Temperaturänderung ist ein sehr träger Vorgang). Hier habe ich an sich auch kein Anfang und Ende von der Quelle vorgegeben. In den Daten über einen Zeitraum von sagen wir 1 bis 2 Stunden ist aber eindeutig ersichtlich wo eine Messung tatsächlich anfängt und aufhört. Das heißt erst hab ich alle Daten für Gesamtzeitraum T, dann guckt das Programm drüber und verwirft automatisch die Pseudo-Nicht-Messzeiträume und über bleiben meine Messzeiträume t_1 bis t_n.

    Probier doch mal was du verlierst, wenn du nur jeden 10ten oder jeden 100ten Wert überhaupt entgegennimmst und verarbeitest
    Wenn der Messwert gleich bleibt, braucht man ihn auch nicht abzuspeichern.
    Erst wenn eine Änderung über den Rauschwert hinausgeht, merkt man sich
    diesen Wert, sowie den Zeitstempel. Hat die Messwertkurve eine starke
    Steigung misst man öfter als bei gleichbleibenden Werten.
    Das ist tatsächlich ein sehr interessanter Gedanke, ich denke das würde ich zumindest probieren so umzusetzen.

    Irgendwie bekomme ich das mit den Diagrammen nicht gebacken :(

    Also ich jedes mal wenn ich einen Beispielcode o.ä. in die XAML Schreibe geht das ding quasi direkt kaputt.
    Wobei ich nichtmal genau weiß welche library ich da am besten verwenden soll (weil bisher keine funktioniert und es auch kaum informationen gibt gefühlt).

    Also ich möchte ja eigentlich nur zwei Diagramme:
    1. Ein Punktdiagramm / Kartesisches Koordinatensystem wo X1 und Y1 jeweils platziert werden und die einzelnen Punkte werden mit einer Linie verbunden
    2. Ein Liniendiagramm mit X-Achse als Zeit in den letzten Sekunden und 2 Y-Achsen (jeweils für X1 und Y1 aber das soll übereinander gelegt werden das man beide ansehen kann).

    Der einfachheit habe ich jetzt erstmal versucht ein Liniendiagramm nur mit X1 zu erstellen. Dafür verwende ich DotNetProjects.WpfToolkit.DataVisualization und in meinem XAML Code habe ich dann folgende Zeile:

    Quellcode

    1. <chartingToolkit:LineSeries DependentValuePath="Value" IndependentValuePath="Key" IsSelectionEnabled="False" ItemsSource="{Binding Path=NewRealtimeData}"/>



    Jetzt weiß ich aber an 2 Stellen nicht weiter:
    1. Müsste ich nicht eigentlich irgendwie die Eigenschaften von dem Liniendiagramm festlegen können (Also zumindest Position und Größe und welche Daten wo hinsollen?)
    2. Wie gehts weiter mit dem Binding Path?
    Logischerweise funktioniert das mit dem NewRealtimeData nicht aber ich bin mir unsicher wies funktioniert.

    Hier werden andere Daten als Ursprung verwendet ("fest" deklarierte und ich möchte ja einen neuen Wert eingeben und dann bei Datenmenge X das letzte löschen).
    Könnten solche Diagramme eigentlich ihre Werte aus einem Array bekommen? (also alle Werte die im Array stehen werden angezeigt und die rutschen dann immer 1 Wert weiter wenn ein neuer Wert kommt)
    Weil dann könnte ich dieses gleich nehmen für Lightsource seine Idee und dieses Array abspeichern wenn mein Alarmwert in der Hälfte des Arrays ist (das ich sehe was vor und nach meinem Fehler passiert ist).


    Also aktueller Stand ist folgender (bitte das Modbus Zeug kurz übersehen das ist noch in Arbeit):

    Spoiler anzeigen

    C#-Quellcode

    1. using System;
    2. using System.IO.Ports;
    3. using System.Windows;
    4. using System.Windows.Controls;
    5. using System.Collections.ObjectModel;
    6. using ETherCheckDataAcq;
    7. using System.Windows.Media;
    8. using EasyModbus;
    9. namespace Final
    10. {
    11. /// <summary>
    12. /// Interaction logic for MainWindow.xaml
    13. /// </summary>
    14. public partial class MainWindow : Window
    15. {
    16. public ETherRealtimeClass ether;
    17. public EasyModbus.ModbusClient modbusClient;
    18. public int ComPort;
    19. public string Message = "";
    20. public MainWindow()
    21. {
    22. InitializeComponent();
    23. chkbxAutoconnect.Visibility = Visibility.Hidden;
    24. btnConnect.Visibility = Visibility.Hidden;
    25. btnSetComPort.Visibility = Visibility.Hidden;
    26. btnSetPasswd.Visibility = Visibility.Hidden;
    27. btnDisconnect.Visibility = Visibility.Hidden;
    28. txtComPort1.Visibility = Visibility.Hidden;
    29. lblComPort.Visibility = Visibility.Hidden;
    30. lblPassword.Visibility = Visibility.Hidden;
    31. txtSetPasswd.Visibility = Visibility.Hidden;
    32. btnLock1.Visibility = Visibility.Hidden;
    33. chkbxAutoconnect.IsChecked = Final.Properties.Settings.Default.AutoConnect;
    34. ether = new ETherRealtimeClass(0, 0x70);
    35. // Register callback for real-time data
    36. ether.RegisterDataCallback(NewRealtimeData);
    37. ComPort = Int32.Parse(Final.Properties.Settings.Default.ComPort);
    38. txtComPort1.Text = ComPort.ToString();
    39. Loaded += MainWindow_Loaded;
    40. //Modbus Zeug
    41. modbusClient = new EasyModbus.ModbusClient();
    42. }
    43. public void NewRealtimeData(Int32 X1, Int32 Y1, Int32 X2, Int32
    44. Y2, Int32 Xmix_or_percent, Int32 Ymix_or_percent, Int32
    45. Theta_or_status_X, Int32 Radius_or_status_Y)
    46. {
    47. if (X1 > 0x800000 Y1 > 0x800000 X2 > 0x800000 Y2 > 0x800000 X1 < -0x800000 Y1 < -0x800000 X2 < -0x800000 Y2 < -0x800000)
    48. {
    49. return;
    50. }
    51. Dispatcher.Invoke(() =>
    52. {
    53. txtX.Text = X1.ToString();
    54. txtY.Text = Y1.ToString();
    55. });
    56. }
    57. private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    58. {
    59. if (Final.Properties.Settings.Default.AutoConnect == true)
    60. {
    61. OpenSerialConnection();
    62. }
    63. }
    64. void txtFrequency_TextChanged(object sender, TextChangedEventArgs e)
    65. {
    66. if (txtFrequency.Text != "")
    67. {
    68. ether.WriteToInstrument(1, 0, "<FREQUENCY>" +
    69. Convert.ToInt32(txtFrequency.Text) * 1000 + "</FREQUENCY>");
    70. }
    71. }
    72. private void txtGainX_TextChanged(object sender, TextChangedEventArgs e)
    73. {
    74. if (txtGainX.Text != "")
    75. {
    76. ether.WriteToInstrument(1, 0, "<GAIN_X>" + Convert.ToInt32(txtGainX.Text) * 10 + "</GAIN_X>");
    77. }
    78. }
    79. private void txtGainY_TextChanged(object sender, TextChangedEventArgs e)
    80. {
    81. if (txtGainY.Text != "")
    82. {
    83. ether.WriteToInstrument(1, 0, "<GAIN_Y>" + Convert.ToInt32(txtGainY.Text) * 10 + "</GAIN_Y>");
    84. }
    85. }
    86. private void txtPhase_TextChanged(object sender, TextChangedEventArgs e)
    87. {
    88. if (txtPhase.Text != "")
    89. {
    90. ether.WriteToInstrument(1, 0, "<PHASE>" + Convert.ToInt32(txtPhase.Text) * 100 + "</PHASE>");
    91. }
    92. }
    93. private void txtLowpass_TextChanged(object sender, TextChangedEventArgs e)
    94. {
    95. if (txtLowpass.Text != "")
    96. {
    97. ether.WriteToInstrument(1, 0, "<FILTER_LP>" +
    98. Convert.ToInt32(txtLowpass.Text) * 100 + "</FILTER_LP>");
    99. }
    100. }
    101. private void txtHighpass_TextChanged(object sender, TextChangedEventArgs e)
    102. {
    103. if (txtHighpass.Text != "")
    104. {
    105. ether.WriteToInstrument(1, 0, "<FILTER_HP>" +
    106. Convert.ToInt32(txtHighpass.Text) * 100 + "</FILTER_HP>");
    107. }
    108. }
    109. private void btnConnect_Click(object sender, RoutedEventArgs e)
    110. {
    111. ComPort = int.Parse(txtComPort1.Text);
    112. OpenSerialConnection();
    113. }
    114. private void btnDisconnect_Click(object sender, RoutedEventArgs e)
    115. {
    116. ether.CloseSerialConnection();
    117. MessageBox.Show("Verbindung Getrennt");
    118. }
    119. private void OpenSerialConnection()
    120. {
    121. bool result = ether.OpenSerialConnection(ComPort);
    122. if (result)
    123. {
    124. }
    125. else
    126. {
    127. MessageBox.Show("Verbindungsaufbau nicht möglich");
    128. }
    129. //ether.WriteToInstrument(1, 0, "<USB_OUTPUT>0</USB_OUTPUT>");
    130. ether.WriteToInstrument(1, 0, "<USB_OUTPUT>7</USB_OUTPUT>");
    131. }
    132. private void btnSetComPort_Click(object sender, RoutedEventArgs e)
    133. {
    134. Final.Properties.Settings.Default.ComPort = txtComPort1.Text;
    135. Final.Properties.Settings.Default.Save();
    136. ComPort = int.Parse(Final.Properties.Settings.Default.ComPort);
    137. }
    138. private void btnSetPasswd_Click(object sender, RoutedEventArgs e)
    139. {
    140. Final.Properties.Settings.Default.Password = txtSetPasswd.Text;
    141. Final.Properties.Settings.Default.Save();
    142. }
    143. private void btnLock_Click(object sender, RoutedEventArgs e)
    144. {
    145. string string1 = txtPassword.Password;
    146. string string2 = Final.Properties.Settings.Default.Password;
    147. if (string1.Equals(string2))
    148. {
    149. btnLock1.Visibility = Visibility.Visible;
    150. chkbxAutoconnect.Visibility = Visibility.Visible;
    151. btnConnect.Visibility = Visibility.Visible;
    152. btnDisconnect.Visibility = Visibility.Visible;
    153. txtComPort1.Visibility = Visibility.Visible;
    154. lblComPort.Visibility = Visibility.Visible;
    155. lblPassword.Visibility = Visibility.Visible;
    156. txtSetPasswd.Visibility = Visibility.Visible;
    157. btnUnlock.Visibility = Visibility.Hidden;
    158. btnSetComPort.Visibility = Visibility.Visible;
    159. btnSetPasswd.Visibility = Visibility.Visible;
    160. }
    161. else
    162. {
    163. MessageBox.Show("Wrong Password");
    164. }
    165. }
    166. private void btnLock1_Click(object sender, RoutedEventArgs e)
    167. {
    168. chkbxAutoconnect.Visibility = Visibility.Hidden;
    169. btnConnect.Visibility = Visibility.Hidden;
    170. btnDisconnect.Visibility = Visibility.Hidden;
    171. txtComPort1.Visibility = Visibility.Hidden;
    172. lblComPort.Visibility = Visibility.Hidden;
    173. lblPassword.Visibility = Visibility.Hidden;
    174. txtSetPasswd.Visibility = Visibility.Hidden;
    175. btnSetComPort.Visibility = Visibility.Hidden;
    176. btnSetPasswd.Visibility = Visibility.Hidden;
    177. txtPassword.Password = "";
    178. btnUnlock.Visibility = Visibility.Visible;
    179. }
    180. private void chkbxAutoconnect_Checked(object sender, RoutedEventArgs e)
    181. {
    182. Checkbox();
    183. }
    184. private void chkbxAutoconnect_Unchecked(object sender, RoutedEventArgs e)
    185. {
    186. Checkbox();
    187. }
    188. private void Checkbox()
    189. {
    190. Final.Properties.Settings.Default.AutoConnect = chkbxAutoconnect.IsChecked.Value;
    191. Final.Properties.Settings.Default.Save();
    192. }
    193. private void btnConnectModbus_Click(object sender, RoutedEventArgs e)
    194. {
    195. modbusClient.IPAddress = txtModbusServerIP.Text;
    196. modbusClient.Port = int.Parse(txtModbusServerPort.Text);
    197. modbusClient.Connect();
    198. if (!modbusClient.Connected)
    199. {
    200. txtModbusTest.Text = modbusClient.ReadHoldingRegisters(int.Parse(txtModbusAdress.Text), 1).ToString();
    201. }
    202. }
    203. }
    204. }


    Mit meiner XAML:

    Quellcode

    1. <Window x:Class="Final.MainWindow"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    6. xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=DotNetProjects.DataVisualization.Toolkit"
    7. xmlns:local="clr-namespace:Final"
    8. mc:Ignorable="d"
    9. Title="MainWindow" Height="1080" Width="1920">
    10. <Grid x:Name="txtComPort" Width="1920" Height="1080">
    11. <Grid.RowDefinitions>
    12. <RowDefinition/>
    13. </Grid.RowDefinitions>
    14. <Button x:Name="btnUnlock" Content="Unlock"
    15. HorizontalAlignment="Left" Margin="306,24,0,0" VerticalAlignment="Top"
    16. Height="33" Width="65" Click="btnLock_Click"/>
    17. <PasswordBox x:Name="txtPassword" HorizontalAlignment="Left"
    18. Margin="90,27,0,0" VerticalAlignment="Top" Width="191" Height="30"/>
    19. <TextBox x:Name="txtFrequency" HorizontalAlignment="Left"
    20. Margin="179,106,0,0" TextWrapping="Wrap" VerticalAlignment="Top"
    21. Width="191" TextChanged="txtFrequency_TextChanged" Height="29"/>
    22. <Label x:Name="lblFrequency" Content="Frequency"
    23. HorizontalAlignment="Left" Margin="67,99,0,0" VerticalAlignment="Top"
    24. Height="43" Width="103"/>
    25. <TextBox x:Name="txtGainX"
    26. HorizontalAlignment="Left" Margin="179,155,0,0" TextWrapping="Wrap"
    27. VerticalAlignment="Top" Width="191" Height="29"
    28. TextChanged="txtGainX_TextChanged"/>
    29. <TextBox
    30. x:Name="txtGainY" HorizontalAlignment="Left" Margin="179,204,0,0"
    31. TextWrapping="Wrap" VerticalAlignment="Top" Width="191" Height="29"
    32. TextChanged="txtGainY_TextChanged"/>
    33. <TextBox
    34. x:Name="txtPhase" HorizontalAlignment="Left" Margin="179,253,0,0"
    35. TextWrapping="Wrap" VerticalAlignment="Top" Width="191" Height="29"
    36. TextChanged="txtPhase_TextChanged"/>
    37. <TextBox
    38. x:Name="txtLowpass" HorizontalAlignment="Left" Margin="179,305,0,0"
    39. TextWrapping="Wrap" VerticalAlignment="Top" Width="191" Height="29"
    40. TextChanged="txtLowpass_TextChanged"/>
    41. <TextBox
    42. x:Name="txtHighpass" HorizontalAlignment="Left" Margin="179,348,0,0"
    43. TextWrapping="Wrap" VerticalAlignment="Top" Width="191" Height="29"
    44. TextChanged="txtHighpass_TextChanged"/>
    45. <Label
    46. x:Name="lblGainX" Content="Gain X" HorizontalAlignment="Left"
    47. Margin="99,148,0,0" VerticalAlignment="Top" Height="43" Width="71"/>
    48. <Label x:Name="lblGainY" Content="Gain Y"
    49. HorizontalAlignment="Left" Margin="99,197,0,0" VerticalAlignment="Top"
    50. Height="43" Width="70"/>
    51. <Label x:Name="lblPhase"
    52. Content="Phase" HorizontalAlignment="Left" Margin="104,246,0,0"
    53. VerticalAlignment="Top" Height="43" Width="65"/>
    54. <Label
    55. x:Name="lblFilterLP" Content="Filter Lowpass"
    56. HorizontalAlignment="Left" Margin="32,299,0,0" VerticalAlignment="Top"
    57. Height="42" Width="134"/>
    58. <Label x:Name="lblFilterHP"
    59. Content="Filter Highpass" HorizontalAlignment="Left" Margin="29,341,0,0"
    60. VerticalAlignment="Top" Height="42" Width="140"/>
    61. <TextBlock x:Name="txtX" HorizontalAlignment="Left"
    62. Margin="134,65,0,0" TextWrapping="Wrap" Text="X" VerticalAlignment="Top"
    63. Height="16" Width="68"/>
    64. <TextBlock x:Name="txtY"
    65. HorizontalAlignment="Left" Margin="217,68,0,0" TextWrapping="Wrap"
    66. Text="Y" VerticalAlignment="Top" Height="16" Width="64"
    67. RenderTransformOrigin="-6.667,0.461"/>
    68. <CheckBox
    69. x:Name="chkbxAutoconnect" Content="Autoconnect"
    70. HorizontalAlignment="Left" Margin="666,16,0,0" VerticalAlignment="Top"
    71. Checked="chkbxAutoconnect_Checked"
    72. Unchecked="chkbxAutoconnect_Unchecked" Height="15" Width="88"/>
    73. <Button x:Name="btnConnect" Content="Connect"
    74. HorizontalAlignment="Left" Margin="777,14,0,0" VerticalAlignment="Top"
    75. Click="btnConnect_Click" Height="20" Width="48"/>
    76. <Button x:Name="btnDisconnect" Content="Disconnect"
    77. HorizontalAlignment="Left" Margin="844,16,0,0" VerticalAlignment="Top"
    78. Click="btnDisconnect_Click" Height="20" Width="62"/>
    79. <TextBox x:Name="txtComPort1" HorizontalAlignment="Left"
    80. Margin="719,51,0,0" TextWrapping="Wrap" Text="ComPort"
    81. VerticalAlignment="Top" Width="120" Height="18"/>
    82. <Label x:Name="lblComPort" Content="ComPort"
    83. HorizontalAlignment="Left" Margin="656,45,0,0" VerticalAlignment="Top"
    84. Height="26" Width="56"/>
    85. <Label x:Name="lblPassword"
    86. Content="Password" HorizontalAlignment="Left" Margin="653,83,0,0"
    87. VerticalAlignment="Top" Height="26" Width="60"/>
    88. <TextBox x:Name="txtSetPasswd" HorizontalAlignment="Left"
    89. Margin="719,87,0,0" TextWrapping="Wrap" Text="Password"
    90. VerticalAlignment="Top" Width="120" Height="18"/>
    91. <Button x:Name="btnSetComPort" Content="Save ComPort"
    92. HorizontalAlignment="Left" Margin="844,50,0,0" VerticalAlignment="Top"
    93. Click="btnSetComPort_Click" Height="20" Width="78"/>
    94. <Button x:Name="btnSetPasswd" Content="Save Password"
    95. HorizontalAlignment="Left" Margin="844,86,0,0" VerticalAlignment="Top"
    96. Click="btnSetPasswd_Click" Height="20" Width="81"/>
    97. <Button x:Name="btnLock1" Content="Lock" HorizontalAlignment="Left"
    98. Margin="306,66,0,0" VerticalAlignment="Top" Height="35" Width="65"
    99. Click="btnLock1_Click"/>
    100. <chartingToolkit:LineSeries
    101. DependentValuePath="Value" IndependentValuePath="Key"
    102. IsSelectionEnabled="False" ItemsSource="{Binding
    103. Path=NewRealtimeData}"/>
    104. <Label x:Name="lblModbusIP"
    105. Content="Modbus Server IP" HorizontalAlignment="Left"
    106. Margin="392,24,0,0" VerticalAlignment="Top"/>
    107. <Label
    108. x:Name="lblModbusPort" Content="Modbus Server Port"
    109. HorizontalAlignment="Left" Margin="380,55,0,0"
    110. VerticalAlignment="Top"/>
    111. <TextBox
    112. x:Name="txtModbusServerIP" HorizontalAlignment="Left"
    113. Margin="506,28,0,0" TextWrapping="Wrap" VerticalAlignment="Top"
    114. Width="120"/>
    115. <TextBox x:Name="txtModbusServerPort"
    116. HorizontalAlignment="Left" Margin="506,59,0,0" TextWrapping="Wrap"
    117. VerticalAlignment="Top" Width="120" Text="502"/>
    118. <Button x:Name="btnModbusSaveServer" Content="Save Modbus Server"
    119. HorizontalAlignment="Left" Margin="392,85,0,0"
    120. VerticalAlignment="Top"/>
    121. <TextBox
    122. x:Name="txtModbusTest" HorizontalAlignment="Left" Margin="523,138,0,0"
    123. TextWrapping="Wrap" Text="Value" VerticalAlignment="Top"
    124. Width="120"/>
    125. <Button x:Name="btnConnectModbus"
    126. Content="Connect Modbus" HorizontalAlignment="Left" Margin="523,91,0,0"
    127. VerticalAlignment="Top" Click="btnConnectModbus_Click"/>
    128. <TextBox x:Name="txtModbusAdress" HorizontalAlignment="Left"
    129. Margin="392,138,0,0" TextWrapping="Wrap" Text="Adress"
    130. VerticalAlignment="Top" Width="120"/>
    131. </Grid>
    132. </Window>



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

    Was du willst ist serielle Schnittstelle auslesen, Daten auswerten, Datenbank beschreiben, Daten visuell aufbereiten. Und nebenbei das Ganze noch schick in WPF. Das sind fünf Themen für sich.
    Und am Anfang hatten wir Probleme eine Klasse zu instanzieren...

    Soweit ich das bisher erfasst habe, klappt serielle Schnittstelle auslesen. Und das nur so halb, denn alles was du davon hast ist ne flackernde Textbox. Ich denke da solltest du erstmal ansetzen.
    Mit Charts/Diagrammen habe ich in WPF leider noch nicht gearbeitet, aber mit Textbox-Texten wird das schwierig umzusetzen.
    @Eddolino Pack mal Deinen Quellcode in einen
    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!
    Also Quellcode ist im Spoiler.

    Also wirklich fertig ist nur die serielle Kommunikation mit Gerät (also alle relevanten Befehle kann ich
    ans Gerät senden und erhalte alle relevanten Daten zurück) und dafür habe ich auch eine kleine GUI
    (okay also ich bin mir nicht sicher ob das eine Programmfunktion oder eine Gerätefunktion ist aber der Hersteller hat theoretisch die Funktion, das die letzten Parameter wieder geladen werden und ich bin mir nicht sicher ob er dann die Parameter vom Gerät ausliest und dann in den jeweiligen Feldern anzeigt oder ob er das einfach irgendwie zwischenspeichert, wenn er irgendwie die möglichkeit hat die Daten auszulesen hätte ich das eigentlich auch ganz gerne aber wenn ich einfach die Parameter zwischenspeicher und so weiß was ich als letztes gesendet habe ist das auch okay).

    Die Werte die ich vom Gerät bekomme passen auch also das ist denke ich 1:1 wie der Hersteller die Daten bekommt.

    Ich arbeite jetzt noch an dem Modbus Client aber da sehe ich gerade keine Probleme
    Die
    Datenbank Geschichte ist für mich vom Gedanken her auch abgeschlossen,
    also ich sehe es als nicht direkt möglich oder sinnvoll alle Messdaten
    abzuspeichern und ich speicher dann meine Messparameter und meine Alarme
    ein (+z.b. ein Array mit den letzten 10sek der Messdaten bei Fehlern
    wenn ich dazu komme).
    Ich werde noch einen Alarm einprogrammieren
    aber das ist eigentlich auch relativ einfach z.b. if (x1>alarm)
    {Alarmsenden} usw.

    Das letzte Thema was bei mir also eigentlich
    wirklich ungeklärt ist und wo ich nicht weiter weiß ist das
    Liniendiagramm bzw. die Diagramme überhaupt.

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