TIA SCL. Zählaufgabe Problem

D4K!ZZ4

Level-1
Beiträge
149
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Gemeinde,

Ich habe ein kleines Problem bei meinem aktuellen Projekt.

Es handelt sich um eine Handbetätigte Produktionsanlage.

Der Bediener entscheidet nach einmaligen Prozessablauf ob er das Bauteil ablegt oder ausschläußt als Ausschuss.

Ich muss jetzt irgendwie detektieren ob in den letzten 50 Produzierten Teilen 5 ausgeschläuscht wurden und infolge dessen die Anlage sperren.

Habt ihr einen Ansatz wie ich das anpacken könnte?

Ich dachte jetzt schon an ein Schieberegister das für Gutteile eine 1 Schreibt und Ausschus eben eine null und dann eben nach den nullen detektieren.

Oder habt ihr andere Ideen für mich?

Ich arbeite mit SCL.

Zwischenzeitlich meine erste Idee.
Code:
// Berrechnung Anlagenstop nach 3 NIO Teilen in den letzten 20 Teilen

// Array Schreibschleife
IF #E_IMP_NIO AND NOT #HM9 THEN
  #NIO_20_RING[#array_index] := false;
  #array_index := #array_index +1;
  ;
END_IF;
#HM9 := #E_IMP_NIO;

IF #E_IMP_AL AND NOT #HM10 THEN
  #NIO_20_RING[#array_index] := true;
  #array_index := #array_index +1;
  #NIO_20_RING[#array_index] := true;
  #array_index := #array_index +1;
  ;
END_IF;
#HM10 := #E_IMP_AL;

IF #array_index >= 20 THEN
  #array_index := 1;
  ;
END_IF;


// Array Leseschleife

#array_index_2 := #array_index_2 +1;

IF #NIO_20_RING[#array_index_2] THEN
    // IF Statement
    ;
ELSE #NIO_20_ERR_CNT := #NIO_20_ERR_CNT +1 ;
END_IF;
  
IF #NIO_20_ERR_CNT >= 3 THEN
  #M_Stop_3in20 := true;

END_IF;

IF #array_index_2 >= 20 THEN
  #array_index_2 := 1;
  #NIO_20_ERR_CNT := 0;
  ;
END_IF;

// Test Reset Stop Merker
IF "Tag_8" THEN
  #M_Stop_3in20 := false;

END_IF;

Ich bin was SCL angeht noch anfänger, also weiß ich nocht nicht ob der Code so Sinnvoll ist.
Konnte ihn auch no ned testen.

Grüße Chris
 
Zuletzt bearbeitet:
Hi Chris

im Prinzip ganz gut, aber hi und da noch Fehler drin.
Mir ist z.B. nicht klar, wie du zu deiner Aussage 3 von 20 kommen willst.

Ich würde das in etwa so anpacken. Ein Array of Bool und ein "Zeiger" in dasselbe und einen Zähler.
Code:
buffer : array[1..30] of bool
index : int := 0;
counter : int := 0;

Im Ring-Puffer buffer werden die Ausschussteile mit true markiert. Zu beginn ist im buffer ja noch alles false :)
Wenn ein Ausschussteil vorliegt, dann wird das indexte Teil true und der counter inkrementiert.
Steigt der Counter über die Schwelle (von 3 oder 5) dann hisst du eben die weise Flagge :)
Dann wird auch der index inkrementiert und der Umlauf beachtet
Nun wird wenn das indexte Teil true ist, der counter wieder dekrementiert. Damit wird vermieden, dass die alten Teile, die aus dem Ringpuffer raus fallen immer noch gezählt sind.

Das sollte es sein. Also in Code etwa so (ohne Garantie auf die Syntax)
Code:
if #müll then
    #buffer[index] := true;
    #counter := #counter + 1;
    if #counter > 3 then
        #jetzt_sind_es_zu_viele := true;
    end_if
end_if

#index := #index +1;
if #index > 30 then
    #index := 1;
end_if;

if #buffer[#index] then
   #counter := #counter - 1;
end_if;

'n schön' Tach auch
HB
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich dachte jetzt schon an ein Schieberegister das für Gutteile eine 1 Schreibt und Ausschus eben eine null und dann eben nach den nullen detektieren.
[...]
Ich bin was SCL angeht noch anfänger, also weiß ich nocht nicht ob der Code so Sinnvoll ist.
Deine Lösungsidee ist schon ganz OK, ich würde allerdings für Schlechtteile eine 1 schreiben. (kannst Du aber natürlich machen wie Du willst bzw. mußt.)
Das mit SCL wird schon. Blos nicht so kompliziert denken.

  • Liste für 50 Teile (Schieberegister oder besser Ringpuffer, jeweils Array of BOOL)
  • JEDES Teil muß mit IO oder NIO eingetragen werden (nicht nur die NIO!)
  • wenn ein neues Teil in die Liste kommt, dann mit Schleife die NIO zählen. (oder NIO des neuen Teils addieren und NIO des rausfallenden Teils abziehen)
  • Summe NIO > max tolerierbare NIO vergleichen
Code:
FUNCTION_BLOCK FB10
// Berechnung Anlagenstop nach 5 NIO Teilen in den letzten 50 Teilen

VAR_INPUT
  IN_neues_Teil : BOOL ;
  IN_neu_IO_NIO : BOOL ; // 0=IO / 1=NIO
  IN_Reset : BOOL ;
END_VAR
VAR_TEMP
  i : INT ;
  ex_IO_NIO : BOOL ;
END_VAR
VAR
  Liste : ARRAY [1..50] OF BOOL ;
  Listindex : INT := 1 ;
  NIO_count : INT ;
  NIO_max : INT := 4 ; // max zulässige Anzahl NIO-Teile per 50 Teile
  Stop_NIO : BOOL ;
END_VAR

  IF IN_neues_Teil THEN  // neues Teil einspeichern
    // Listenzeiger auf ältestes Teil setzen
    Listindex := (Listindex MOD 50) + 1 ;

    // Zustand des herausfallenden Teils merken, falls benötigt
    ex_IO_NIO := Liste[Listindex] ;

    // Zustand neues Teil einspeichern
    Liste[Listindex] := IN_neu_IO_NIO ;

    // NIO-Teile in Liste zählen
    NIO_count := 0 ;
    FOR i := 1 TO 50 DO
      IF Liste[i] THEN    //wenn NIO
        NIO_count := NIO_count + 1 ;
      END_IF;
    END_FOR;

  END_IF;

  IF IN_Reset THEN  // Reset - alle 50 Teile IO setzen
    Listindex := 1 ;
    NIO_count := 0 ;
    FOR i := 1 TO 50 DO
      Liste[i] := FALSE ;
    END_FOR;
  END_IF;

  // "zu viele NIO"-Signalisierung
  Stop_NIO := NIO_count > NIO_max ;

END_FUNCTION_BLOCK

Harald
 
Hallo Harald und HB,

Danke für eure Antworten. Ich werd mir das nochmal zu gemüte führen.

Ich werd unter umständen darauf zurück kommen.

Ich werde mal meinen Code an der Anlage testen und mal meine Erfahreungen berichten.

Würde ganz gerne meinen Code zum laufen bekommen.

Aber vielen vielen Dank auf jeden Fall.
 
Zurück
Oben