Ankündigung

Einklappen
Keine Ankündigung bisher.

Unvorhersehbare Reihenfolge bei der Logikberechnung

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Unvorhersehbare Reihenfolge bei der Logikberechnung

    Hallo, zusammen,

    seit Tagen grübel ich über eine Logik, für die ich in C keine 10 Minuten gebraucht hätte, sie zum implementieren, incl. Rechner hochfahren, compilieren und linken.

    Zur Anzeige des Sicherungszustandes des Hauses möchte ich im InfoDisplay einen 14-Byte-Text anzeigen lassen. Dort soll stehen, ob die BWM aktiv sind, nur die Reed-Kontakte des Erdgeschosses überwacht werden, das Schlafzimmerfenster überwacht wird usw. Letztlich sind insgesamt 9 Bits auszuwerten, von denen ein Teil auch in einem 8-Bit-Wert untergebracht sind.

    Um daraus Text zu generieren, muss ich verschiedenste UNDs und Negationen durchführen. Und ständig schickt mir die Logik die unerschiedlichsten Strings auf den Bus. Also habe ich die Logikinitialisierungsphase überbrückt, mit Textselektoren gearbeitet, hier einen Binärauslöser, dort eine Sperre eingefügt, bis ich endlich nach nur 2 Tagen zu dem Punkt kam, dass bei Zustandsänderung nur noch zwei Texte auf den Bus geschickt wurde, einmal ein falscher, dann der richtige.

    Manche mögen damit zufrieden sein, ich wollte aber verstehen, woran es liegt. Nun bin ich darauf gekommen, dass die Ursache darin liegt, dass die Berechnung der Logikbausteine eben seriell ist und nicht (pseudo)parallel.

    Um das zu verdeutlichen, habe ich eine Testlogik beigefügt. Die Debug-Variable ist zu Beginn 0. Der obere Zweig prüft, ob die Bits 0 und 1 (aka Bit 1 und Bit 2) 0 sind, durch Negation 1, und UNDet diese. Das Ergebnis bedient die Sperre, die letztlich dann aufmacht, wenn die Bits 0 und 1 nicht gesetzt sind. Hinter der Sperre wird 1 auf den Wert addiert. Nach dem ersten Lauf hat die Variable also den Wert 1 und schließt über die nun 0 liefernde UND-Verknüpfung die Sperre, so dass am Ende der Wert der Variable 1 bleiben sollte.

    Denkste. Lt. Eibmon kommt die Veriable locker über 20, bevor endlich mal die Sperre zumacht.

    Nun mögen einige von euch sagen: Ist klar, dass es so ist. Nur bringt dieses Phänomen leider mit sich, dass ich keine Möglichkeit gefunden habe, die diversen UND-Verknüpfungen so zu synchronisieren, dass ein Gatter nicht mehrfach feuert, weil sich die verschiedenen Eingänge nacheinander ändern, weil deren Zulieferer nacheinander berechnet werden. Und damit werden unterschiedliche und häufig auch falsche Texte auf den Bus geschickt, weil eigentlich unwahre Bitkombinationen zwischenzeitlich doch mal kurz wahr waren.

    Wie kann ich das synchronisieren?

    Vielleicht hat jemand das Problem irgendwie gelöst. Vielleicht gibt es auch gar keine Lösung...

    /Tokamak
    Angehängte Dateien
    openHAB 4.2

    #2
    Schönes Thema. Zwar kenne ich mich mit dem HS nicht aus, aber Dein geschildertes Problem ist eins, dass mir in meinem Beruf als FPGA-Entwickler täglich begegnet. Wie Du schon selbst erkannt hast, liegt das Problem an der Tatsache, dass die Einzelsignale, die zum Ergebnis beitragen ungleiche Laufzeiten durch die Logik haben. Du brauchst also so etwas wie einen Takt, der sicherstellt, dass der Ausgang nur dann geschaltet wird, wenn alle Eingangssignale des letzten Logikblockes stabil sind und nicht mehr toggeln. Dafür ist eine Art Registerstufe an den Eingängen und dem Ergebnis erforderlich. Weiß nicht, ob es so etwas im HS gibt. Müßte so eine Art Sample&Hold-Glied sein. Ansteuern müsste man diese Registerstufen mit einer Art Taktsignal...vermutlich am Ausgang auf dem negierten Pegel des Pegels für die Eingangstufen.....alles klar?? Weiß nicht, wie ich es besser erklären soll...vermutlich geben die HS-Experten gleich die bessere Erklärung!

    Gruß,
    Lars

    Kommentar


      #3
      Ein Takt wäre sicher eine Hilfe. Dazu müsste aber mE jeder Logikbaustein einen speziellen Eingang haben, den es leider nicht gibt.

      Es gäbe die letztlich überdimensionierte Möglichkeit, vor jeden Eingang die Sperre zu setzen, und die Sperren eines Bausteins zeitgleich freizugeben. Allerdings fürchte ich, dass man diese Zeitgleichheit genausowenig erreicht.

      Als weitere Möglichkeit könnte man jede Menge Variablen verwenden, die die Ergebnisse eines Bausteins aufnehmen. Und nur bei Wertänderung einer der Variablen (send by change) würde man den nächsten Logikbaustein berechnen. Dann würden final nur Änderungen durchgreifen, was in diesem Fall ausreichen würde. ("Wenn der Konjunktiv schlank machen würde...")

      Hierzu bräuchte ich idealerweise lokale Variablen. Da es die meines Wissens im HS nicht gibt, müsste ich auf interne - globale - Variablen des HS zurückgreifen, was meinem Programmiererherzen, das nach großer Lokalität strebt, widerstrebt. Zur Zeit sehe ich das aber als einzige effektive Möglichkeit.

      Vielleicht gibt es auch andere Lösungen mit HS-Bordmitteln...
      openHAB 4.2

      Kommentar


        #4
        Zitat von Tokamak Beitrag anzeigen
        Manche mögen damit zufrieden sein, ich wollte aber verstehen, woran es liegt. Nun bin ich darauf gekommen, dass die Ursache darin liegt, dass die Berechnung der Logikbausteine eben seriell ist und nicht (pseudo)parallel.

        Es ist genau umgekehrt, dein problem tritt auf weil die Logikbausteine pseudo-parallel und nich seriel ausgeführt werden. Waäre die Ausführung serialisiert dann gäbs dieses Phenomen nicht.

        Allerdings nach meinem Verständnis müsste deine Logk bei 2 stehen bleiben, was offensichltlich nicht der Fall ist. Ich werd mal einige Tests machen...

        Gruss,
        Gaston

        Kommentar


          #5
          Die Aussage "müsste deine Logk bei 2 stehen bleiben" in meinem vorherigen Post sollte eigentlich lauten "müsste deine Logk spätestens bei 2 stehen bleiben".


          Ich habe die gleiche Logik bei mir getestst und diese bleibt bei 1 stehen. Ich versuche jetzt sie dazu zu bringen erst bei 2 stehen zu bleiben, aber ich sehe nicht wie sie bis 20 laufen könnte. Aber dazu mache ich auch noch einen Test.

          Bist Du sicher dass das KO nicht als remanent gesetzt ist und auch keien andere Verweise hat ?

          Gruss,
          Gaston

          Kommentar


            #6
            Zitat von Gaston Beitrag anzeigen
            Allerdings nach meinem Verständnis müsste deine Logk bei 2 stehen bleiben, was offensichltlich nicht der Fall ist. Ich werd mal einige Tests machen...
            Bei 2? Wenn der Startwert 1 wäre, müsste das Gatter die Sperre schließen, so dass der Wert nicht mehr inrementiert werden würde und damit nie bei 2 ankäme. Man kann argumentieren, dass die 1 eher am Eingang der Sperre vorliegt, als das UND-Gatter die Sperre schließt. Dann müsste es tatsächlich spätestens bei 2 schließen, was natürlich auch schon ein Laufzeiteffekt wäre, den ich in einer reinen Logik nicht berücksichtigen würde.

            Wie oft habe ich mir in den letzten Tagen einen Baustein mit 10 Eingängen und 10 Ausgängen gewünscht, den ich mit selbstgeschriebenen Code füllen kann. Dann wäre ich in 0,nichts fertig.

            Nun bin ich mal gespannt, wie hoch bei dir der Zähler kommt. Allerdings ist das wirklich nur ein Testbeispiel. In der Texterzeugungslogik, von der ich zu Beginn sprach, feuert u.a. ein Logikgatter mehrfach, wenn es mit Werten aus dem Baustein "1Byte -> 8Bit" beschickt wird. Die Ausgänge des Wandlers feuern offensichtlich nacheinander und starten das dahinterliegende UND-Gatter mehrfach.
            openHAB 4.2

            Kommentar


              #7
              Zitat von Gaston Beitrag anzeigen
              Bist Du sicher dass das KO nicht als remanent gesetzt ist und auch keien andere Verweise hat ?
              Ja und ja, zumindest bin ich mir sehr sicher. Ich schaue aber nochmal nach, bin gerade auf Arbeit.

              Wie ich aber zuvor schrieb ist mein Beispiel nur zur Versinnbildlichung. Mein Ausgangsproblem liegt im Mehrfachfeuern eines Gatters, weil die Eingänge unterschiedlich schnell beschickt werden, obwohl alles aus einer einzigen Änderung heraus geschieht.
              openHAB 4.2

              Kommentar


                #8
                Mein Ausgangsproblem liegt im Mehrfachfeuern eines Gatters, weil die Eingänge unterschiedlich schnell beschickt werden, obwohl alles aus einer einzigen Änderung heraus geschieht.
                Das Problem lässt sich doch aber relativ einfach beheben: Mit dem ursprünglichen Ereignis startest du eine Zeitverzögerung (1-2 sek sollte reichen), die dann nach Ablauf der Zeit das endgültig berechnete Ergebnis weiterleitet...
                Gruß, Marc

                Kommentar


                  #9
                  Zitat von MarcNaroska Beitrag anzeigen
                  Das Problem lässt sich doch aber relativ einfach beheben: Mit dem ursprünglichen Ereignis startest du eine Zeitverzögerung (1-2 sek sollte reichen), die dann nach Ablauf der Zeit das endgültig berechnete Ergebnis weiterleitet...
                  Es wird eine interne Variable neu belegt, und deren Bits werden dann direkt in der Texterzeugerlogik ausgewertet. Da kann ich gar nichts zwischenschalten.
                  Tatsächlich habe ich es auch an einer Stelle mit einem Telegrammverzögerer probiert, der ein Bit dieser internen Varbiable auf den Eingang einer Sperre schickte, nachdem sichergestellt war, dass die Sperre sicher entsprechend anderer verUNDeter Bits der gleichen internen Variable geöffnet oder geschlossen wurde. Danach gab es aber wieder eine Verzweigung, mit unterschiedlichen langen Wegen. Das konnte ich bisher nicht auffangen.
                  openHAB 4.2

                  Kommentar


                    #10
                    Da habe ich mich vielleicht nicht ganz klar ausgedrückt:
                    Ich meinte, das nur bei einer Änderung der internen Variablen ein Binärauslöser eine Zeitverzögerung startet, welche dann nach x Sekunden einen weiteren Binärauslöser startet, der das dann vollständig berechnete Endergebnis auf die endgültige Zielvariable weiterleitet. Alle Änderungen, die dazwischen passieren, werden somit nicht weitergeleitet.

                    Die (schönere) Lösung wäre natürlich ein selbstgebastelter Logikbaustein, der bei Änderung des Eingangswertes genau den richtigen Text erzeugt...
                    Ich habe mich auch erst gescheut, Logikbausteine zu erstellen. Im Endeffekt ist das aber manchmal sogar einfacher als eine recht Komplexe Logik im GLE zu erstellen, gerade wenn es um die Auswertung von einzelnen Zuständen geht...
                    Gruß, Marc

                    Kommentar

                    Lädt...
                    X