Problem mit Ringpuffer

nutellahase

Level-2
Beiträge
180
Reaktionspunkte
28
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich bin hier gerade am Verzweifeln...
Habe mir einen Ringpuffer in SCL erstellt. Das Einlesen der Daten funktioniert einwandfrei. Beim Auslesen hab ich ein Problem. Hab schon etliches probiert aber nie kam was brauchbares raus..

Das Problem liegt bei der Variable "daten[index].lesen".

Die Daten werden von außen beschrieben, wenn ein Eingang eine Mindestdauer anliegt. Der (in einem anderen Baustein) abgelaufene Timer flankt mir dann mein Signal "Daten[index].schreiben" und schreibt mir nach der Reihe die Werte in einen DB.

Die FB's wo die Signale herkommen und hingehen werden als Multiinstanzen aufgerufen. Dort wird ein Vergleich durchgeführt ob die Gerätenummer identisch mit einer vorgegebenen Nummer ist. Wenn dem so ist wird ein Ausgang für eine gewisse Dauer angesteuert. Mit der neg. Flanke des TOF's wird mir dann mein Signal "Daten[index].lesen" geflankt.

Anhand des Codes sieht man jetzt ganz gut dass ich das Signal "Daten[index].lesen" benötige, welches ich aber erst bekomme wenn ein Element/mehrere Elemente im Puffer gespeichert ist/sind. Sobald also min. ein Element im Puffer gespeichert wurde sollte es sowas wie einen Initialtrigger geben und danach falls mehrere Werte gespeichert sind einfach mit dem Signal "Daten[index].lesen" fortgefahren werden.

Habs Testweise mal probiert, indem ich per Hand einen Ausgang ansteuere, wenn schon mehrere Daten gespeichert sind. Dann funktionierts (nur dass der Ausgang per Hand halt immer fälschlicherweise angesteuert wird). Die Ausgänge dürfen immer nur nacheinander wie sie im Puffer gespeichert sind angesteuert werden!

Hoffe ich hab mich klar ausgedrückt??



Code:
FUNCTION "Datenpuffer": VOID

VAR_INPUT
    Daten: ARRAY [1..100] OF                                                               (*Datensätze von Geräten 1 bis 30*)
    STRUCT
        Anforderungszeit:DT;                                                               (*Zeit wann angefordert wurde*)
        Saugernummer:INT;                                                                  (*Gerät welches angefordert hat*)
        lesen:BOOL;                                                                        (*Lese das "älteste" Gerät aus dem Puffer*)
        schreiben:BOOL;                                                                    (*Schreibe das "jüngste" Gerät in den Puffer*)
    END_STRUCT;
END_VAR

VAR_OUTPUT
    Datenpuffer: ARRAY [0..99] OF                                                          (*Datenpuffer für 100 Datensätze*)
    STRUCT
        Anforderungszeit:DT;                                                               (*Zeit, für die Visualisierung, wann angefordert wurde*)
        Saugernummer:INT;                                                                  (*Gerät, für die Visualisierung, welches angefordert hat*)
    END_STRUCT;
    Leseindex:INT:=0;                                                                      (*Zeiger an welcher Stelle ausgelesen werden soll*)
    Schreibindex:INT:=0;                                                                   (*Zeiger an welcher Stelle eingelesen werden soll*)
    Elemente:INT:=0;                                                                       (*Anzahl der Datensätze im Datenpuffer*)
    Ueberlauf:BOOL;                                                                        (*wird gesetzt, wenn der Datenpuffer voll ist und Daten eingelesen werden sollen*)
    Unterlauf:BOOL;                                                                        (*wird gesetzt, wenn der Datenpuffer leer ist und Daten ausgelesen werden sollen*)
    aktuelles_Geraet:INT:=0;
END_VAR

VAR_TEMP
    index:INT;
END_VAR

BEGIN

    FOR index:= 1 TO 100 BY 1 DO                                                           (*Durchsuche Listeneinträge 1-100*)
        
        (*Daten in den Puffer schreiben*) 
        
        IF Daten[index].schreiben THEN                                                     (*Fordert eines der 30 Geräte an?*)            
    
            IF Elemente < 99 THEN                                                          (*Ist Platz im Datenpuffer?*)
            Datenpuffer[Schreibindex].Anforderungszeit:= Daten[index].Anforderungszeit;    (*Schreibe Daten an der Schreibindexstelle in den Puffer*)
            Datenpuffer[Schreibindex].Saugernummer:= Daten[index].Saugernummer;            (*Schreibe Daten an der Schreibindexstelle in den Puffer*)
            Schreibindex:= Schreibindex + 1;                                               (*Erhöhe Schreibindex um eins*)
            Elemente:= Elemente + 1;                                                       (*Erhöhe Datensätze um eins*)
               
               IF Schreibindex > 99 THEN                                                   (*sind 100 Werte eingelesen, beginne wieder bei 0*)
               Schreibindex:= 0;
               END_IF;
            
            ELSE
            Ueberlauf:=TRUE;                                                               (*sind 100 Werte eingelesen, aber kein Wert ausgelesen dann melde Überlauf*)
            END_IF;
           
        END_IF;       
                 
        (*Daten aus dem Puffer lesen*)                      
                         
        IF daten[index].lesen THEN
            
            IF Elemente > 0 THEN
            aktuelles_Geraet:= Datenpuffer[Leseindex].Saugernummer;  
            Leseindex:= Leseindex + 1;
            Elemente:= Elemente - 1;
            
              IF Leseindex >  99 THEN
              Leseindex:= 0;
              END_IF;
                                                                        
            END_IF;
        END_IF;
    
    END_FOR;

END_FUNCTION
 
Das Problem liegt bei der Variable "daten[index].lesen".

Anhand des Codes sieht man jetzt ganz gut dass ich das Signal "Daten[index].lesen" benötige, welches ich aber erst bekomme wenn ein Element/mehrere Elemente im Puffer gespeichert ist/sind. Sobald also min. ein Element im Puffer gespeichert wurde sollte es sowas wie einen Initialtrigger geben und danach falls mehrere Werte gespeichert sind einfach mit dem Signal "Daten[index].lesen" fortgefahren werden.
:rolleyes: Die Lösung kann manchmal so einfach sein, wenn man nicht immer über 7 Ecken denkt... mit diesen Code klappts. Fehler ist mir jetzt keiner mehr aufgefallen.

Code:
   (*Daten aus dem Puffer lesen*)                      
        IF Elemente > 0 THEN
        aktuelles_Geraet:= Datenpuffer[Leseindex].Saugernummer;
        IF Daten[index].lesen THEN
            Leseindex:= Leseindex + 1;
            Elemente:= Elemente - 1;
        END_IF;
        END_IF;
Wenn also ein Element in der Liste enthalten ist wird der erste Ausgang angesteuert (und somit auch der Timer und die darauffolgende neg. Flanke). Jetzt muss die Flanke kommen, damit der Index erhöht bzw. ein Element gelöscht wird.
 
Zurück
Oben