B&R Schieberegister?

Anaconda55

Level-1
Beiträge
301
Reaktionspunkte
6
Zuviel Werbung?
-> Hier kostenlos registrieren
Habe vor eine Prüfstation zu programmieren.

Es ist ein inkrementargeber für ein Band vorhanden wo sich einzelne Schrauben drauf befinden.

Ablauf wird folgender sein:

Wenn die Triggerlichtschranke belegt ist wir ein Teil gespeichert, das dann wenn es bei einer Kamera ist die Kamera triggert und dann bekommt die Steuerung von der Kamera IO oder NIO Teil. Je nachdem wird dann ein Teil an Position 1 oder 2 abgeblasen.

Sollte man das ganze über ein Schieberegister machen?
Es kann sein das die Lücken zwischen den Schrauben unterschiedlich sind, sowie die Schraubenabmessungen.

Wie würdet ihr soetwas lösen?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
B&R beherrscht ST wird aber in Automation Basic geschrieben.
Fifo okay.
Was noch dazukommt ist wenn man auf das Ergebnis wartet bereits ein neues Teil oder mehere für die Kamera getriggert wird/werden ...
 
Ja sowas habe ich mir schon überlegt, aber wie mache ich es mit den Positionen.

z.B. so:

Array[100]

Bei der TriggerLS folgenden Wert setzen:

Array[1].Bauteilstatus=0
Array[1].Position=0
Array[1].Belegt=TRUE

Trigger Kamera auslösen über eine Schleife die das Array durchläuft und nach Position z.B. 1100 sucht. Wenn True dann Kamera triggern und Status auf 8 (Wartezustand setzen)

Array von hinten nach vorne durchlaufen und abfragen ob Status 8 wenn Status 8 zwischen Kamera und Abblasposition dann IO oder NIO zuweisen, IO Status 1.

Beim Ausblasen genau die gleiche Verfahrensweise:

Abblasen 1 bei 1600. Wenn Position stimmt und Status 1 dann Abblasen und Belegt auf 0 setzen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich würde es vielleicht in etwa so machen :
Kommt ein Teil (steigende Flanke der 1. Lichtschranke) dann merkst du dir den aktuellen Zählwert der Zählerkarte, an der der Inkrementalgeber angeschlossen ist in der ersten freien Speicher eines ARRAY's.

Zyklisch scannst du die Eintrags-Positionen dieses Array's ob ein gespeicherter Wert plus dem Offset deiner Bearbeitungsposition dem aktuellen Zählerstand entspricht. Ist dem so, dann lösst du die jeweilige Aktion aus.

Genauso kannst du dann mit den weiteren Positionen verfahren ...

Gruß
LL
 
Ja, dass ist auch eine Möglichkeit.

Man muss natürlich noch den Überlauf der Zählermoduls beachten.

Bei der ersten Lichtschranke muss ich es dann aber so machen dass ich bei fallenden Flanke und steigende Flanke zähle, dadurch den Druchmesser der Schraube ermittele und diese Position im Array speichere.

Sollte ja möglich sein?!
 
Ich würde das ganz ähnlich wie Larry machen.

Angenommen der Inkrementalgeber liefert fortlaufend einen Vorzeichenlosenwert (z.B. UDINT oder DWORD).

Dann kann man den Detlawert errechnen (das klappt auch beim Überlauf).
Code:
Delta :=  Neuerwert - Gespeicherterwert ;
Wenn der Delta-Wert nun in einem Toleranzfenster zu gewünschten Position liegt kann der Aktor angesteuert werden.

Der Ablauf wäre dann wie folgt:

Immer wenn der Trigger ausgelöst wird, wird ein Eintrag in den FIFO mit dem aktuellen Inkremental wert gemacht.

Wenn mindestens ein Eintrag im FIFO ist wird dieser gelesen und in jedem SPS-Zyklus der Delta-Wert gebildet wenn dieser Wert im Fenster liegt wird der Aktor angesteuert. Wenn der FIFO nicht leer ist wird ein neuer Wert daraus genommen und das ganze beginnt von vorne.

Um nun mehrere Abblaspositionen (Gut, Schlecht, sonstwas) verwalten zu können würde ich einfach für jede Abblaspositionen einen eigenen FIFO-Speicher einrichten.
 
