Schrittketten über Datei einbinden?

  • VB.NET

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von Tobi123.

    Schrittketten über Datei einbinden?

    Hallo,
    ich steuer Steckdosen (16 Stück) über die serielle Schnittstelle an. Das funktioniert wunderbar.
    Nun möchte ich die Steckdosen als Lauflichter ansteuern. Damit man den Ablauf (vor, zurück, paarweise, gegenläufig...) belibig ändern kann, möchte ich den "Lauflichtablauf" in eine Ini schreiben und dort den jeweiligen Kanal ein- bzw. ausschalten mit verschiedenen Wartezeiten dazwischen.

    [Lauflicht001]
    Timer1=200ms
    Timer2=500ms
    Kanal1=1
    warten Timer1
    Kanal1=0
    warten Timer2
    Kanal2=1
    warten Timer1
    Kanal2=0
    warten Timer2
    Kanal3=1
    usw...

    Nun möchte ich wissen wie man soetwas programmiert oder ob ihr das vielleicht prinzipiell ganz anders machen würdet.

    Vielen Dank,
    Tobi
    Willkommen im Forum. :thumbup:
    Nun mal langsam mit die jungen Pferde.
    Bring erst mal eins zum Laufen, dann wird das nächste einfacher.
    Wie sind denn die Steckdosen miteinander verschaltet?
    Was läuft schon?
    Wie?
    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,
    na denn hol ich mal etwas weiter aus:
    Also ich habe 16 Steckdosen die an einem Mikrokontroller angeschlossen sind. Der Mikrokontroller kümmert sich um das komplette Timing der Steckdosen(also Phasennulldurchgangserkennung messen und Tyristoren zünden...). Der Mikrokontroller bekommt nun über die serielle Schnittstelle 16 Helligkeitswerte (jeweils 0-255) um die Steckdosen zu steuern. Dementsprechend habe ich für die VB.Net Software 16 "Schieberegler" um die Helligkeit zu dimmen - bis sie aus sind.
    Das ist alles fertig und funktioniert.

    Nun möchte ich nicht nur feste Helligkeiten einstellen, sondern die Steckdosen sollen als Lauflicht geschaltet werden, d.h. ich schicke den Wert 255 üeber die serielle Schnitstelle an den Mikrokontroller und die Steckdose ist an. Nach einer Wartezeit sende ich den Wert 0 und die Steckdose ist aus.

    Hier mein bisheriges Programm für das Senden - nix großes aber es funktioniert:

    If senden_merker = 0 Then
    senden_merker = 1

    SerialPort.Write(startbyte, 0, 1) 'Wert von Variable über RS232 senden

    SerialPort.Write(Kanal1, 0, 1)
    SerialPort.Write(Kanal2, 0, 1)
    SerialPort.Write(Kanal3, 0, 1)
    SerialPort.Write(Kanal4, 0, 1)
    SerialPort.Write(Kanal5, 0, 1)
    SerialPort.Write(Kanal6, 0, 1)
    SerialPort.Write(Kanal7, 0, 1)
    SerialPort.Write(Kanal8, 0, 1)
    SerialPort.Write(Kanal9, 0, 1)
    SerialPort.Write(Kanal10, 0, 1)
    SerialPort.Write(Kanal11, 0, 1)
    SerialPort.Write(Kanal12, 0, 1)
    SerialPort.Write(Kanal13, 0, 1)
    SerialPort.Write(Kanal14, 0, 1)
    SerialPort.Write(Kanal15, 0, 1)
    SerialPort.Write(Kanal16, 0, 1)

    SerialPort.Write(stopbyte, 0, 1)
    End If
    Wenn Du ein Lauflicht machen willst, solltest Du mal probieren, das zunächst für den Startzustand aufzumalen.
    Lege über Deine 16 Stellen ein Rechteck, ein Dreieck oder einen Sinus.
    Die so ermittelten Helligkeitswerte legst Du tabellarisch in einem Byte-Feld ab.
    Zum Zeitpunkt t0 sendest Du alle Werte direkt an Dein Port (Kanal 0 - Index 0, Kanal 1 - Index 1 usw.) (hier ist es ungünstig, dass Deine Kanäle 1...16 gezählt werden, denn .NET adressiert das Array 0...15, also Kanal 0...15).
    Zum Zeitpunkt t1 sendest Du das Array um einen Index verschoben: Kanal 0 - Index 1, Kanal 1 - Index 2, ... Kanal 15 - Index 0.
    Zum Zeitpunkt t2 sendest Du das Array um zwei Indexe verschoben: Kanal 0 - Index 2, Kanal 1 - Index 3, ... Kanal 15 - Index 1.
    usw.
    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 da an den Steckdosen Scheinwerfer sind die nachleuchten(trägheit der Leuchtmittel), wollte ich nur "AN" oder "AUS" übertragen(also Wert "0" oder Wert "255"). Ich glaube ich habe mich da falsch ausgedrückt. :S

    Ich möchte verschiedene Lauflichteffekte haben, d.h. ich habe keine feste Reihenfolge, wann welche Steckdose geschaltet wird. Deshalb hatte ich die Idee eine "Programm.INI" zu schreiben in der der Ablauf steht.

    Meine Frage ist nun wie ich diese Datei auslese und auswerte.
    Zum Start sind alle Steckdosen AUS.
    In der Datei KANN nun in der ersten Zeile stehen, dass die Steckdose 1 eingeschaltet wird. Es könnte aber auch stehen, dass Steckdose 16 eingeschaltet wird(oder eine ganz andere). Nach einem Steckdosenschaltbefehl kommt immer eine Wartezeit. Was danach kommt ist auch VARIABEL. Es könnte stehen, dass Steckdose 1 wieder ausgeschaltet wird, es könnte aber auch stehen, dass nun Steckdose 2 auch eingeschaltet wird.

    Also muss das Programm die INI zeilenweise lesen und in jeder Zeile erkennen welche Steckdose geschaltet werden soll und welchen neuen Wert die Steckdose bekommen soll - oder ob es eine Wartezeit für einenTimer ist.

    XML-Quellcode

    1. INI Datei:
    2. [Lauflicht001]
    3. Steckdose 1 an
    4. warten 1000ms
    5. Steckdose 2 an
    6. warten 1000ms
    7. Steckdose 3 an
    8. warten 1000ms
    9. Steckdose 4 an
    10. warten 1000ms
    11. Steckdose 1 aus
    12. warten 1000ms
    13. Steckdose 2 aus
    14. warten 1000ms
    15. Steckdose 3 aus
    16. warten 1000ms
    17. Steckdose 4 aus
    18. warten 1000ms
    19. [Lauflicht002]
    20. Steckdose 1 an
    21. warten 1000ms
    22. Steckdose 1 aus
    23. warten 1000ms
    24. Steckdose 2 an
    25. warten 1000ms
    26. Steckdose 2 aus
    27. warten 1000ms
    28. Steckdose 3 an
    29. warten 1000ms
    30. Steckdose 3 aus
    31. warten 1000ms
    32. Steckdose 4 an
    33. warten 1000ms
    34. Steckdose 4 aus
    35. warten 1000ms
    36. [Lauflicht003]
    Du denkst zu kompliziert. :D
    Löse Dein Problem grafisch :!:
    Zeitpunkt t0 Lampe 0 bis 15
    Zeitpunkt t1 Lampe 0 bis 15
    Zeitpunkt t2 Lampe 0 bis 15
    Ich denke, dass alle Steckdosen / Lampen (quasi) gleichzeitig geschaltet werden.
    Da musst Du nur 16 Werte für jeden Zeitpunkt ablegen und eine Wartezeit.
    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!
    hmm...vielleicht seh ich gerade den Wald vor lauter Bäumen nicht...
    ich habe mal das aktuelle Programm angehängt und die Lauflichtfunktion ohne INI zum testen eingebaut. Soweit läuft es aber - so wie ich es programmiert habe sieht es gruselig aus...aber ich weiß gerade nicht wie es besser geht - deshalb die Überlegung mit der INI. sollen natürlich noch ein paar mehr lauflichtfunktionen werden...

    zur info:
    programmstart -> in Form1 unter Comeinstellungen ERST den Button öffnen drücken und danach rechts die Button für die Lauflichter testen....
    Dateien
    Hallo Tobi123.

    Du solltest Dir folgende Frage stellen: Wie soll die Datei funktionieren?

    Möglichkeit 1:
    In jeder Zeile steht ein Befehl (Lampe x ein/aus oder pause).
    Das ergibt dann z.B. folgendes:

    Schalten:<Kanal>=<Zustand>
    <Kanal> kann eine Zahl von 0 bis 15 sein (sollte es zumindest)
    <Zustand> kann 0 (für aus) oder 1 (für ein) sein. Das geht auch mit "True" oder "False", anstelle von "1" oder "0".

    Pause:<Dauer>
    <Dauer> ist eine Zahl, die die Wartezeit in Millisekunden angibt.

    Spoiler anzeigen

    Quellcode

    1. Schalten:0=1
    2. Schalten:1=1
    3. Schalten:2=1
    4. Schalten:3=0
    5. ...
    6. Pause:1000
    7. Schalten:2=0
    8. Pause:500
    9. Schalten:3=1
    10. ...


    Möglichkeit 2:
    In jeder Zeile stehen alle Informationen.
    Also die Zustände für alle 16 Lampen und die Wartezeit.

    <Kanal0><Kanal1>...<Kanal15>:<Dauer>
    <Kanal0> ist der Zustand für den ersten Kanal. Also "0" für aus, "1" für ein (hier sollte man bei Zahlen bleiben).
    <Kanal1> für den zweiten, und so weiter.
    ...
    <Dauer> ist wie beim obrigen die Wartezeit in Millisekunden.

    Wenn bei einem Kanal "*" angegeben wird, dann ändert sich der Zustand nicht. Dadurch spart man sich das Übernehmen der Werte aus der vorigen Zeile und einen Haufen Arbeit, wenn man irgendwo oben eine Änderung vornimmt.

    Spoiler anzeigen

    Quellcode

    1. 00110101;1000
    2. 01*0*01*;500


    Welches Konzept für Dich besser geeignet ist, musst Du herausfinden.
    Das zweite Format ist leichter auszulesen, da es keine komplizierte Syntax hat. Es hat auch den Vorteil, dass man übersichtlicher (weil kompakter) bleibt.
    Dafür ist das erste Format besser lesbar.

    Wichtig, wenn Du Dir ein Format machst: Nimm unnötige Zeichen raus.
    Das hier:

    Quellcode

    1. Name = Wert;

    ist wesentlich schwieriger zu parsen als

    Quellcode

    1. Name=Wert


    Auch sollten Deine Syntax-Zeichen nie als Wert in einer Variable vorkommen. Also ist ein ; zum Trennen von mehreren Einträgen in

    Quellcode

    1. Name1=Wert1;Name2=Wert2;Name3=Wert3

    eher ungeeignet, wenn ein Wert ein ";" beinhalten kann.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Hallo Niko,
    Möglichkeit 1 ist genau das was ich meine. Nur leider weiß ich nicht wie ich das umsetzen soll...

    Was soll ich nehmen? Textdatei? INI? XML?...
    und wie mache ich dann die Auswertung?
    Ich habe auch noch nichts in der Richtung im Netz gefunden.

    würde mich über jede Hilfe freuen

    Tobi
    XML ist eher zum Halten von Datenstrukturen gedacht.
    Überlege Dir, wie Du es abspeichern willst, um es einfach wieder auslesen zu können.

    Die Variante, die ich für viele Projekte verwende ist

    Quellcode

    1. Eintragname:Name1=Wert1;Name2=Wert2;.....

    bzw. wenn es keine komplexen Sachen sind

    Quellcode

    1. Name=Wert


    Da Du keine ";", ":" und "=" Zeichen in den Werten haben wirst, kannst Du die einfache Variante verwenden, und einfach nach den Zeichen splitten. (StringVariable.Split(Zeichen)).

    PS: Ich weiß nicht, wie weit Du da schon bist, aber
    Option Strict On.
    home.arcor.de/eckardahlers/Pro…/Blogs/WarumStrictOn.html

    Denn ich habe die Vermutung, dass Du beim Splitten sowas wie Bla.Split(":") schreiben wirst.
    Die .Split() Funktion erwartet ein Char. ":" ist aber ein String mit der Länge 1.
    Char-Literale gibt man in VB mit ""c an (und zwischen die "" kommt das Zeichen).
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Bei den txt Dateien habe ich gelesen, dass man die ganze Datei einlesen muss und bei INI dateien kann man direkt in bestimmte Zeilen springen.

    Also ich habe 16 Kanäle(K) und jeweils den Status 1/0 dazu.
    Außerdem mindestens 2 Wartezeiten sagen wir Timer.
    In eine Datei sollen mehrere Programmabläufe [Lauflicht001]

    [L001]
    T1=1000 'Timer 1 mit 1000ms definieren
    T2=500 'Timer 2 mit 500ms definieren
    K1=1 'Kanal 1 setzen
    T1 'Wartezeit von Timer 1
    K1=0 'Kanal 1 reset u.s.w.
    T2
    K2=1
    T1
    K2=0
    T2
    [L002]
    'nächstes Programm...

    funktioniert die Splitfunktion mit INI Dateien?
    Ich denke mal ich muss jede Zeile einzelnd einlesen, trennen und "verarbeiten" und dann die nächste Zeile. Mit diesem Code lande ich immer in der letzen Zeile meiner test.txt.

    Dim pfad As String = "c:\test.txt"

    For Each zeileKomplett As String In IO.File.ReadAllLines(pfad)
    Dim zeileSplit() As String = zeileKomplett.Split("="c)
    Select Case zeileSplit.Length

    Case Is < 2
    Debug.WriteLine(zeileKomplett & " -> Ungültig")
    Case Is > 2
    Debug.WriteLine(zeileKomplett & " -> Nicht eindeutig!")
    Case Else
    TextBox1.Text = ("Name: " & zeileSplit(0) & " Wert: " & zeileSplit(1))
    End Select
    Next
    Also ich finde, das Prinzip, mehrere Abläufe in einer Datei zu hinterlegen, etwas komisch. Für mich wäre es praktikabler eine Datei für jedes Programm zu haben.
    Ist aber Ansichtssache.

    Egal, ob Du eine Ini-Datei oder ein eigenes Format hast. Du musst es selbst auslesen (Für Inis gibt's eine API, aber das wäre unnötig). Deshalb lohnt es sich, ein eigenes, einfach auszulesendes Format zu verwenden.

    Da Du
    Bei den txt Dateien habe ich gelesen, dass man die ganze Datei einlesen muss und bei INI dateien kann man direkt in bestimmte Zeilen springen.
    geschrieben hast:
    Bei Ini-Formaten wird auch nur entweder in der Datei gesucht, oder alles eingelesen und dann nach einem Schlüssel gesucht.


    PS: Die Dateiendung ist für den Inhalt irrelevant. Du kannst auch den Inhalt einer MP3-Datei in eine Datei mit der Endung .doc speichern.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    @Tobi123: Du vermengst Teilprobleme miteinander und schaffst dadurch nur Chaos.
    1. Problem: Wie steuere ich meine Steckdosen / Lichter an?
    2. Problem: Wie generiere ich Daten, um das ganze dynamisch zu machen.
    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!

    RodFromGermany schrieb:

    RodFromGermany schrieb:
    @Tobi123: Du vermengst Teilprobleme miteinander und schaffst dadurch nur Chaos.
    1. Problem: Wie steuere ich meine Steckdosen / Lichter an?
    2. Problem: Wie generiere ich Daten, um das ganze dynamisch zu machen.
    hmmm,
    also ich steuere bereits die Steckdosen / Lichter erfolgreich an, wie im Testprogramm zu sehen ist (auch als Lauflicht) - ist also kein Problem mehr.
    Zum Thema Daten generieren hat Niko schon gute Tips zum Aufbau einer Datei gegeben. Die einzige Frage ist nun noch, wie ich die Datei(en) in das vorhandene Programm eingebunden bekomme. Aber auch da hat Niko bereits einen Ansatz gegeben.

    Ich denke schon dass ich auf dem richtigen Weg zur Problemlösung bin.