Doeni Geschrieben July 5, 2012 at 14:42 Geschrieben July 5, 2012 at 14:42 Kann mir mir jemand erklären wie man Messwerte von Bricklets in einer Windows Form anzeigen lassen kann. Ich kriegs irgendwie nicht hin Programmiersprche: c# Zitieren
Nic Geschrieben July 5, 2012 at 16:26 Geschrieben July 5, 2012 at 16:26 Für den Anfang würde ich Lektüre zu C# empfehlen: http://www.tinkerunity.org/forum/index.php/topic,218.msg970.html#msg970 In Kombination mit der ausführlichen Doku und API Beschreibung auf der Website von TF genau studieren insbesondere die Code-Beispiele zum betreff. Bricklet analysieren. Falls weiterhin Unklarheit, anschließend genauere Angaben zum Problem ins Forum stellen, welche Messwerte, welches Bricklet etc. Zitieren
The_Real_Black Geschrieben July 5, 2012 at 17:17 Geschrieben July 5, 2012 at 17:17 Ich vermute mal du hast bereits einen Code wie: ipcon = new IPConnection(host, port); temp = new BrickletTemperature(t.Uid); temp.SetTemperatureCallbackPeriod(1000); temp.RegisterCallback(new BrickletTemperature.Temperature(TempCB)); ... void TempCB(short val) { labelxyz.text = val.ToString(); } Problem ist klar da es Multi-Threaded ist kann man nicht auf das Label zugreifen. Stichwort ist INVOKE! temp.RegisterCallback(new BrickletTemperature.Temperature(TempCB)); SetValues = new SetPosDel(InvokeSetter); ... private delegate void SetPosDel(double val); private SetPosDel SetValues; void TempCB(short val) { try { object[] p = { (val / 100.0) }; this.Invoke(SetValues, p); } catch { } } private void InvokeSetter(double val) { DateTime now = DateTime.Now; txt_log.Text = "Temperatur um " + now.ToString("yyyy-MM-dd HH:mm:ss:ff") +": " + val.ToString("0#.##") + "°C" + Environment.NewLine + txt_log.Text; txt_ExcelLog.Text += now.ToString("HH:mm:ss") + "\t" + val + Environment.NewLine; } Zitieren
Doeni Geschrieben July 6, 2012 at 17:34 Autor Geschrieben July 6, 2012 at 17:34 Ich bekommen eine Fehlermeldung so ungefähr: Instanzmember können nicht in einer statischen Klassse deklariert werden. Ich hoffe du kannst mir noch einmal helfen Zitieren
AuronX Geschrieben July 6, 2012 at 17:42 Geschrieben July 6, 2012 at 17:42 Dann hast du eine static class. Von dieser können mit new keine neuen Instanzen angelegt werden. Das heißt alle Variablen und Methoden der Klasse brauchen auch das static-Schlüsselwort. Ich weiß allerdings nicht ob du wirklich eine statische Klasse haben willst. Die Lösung ist es entweder überall static dazuzuschreiben (in dieser Klasse) oder eben es vom class zu entfernen. Aus dem Bauch heraus würde ich sagen versuch es nicht-statisch, ist i.d.R. die richtige Lösung auch wenn statisch "erstmal einfacher (und hauptsache es läuft)" aussieht. Poste gerne Code-Ausschnitte und sage was du wissen willst. Wir können nur kurz schreiben warum es nicht geht, aber ich kann mir auch Zeit nehmen und grundsätzliche Hinweise zum Code schreiben. Ist aber einfacher wenn man eine "Diskussionsgrundlage" hat Zitieren
The_Real_Black Geschrieben July 6, 2012 at 18:14 Geschrieben July 6, 2012 at 18:14 Poste mal allen Code der wichtig sein kann. Dann kann man helfen oder du postest das Projekt als zip, dann kann man einen Blick draufwerfen und ausbessern. Zitieren
Doeni Geschrieben July 6, 2012 at 18:32 Autor Geschrieben July 6, 2012 at 18:32 Immernoch mit vielen Fehlern schon mal Danke für eure tolle Unterstützung Program.cs Zitieren
AuronX Geschrieben July 6, 2012 at 19:02 Geschrieben July 6, 2012 at 19:02 Ah okay, dein eigener Code liegt grundsätzlich an der falschen Stelle (würde ich sagen). Tatsächlich kannst du zunächst die Program-Klasse so lassen wie sie dir von Visual Studio erzeugt wird. Dein eigener Code sollte besser in die Klasse Form1 wandern (rechtsklick auf Form1 im Solution Explorer und dort "View Code"). (Die Klasse Form1 darfst du auch gerne nach MainWindow o.ä. umbenennen, das ist aber nicht soooo wichtig ^^) Grundlegend sollte das so aussehen: - Instanz-variablen für deine Brick(let)s und die IPConnection - Im Konstruktor der Form (nach InitializeComponents) die Instanzvariablen initialisieren (ipcon = new ... und ipcon.AddDevice(...)) - Beim Schließen der Form kannst du sowas machen wie ipcon.destroy Woher weißt du wann die Form geschlossen wird? Dazu im Solution Explorer die Form Doppelklicken, du solltest jetzt eine Vorschau davon sehen, auf properties gehen (Eigenschaften), dort kannst du dir Events anzeigen lassen, eines davon heißt closing. Dieses Event wird gerufen sobald sich die Form schließt. Ein Doppelklick darauf sollte reichen, damit dir automatisch eine Methode erzeugt wird die beim Schließen gerufen wird. Dort kann jetzt dein "aufräum-code" rein. Grundsätzlich solltest du dir vermutlich auch ein bis zwei Einstiegshilfen in WinForms suchen... etwa die hier (sehr kurz): http://msdn.microsoft.com/en-us/library/360kwx3z(v=vs.90).aspx Zitieren
The_Real_Black Geschrieben July 6, 2012 at 19:11 Geschrieben July 6, 2012 at 19:11 Mal ein "anderer" Ansatz (durch code sieht und lernt man es am besten): - Code ist verschoben - und getestet (klappt mit meiner UID // ist bereits auf deine UID geändert.) - sonst siehe oben. - ich habe mich mal auf den Poti beschränkt. - auf der Form ist ein label welches dir die Position des Potis anzeigt. Edit: Ich erwarte, dass der Brick bereits angeschlossen ist (keine Fehlerprüfungen oder so) da es nur ein Beispiel ist.Hilfestellung.zip Zitieren
Doeni Geschrieben July 7, 2012 at 13:09 Autor Geschrieben July 7, 2012 at 13:09 Vielen Dank es klappt auch soweit nur etwas auf dem lcd anzuzeigen klappt nnicht.Messwerte_verwalten.zip Zitieren
The_Real_Black Geschrieben July 7, 2012 at 13:21 Geschrieben July 7, 2012 at 13:21 // --- lcd = new Tinkerforge.BrickletLCD20x4(UID2); ipcon.AddDevice(lcd); lcd.BacklightOn(); // --- Das Lcd ist nicht in der Connection. Dann im Setter: lcd.WriteLine(0, 0, "Ausgabe: " + lcdtext + " " ); Die Leerzeichen am Ende sind nötig, damit die Verschiebung der negativen Zahlen ausgeglichen wird. Zitieren
Doeni Geschrieben July 8, 2012 at 08:22 Autor Geschrieben July 8, 2012 at 08:22 Kannst du mir die einzelnen Codeteile erklären weil ich dasselbe auch für den Abstandssensor machen will. SetValues = new SetPosDel(InvokeSetter); poti.RegisterCallback(new BrickletRotaryPoti.Position(PositionCB)); poti.SetPositionCallbackPeriod(100); delegate void SetPosDel(double val); private SetPosDel SetValues; .. void PositionCB(short val) { try { object[] p = { (val) }; this.Invoke(SetValues, p); } catch { } } ... private void InvokeSetter(double val) {} Zitieren
The_Real_Black Geschrieben July 8, 2012 at 11:16 Geschrieben July 8, 2012 at 11:16 Kannst du mir die einzelnen Codeteile erklären weil ich dasselbe auch für den Abstandssensor machen will. Gerne. delegate void SetPosDel(double val); private SetPosDel SetValues; Zeile 1 ist die Vereinbarung eines Funktionspointers (delegate) welche vorschreibt, dass eine Methode void zurückliefert und einen Parameter vom Typ double besitzt. Zeile 2 ist dann ein Funktionspointer vom Typ "SetPosDel" mit dem Namen "SetValues". In diese Varibale können wir dann eine Funktion hinterlegen. SetValues = new SetPosDel(InvokeSetter); Dies passiert dann hier die Methode "InvokeSetter" wird in den Funkionspointer\Delegate "SetValues" gelegt. private void InvokeSetter(double val) { /* Setzt die Daten */ } Dass ist die Methode welche unsere Daten im passenden Thread dann ausführt. Innerhalb dieser Methode kann man dann auf die Oberflächenelemente zugreifen. poti.RegisterCallback(new BrickletRotaryPoti.Position(PositionCB)); poti.SetPositionCallbackPeriod(100); Dies ist TF Gebiet: Zeile 1 wir legen hier auch einen Delegaten vom Typ "BrickletRotaryPoti.Position" an und geben diesen in das poti Objekt. Damit wird bei einer Positionsänderung oder Timer die Methode "PositionCB" aufgerufen. Mit Zeile 2 legen wir fest, dass alle 100 ms der Callback aufgerufen werden soll. void PositionCB(short val) { try { object[] p = { (val) }; this.Invoke(SetValues, p); } catch{} } Hier dann als letztes die Callbackfuntion welches die TF Methoden mit dem Oberfläche "verbinden". Der Try Catch Block soll Fehler abfangen, da mir im Beispiel Fehler beim Invoken egal sind ist er leer *grins* "this" ist in diesen Fall eine Referenz auf die Oberfläche\Form. Jede Oberfläche hat einen eigenen Thread zum Darstellen der Elemente. Die TF Methoden laufen aber in anderen Threads um die Oberfläche nicht zu blockieren. Um von einen Thread in einen Anderen auf Elemente zugreifen zu können ist die Invoke-Methode nötig. Diese führt dann fir übergebene Methode in dem anderen Thread aus. Parameter 1 ist "SetValues" unser Funktionspointer auf die "InvokeSetter" Methode und der zweite Parameter sind die Parameter der "InvokeSetter" Methode. Übergeben als "object" Array. Also wird beim Invoke die Methode InvokeSetter mit dem "val" als Parameter aufgerufen. Im Grunde wäre es die Zeile: InvokeSetter(val); Welche Aufgrund der verschiedenen Threads Fehler werfen würde. Zitieren
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.