Zuletzt bearbeitet:
Muss man nicht. Vorausgesetzt der Inkrementalwert ist Vorzeichenlos.
Verstehe ich nicht, kannst Du mir das genauer erklären?



Angenommen ich setze den Wert bei 1500 die Zielposition ist 1800 bei 1750 wird der Zähler auf 0 gesetzt. 1500 - 1800 währen 300 da er aber zurückgesetzt wird währe er bei 50. 1500 - 50 währen dann 1450.
 
Zuletzt bearbeitet:
Verstehe ich nicht, kannst Du mir das genauer erklären?

Meine Aussage stimmt auch nur unter der Voraussetzung das der Abstand zwischen dem Start- und Zielpunkt kleiner eines vollen Inkrementzykluses ist.

Für diesen Fall:

Gilt die Differenz zweier werte ist absolut gesehen gleich.

Hier mal das Beispiel mit Byte (USINT):

Code:
Delta := Neuerwert - Alterwert;

Code:
0 := 100 - 100;
1 := 101 - 100;
100 := 200 - 100;
155 := 255 - 100;
156 := 0 - 100;
157 := 1 - 100;
206 := 50 - 100;


Nun zu dem Fall das der Abstand größer eines Inkrementalzykluses ist dann kann man den von Hand zu Fuß selber bauen.

In jedem SPS-Zyklus das Delta zum vorhergehenden SPS-Zyklus berechnen und den immer auf eine ausreichend große Variable um kopieren in dem man z.B. die Inkremente auf mm umrechnet und diese dann in eine UDINT bzw. DWORD Variable kopiert.... ist das nun verständlich?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja das ist mir jetzt schon klar.

Allerdings funktioniert das nicht wenn in dieser Strecke der Inkrementalwert 2mal oder öfters auf 0 gesetzt wird.

Eventuell könnte ich es so machen?

Bandtaktvorgabe = 5
iDiff = Inkremental - InkrementalALT

if iDiff >= Bandtaktvorgabe then
Bandtakt=true
InkrementalALT = InkrementalALT + Bandtaktvorgabe
else
Bandtakt=false
endif


Bei jedem Bandtakt setze ich dann die Positionen im Array um Bandtaktvorgabe hier 5 hoch.
 
...
Nun zu dem Fall das der Abstand größer eines Inkrementalzykluses ist dann kann man den von Hand zu Fuß selber bauen.

In jedem SPS-Zyklus das Delta zum vorhergehenden SPS-Zyklus berechnen und den immer auf eine ausreichend große Variable um kopieren in dem man z.B. die Inkremente auf mm umrechnet und diese dann in eine UDINT bzw. DWORD Variable kopiert.... ist das nun verständlich?

Also wars doch nicht verständlich ;o(

Hier mal in Codeform:
Code:
(* Alles was nicht explizit angegeben ist entspricht dem Type UDINT *)

FaktorInkrementeProZehntelmillimeter := InkrementeProUmdrehung * 10 / REAL_TO_UDINT(UDINT_TO_REAL(DurchmesserInMillimeter) * PI); (* muss nicht zyklisch berechnet werden PI idt vom Typ Real *)


DeltaInkremente := InkrementeAktuell - InkrementeLetzerZyklus;
InkrementeLetzerZyklus := InkrementeAktuell;

DeltaZehntelmillimeter := DeltaInkremente / FaktorInkrementeProZehntelmillimeter;

Neuerwert := Neuerwert + DeltaZehntelmillimeter;

Delta := NeuerWert - GespeicherterWert; (* Der Gespeicherte Wert stammt aus dem FIFO *)

InPosition := ((Delta < (Sollposition + Toleranz)) AND (Delta > (Sollposition - Toleranz)); (*InPos ist vom Typ Bool*)
 
Die Kreiszahl (Pi)
372f5cb30e3451a55edf154be4308773.png
 
Also da stimmt jetzt was nicht weil z.B. bei UDINT folgendes rauskommt

NeuerWert:=0
GespeicherterWert:=10

Delta := NeuerWert - GespeicherterWert;

Delta Ergebnis = 4294967286

Das heißt das ich nie in Position sein kann ...
 
Zurück
Oben