Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 20

Thema: 4 Werte sortieren und Priorität ausgeben

  1. #1
    Registriert seit
    06.03.2015
    Beiträge
    5
    Danke
    1
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo,

    Ich muss ein FB erstellen an dem man an vier Eingängen vier REAL-Werte anlegen kann. Die vier Werte gehören jeweils zu einer Anlage.

    Jetzt muss an 4 Ausgängen ein Integer-Wert ausgeben werden, der die Priorität ausgibt (1-4)

    Umso kleiner die Zahl am Eingang desto höher die Priorität.

    Beispiel

    Eingang Ausgang

    1 20,5 3
    2 36,4 4
    3 0,63 1
    4 9,20 2

    Gibt es da einen fertigen Baustein? Da ich nicht gut programmieren kann.

    Vielen Dank für eure Hilfe
    Angehängte Grafiken Angehängte Grafiken
    Zitieren Zitieren 4 Werte sortieren und Priorität ausgeben  

  2. #2
    Registriert seit
    25.11.2010
    Ort
    OWL
    Beiträge
    745
    Danke
    27
    Erhielt 164 Danke für 142 Beiträge

    Standard

    Dann programmiere doch schlecht. Hauptsache, der FB funktioniert.

  3. #3
    Registriert seit
    16.03.2014
    Beiträge
    358
    Danke
    74
    Erhielt 45 Danke für 38 Beiträge

    Standard

    Hallo Rainer123,
    es gibt unzählige Möglichkeiten:
    Beispiele:
    a) Du hast 3 Merker und gehst mit 3 verschachtelten if / and / and Abfragen durch die ersten 3 durch und suchst den Kleinsten und merkst dir das.
    Anschl. durch die nächsten 2 mit beachtung des vorigen Merkers, das spart Rechenzeit.
    Beim 3.ten angekommen ergibt sich der letzte durch Logik

    b) Du nimmst dir den Array-Sort aus der OSCAT und fütterst ihn mit deinen Werten und Voila, fast fertig.

    3) Du machst alles selber und "lernst" ggf. dabei

    LG
    Shrimps

  4. #4
    rainer123 ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    06.03.2015
    Beiträge
    5
    Danke
    1
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Vielen Dank für die schnellen Antworten.

    Kannst du mir Beispiel a) genauer erklären?

    Vielen Dank

  5. #5
    Registriert seit
    16.03.2014
    Beiträge
    358
    Danke
    74
    Erhielt 45 Danke für 38 Beiträge

    Standard

    Hi Rain123,
    ich war etwas voreilig.
    Du brauchst keine Merker sondern nur die Vergleichslogik.

    Nachfolgend ein kleines funktionierendes Programm, welches ich leider nich kommentiert habe.
    Wenn du es magst, baue das als FB um und fertig...
    Die Variable bOnce ist als Schrittkette gedacht...

    LG
    Shrimps
    Code:
    PROGRAM MAIN
    VAR
        rWert1 : REAL := 20.5;
        rWert2 : REAL := 36.4;
        rWert3 : REAL := 0.63;
        rWert4 : REAL := 9.2;
        iOut1    : BYTE;
        iOut2    : BYTE;
        iOut3    : BYTE;
        iOut4    : BYTE;
        bOnce    : BOOL := TRUE;
    END_VAR
    
    IF bOnce THEN
    
    iOut1 := 4;
    iOut2 := 4;
    iOut3 := 4;
    iOut4 := 4;
    
    iOut1 := iOut1 -1 * BOOL_TO_BYTE(rWert1 < rWert2);
    iOut1 := iOut1 -1 * BOOL_TO_BYTE(rWert1 < rWert3);
    iOut1 := iOut1 -1 * BOOL_TO_BYTE(rWert1 < rWert4);
    
    iOut2 := iOut2 -1 * BOOL_TO_BYTE(rWert2 < rWert1);
    iOut2 := iOut2 -1 * BOOL_TO_BYTE(rWert2 < rWert3);
    iOut2 := iOut2 -1 * BOOL_TO_BYTE(rWert2 < rWert4);
    
    iOut3 := iOut3 -1 * BOOL_TO_BYTE(rWert3 < rWert1);
    iOut3 := iOut3 -1 * BOOL_TO_BYTE(rWert3 < rWert2);
    iOut3 := iOut3 -1 * BOOL_TO_BYTE(rWert3 < rWert4);
    
    iOut4 := iOut4 -1 * BOOL_TO_BYTE(rWert4 < rWert1);
    iOut4 := iOut4 -1 * BOOL_TO_BYTE(rWert4 < rWert2);
    iOut4 := iOut4 -1 * BOOL_TO_BYTE(rWert4 < rWert3);
    
    
    bOnce := FALSE;
    
    END_IF

  6. Folgender Benutzer sagt Danke zu shrimps für den nützlichen Beitrag:

    rainer123 (15.03.2015)

  7. #6
    Registriert seit
    04.03.2011
    Beiträge
    77
    Danke
    15
    Erhielt 6 Danke für 6 Beiträge

    Standard

    oder du machst dein FB gleich variabel, d.h. du packst die REAL - Werte in ein beliebig großes Array und nutzt zuerst einen Sortieralgorithmus (Bubblesort ist da der einfachste) und weißst danach die Prioritäten einfach auf- bzw absteigend zu

    Code:
    FUNCTION _SORT_AR_LREAL_AB : BOOL
    VAR_INPUT
        PT            : POINTER TO ARRAY[1..500] OF LREAL;
        SIZE         : UINT;
    END_VAR
    VAR
        i            : UINT;
        stop            : UINT;
        temp1        : LREAL;
        changed        : BOOL;
    END_VAR
    
        stop        :=SIZE/8;
    
        REPEAT
            changed        :=FALSE;
    
            FOR i:=1 TO (stop - 1) DO
    
                IF pt^[i] > pt^[i+1] THEN
                    temp1    :=pt^[i];
                    pt^[i]    :=pt^[i+1];
                    pt^[i+1]    :=temp1;
                    changed    :=TRUE;
                END_IF
            END_FOR
        UNTIL
            NOT changed
        END_REPEAT
    
        _SORT_AR_LREAL_AB := TRUE;
    Aufruf dann nur über

    Code:
    _SORT_AR_LREAL_AB(ADR(DEIN_ARRAY), SIZEOF(DEIN_ARRAY));
    Es kommt nicht darauf an, mit dem Kopf durch die Wand zu rennen, sondern mit den Augen die Tür zu finden.

  8. #7
    Registriert seit
    25.11.2010
    Ort
    OWL
    Beiträge
    745
    Danke
    27
    Erhielt 164 Danke für 142 Beiträge

    Standard

    Zitat Zitat von shrimps Beitrag anzeigen
    Code:
    iOut1 := iOut1 -1 * BOOL_TO_BYTE(rWert1 < rWert2);
    You made my day. Eleganter kann man 1*1 oder 1*0 kaum subtrahieren.
    Code:
    IF rWert1<rWert2 THEN
       iOut1:=iOut1-1;
    END_IF
    wäre hier nicht nur einfacher zu verstehen, sondern auch schneller in der Ausführung.

  9. #8
    Registriert seit
    16.03.2014
    Beiträge
    358
    Danke
    74
    Erhielt 45 Danke für 38 Beiträge

    Standard

    Hallo StructuredTrash,
    i made your day ist n schönes Dankeschön (Musste erstmal herzhaft lachen)
    Du hast ja recht: Von hinten durchs Knie...
    Aber ich habe folgende Gründe gehabt:
    - Es war mir unklar wie tief der TE in der ST-Sprache drinsteckt und wenn ich hier so mitlese kommen viele "Profis" mit extremen Boolschen daher...
    (Fast alle Bücher zu Thema ST und Codesys haben "unendlich" viel Boolsche Logik drin und man merkt den Autoren das Fehlen von ST-Tiefe an...)
    Dann fand ich es persönlich lustig, wenig Codezeilen zu schreiben...

    - Mir unkar ist allerdings die Abarbeitungsgeschwindigkeit:
    Hier würde ich gerne mehr erfahren wie der Compiler die Logik umsetzt und wo ggf. Vorrang herrscht ?
    Gibts es da irgendwas zum nachlesen ?

    Am liebsten hätte ich dem TE von Anfang an gerne die Sache mit dem Array und der Sortierlogik vorgegeben so wie der andere Kollege hier, aber dies erschien mir
    als zu schwer für den TE ?!

    So long
    Macht Spaß hier
    Shrimps

  10. #9
    Registriert seit
    25.11.2010
    Ort
    OWL
    Beiträge
    745
    Danke
    27
    Erhielt 164 Danke für 142 Beiträge

    Standard

    Ich finde Deinen Lösungsansatz ganz gut, denn zum Sortieren müsste man die Daten in ein FB-internes Array kopieren, wenn man die FB-Schnittstelle nicht ändern will. Ausserdem ist die Sortierung eigentlich gar nicht die Aufgabe des FBs.
    Aber warum versuchst Du, auf Teufel komm raus bedingte Programmbearbeitung zu vermeiden? Das ist doch gerade die Stärke von ST.
    Um die Bearbeitungsgeschwindigkeit wirklich beurteilen zu können, müsste man sich wohl den Assemblercode anschauen. Ich gehe aber mal davon aus, dass ein Sprungbefehl bei heutigen CPUs nicht länger dauert als eine Subtraktion. Und davon hat man bei der bedingten Ausführung im gesamten FB eben nur 6 statt 12.

  11. Folgender Benutzer sagt Danke zu StructuredTrash für den nützlichen Beitrag:

    shrimps (16.03.2015)

  12. #10
    Registriert seit
    29.03.2004
    Beiträge
    5.731
    Danke
    143
    Erhielt 1.685 Danke für 1.225 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Ich habe mal reingeschaut wie groß die Unterschiede der beiden Varianten (Berechnung von shrimp vs. If-then) sind.

    Von der reinen Anzahl der Anweisungen sind beide Varianten fast identisch.
    Bei der If-Variante werden aber nur im ungünstigsten Fall alle Pfade durchlaufen. Dafür hat die Berechnungs-Variante eine konstante Laufzeit. Evtl. ist das sogar bezüglich besserer Ausnutzung der Prozessor-Pipeline schneller, das müsste man aber ausmessen.

    Wenn das Zielsystem eine 32-Bit Architektur besitzt, spart man auch etwas wenn man anstelle des Datentyps Byte ein Integer verwendet.
    Mal abgesehen davon, dass ich persönlich arithmetische Operationen auf dem Typ Byte nicht so gerne sehe.

    Aber ich hätte nicht gedacht, dass BOOL_TO_... doch relativ effizient umgesetzt werden kann. Ich hätte rein von der Lesbarkeit auch zur If-Variante gegriffen.
    Angehängte Dateien Angehängte Dateien

  13. Folgende 2 Benutzer sagen Danke zu Thomas_v2.1 für den nützlichen Beitrag:

    shrimps (16.03.2015),StructuredTrash (16.03.2015)

Ähnliche Themen

  1. Antworten: 2
    Letzter Beitrag: 24.08.2012, 09:44
  2. C++ Datensätze durchsuchen und sortieren
    Von Forumaner im Forum Hochsprachen - OPC
    Antworten: 20
    Letzter Beitrag: 30.06.2008, 22:02
  3. 6 versch. Werte über den Analogausgang ausgeben
    Von MRT im Forum Sonstige Steuerungen
    Antworten: 22
    Letzter Beitrag: 28.01.2008, 12:46
  4. Werte in BCD ausgeben
    Von SPS-Linksfuß im Forum Simatic
    Antworten: 40
    Letzter Beitrag: 22.08.2006, 11:04
  5. Antworten: 0
    Letzter Beitrag: 06.07.2006, 12:55

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •