# Dezimalzahl in Datenbaustein laden



## Alexus85 (30 September 2010)

Servus Leute!

Ich hab hier ein Programm, welches zwar funktioniert aber zu umständlich (Größe) geschrieben ist.
Folgendes Problem:
Ein Eingang, Bsp. E0.1, soll bei einem Sprung 0->1 eine Dezimalzahl, Bsp. 1, in einen Datenbaustein schreiben.
Wenn ein weiterer Eingang, Bsp. E0.2 ebenfalls einen solchen Sprung erfährt, soll die Zahl, Bsp. mit 2, im Datenbaustein überschrieben werden.

Ich hab das mal versucht mit Sprüngen zu verwirklichen....

------------------
FC1:

U E 0.1
UN M 0.1
SPB _001

U E 0.2
UN M 0.2
SPB _002
SPA _100

_001: L 1
T DB1.DBW0
SPA _100

_002: L 2
T DB1.DBW0
SPA _100

_100: BE

------------------

FC2:

U E 0.1
S M 0.1
UN E 0.1
R M 0.1

U E 0.2
S M 0.2
UN E 0.2
R M 0.2

------------------

Die ganze sache funktioniert wie ich es mir vorgestellt hab. 
Jetzt zum PROBLEM:
Ich habe nicht zwei Eingänge sonder weit über 100.
Daher würde ein ewig langes Programm entstehen, was ich umgehen möchte.

Habt ihr einen Tipp wie ich das ganze einfacher gestallten kann?
Wichtig ist vorallem, dass der Wert immer vom aktuellsten Eingangs-Sprung überschrieben wird.

Ich sag jetzt schon mal Danke für eure Hilfe!!
MfG
Alex


----------



## Verpolt (30 September 2010)

Hallo,



> Jetzt zum PROBLEM:
> Ich habe nicht zwei Eingänge sonder weit über 100.



Und was soll passieren, wenn 12 Eingänge auf einmal anstehen?

oder kommt sowas nie vor?


----------



## vierlagig (30 September 2010)

```
*
//Adressregister initialisieren
      LAR1  P#0.0
//Schleife vorbereiten
      L     200
next: T     #iLoopCounter
//Eingang Abfragen
      U     E [AR1,P#0.0]
      SPBN  nich
//Nummer berechnen und ausgeben
      L     -1
      L     #iLoopCounter
      *I    
      +     200
      T     #iNumber
//Adressregister erhöhen und solange Schleifenzähler > 0 zurück zu next
nich: +AR1  P#0.1
      L     #iLoopCounter
      LOOP  next
```


----------



## M-Ott (30 September 2010)

@4L
Damit erwischst Du "nur" den gesetzten Eingang mit der höchsten Adresse aber nicht zwangsläufig den, der als letzter gekommen ist.

Besser wäre:


```
*
//Adressregister initialisieren
      LAR1  P#0.0
//Schleife vorbereiten
      L     200
next: T     #iLoopCounter
//Eingang Abfragen
      U     E [AR1,P#0.0]
  [COLOR=red]    FP    M[AR1,P#0.0][/COLOR]
      SPBN  nich
//Nummer berechnen und ausgeben
      L     -1
      L     #iLoopCounter
      *I    
      +     200
      T     #iNumber
//Adressregister erhöhen und solange Schleifenzähler > 0 zurück zu next
nich: +AR1  P#0.1
      L     #iLoopCounter
      LOOP  next
```
[/QUOTE]


----------



## vierlagig (30 September 2010)

M-Ott schrieb:


> @4L
> Damit erwischst Du "nur" den gesetzten Eingang mit der höchsten Adresse aber nicht zwangsläufig den, der als letzter gekommen ist.



ich nenne das "room for improvement" 

aber wenn schon, dann 


```
*
//Adressregister initialisieren
      LAR1  P#0.0
[COLOR="Red"][B]      AUF   DB [#iDBNo][/B][/COLOR]
//Schleife vorbereiten
      L     200
next: T     #iLoopCounter
//Eingang Abfragen
      U     E [AR1,P#0.0]
      FP    [COLOR="red"][B]DBX[/B][/COLOR][AR1,P#0.0]
      SPBN  nich
//Nummer berechnen und ausgeben
      L     -1
      L     #iLoopCounter
      *I    
      +     200
      T     #iNumber
//Adressregister erhöhen und solange Schleifenzähler > 0 zurück zu next
nich: +AR1  P#0.1
      L     #iLoopCounter
      LOOP  next
```

laut seiner sprungverteilung wollte er aber die höchste adresse, oder?


----------



## vierlagig (30 September 2010)

vierlagig schrieb:


> laut seiner sprungverteilung wollte er aber die höchste adresse, oder?



nope... er wollte die niedrigste ... das geht natürlich nicht... das kann ich nicht lösen


----------



## M-Ott (30 September 2010)

Perfekt! 



Alexus85 schrieb:


> ...dass der Wert immer vom aktuellsten Eingangs-Sprung überschrieben wird.


 
Er wollte aber den aktuellsten!


----------



## PN/DP (30 September 2010)

Der FC1 von Alex ermittelt - im Gegensatz zu seiner Erklärung - die niedrigste Eingangsnummer, die gerade "springt".
Was will er wohl tatsächlich? Die Nummer des "aktuellsten Sprungs"? Was soll passieren, wenn es mehrere "aktuellste" gibt?

Es scheint irgendeinen seltsamen metaphysischen Zusammenhang zu geben ... Programmierer, die sich nicht so eindeutig 
ausdrücken können, schreiben ziemlich oft auch solchen Code:

```
U E 0.1
S M 0.1
UN E 0.1
R M 0.1
```
Das kommt womöglich davon, das die nur in Setzen und Rücksetzen denken können?

Auf diese geniale Weise kann man schon mal sehr viele Zeilen Code einsparen:

```
U E 0.1
= M 0.1
```

@Alexus85
Besser noch, Du schaust Dir mal den Flanken-Befehl *FP* an, das spart noch mehr Codezeilen.
Und wenn Du platzsparend gleich Word- oder Doppelwordweise die Flankenerkennung durchführen willst,
da haben wir hier auch ein FAQ dazu.

Und wenn Du nochmal genau beschreiben könntest was Du brauchst, dann gibt es sicher eine noch kürzere Lösung.

Harald


----------



## vierlagig (30 September 2010)

PN/DP schrieb:


> Das kommt womöglich davon, das die nur in Setzen und Rücksetzen denken können?



ich würds ja aufs alter schieben, wenn die 85 da nicht stehen würde ... früher gabs doch och nur flip-flops


----------



## vierlagig (1 Oktober 2010)

Mordor_FRI schrieb:


> und wie wäre dies so allgemein gefragt eben aus dem Ärmel mit einer Movebox ?
> Eingang mit FP als Eneable und die Zahl in den DB gehauen?



und das ganze mal 100 ... bausteinende erreicht ...

welche sprünge meinst du eigentlich?


----------



## Mordor_FRI (1 Oktober 2010)

*Sprünge*

Mein Chef sagt 


> Je mehr sprünge im Programm sind um so unfähiger ist der Programmierer


Er mag eh kein AWL

Manchmal muss man springen aber im ernst ich habe auch mal ein Programm mit vielen sprüngen gehabt --> IBN totales desaster nach 2 Tagen Rückbau auf altstand der Anlage --> Fazit: gelernt nicht so viel zu springen bringt nur Ärger.

und wie wäre dies so allgemein gefragt eben aus dem Ärmel mit einer Movebox ?
Eingang mit FP als Eneable und die Zahl in den DB gehauen?

nur ein Gedanke nicht gleich Hauen


----------



## Alexus85 (1 Oktober 2010)

Also zunächst mal vielen Dank für die große Beteiligung an meinem Problem. Ich bin mir sicher ihr werdet mir helfen können.

Zur Erklärung meines umständlichen, bzw. schlechten Programmierungsstils kann ich nur sagen, dass ich das nicht hauptberuflich oder hobbymäßig, und somit oft mache. Ich habe weder einen Kurs belegt und muss mich stets neu einlesen und einarbeiten. Es fehlt mir also auch die nötige Erfahrung umständliche Programmzeilen kompakt und einfach zusammenzufassen.

Da eine genaue Beschreibung meines Problem gewünscht wurde, hier kommt sie:

An ein CP-Modul lässt sich ein Drucker anschließen. In der H.Konfig lässt sich der auszugebene Text in einer Tabelle (SDB) eingeben.
Eine in einem Datenbaustein stehende Nummer gibt an welcher Text aus der Tabelle gedruckt werden soll. Diese Nummern sind ganz normale Dez.Zahlen (2; 13; 240;...)

Jetzt habe ich viele Eingänge (>100). Jeder Eingang soll einer Textzeile entsprechen. Wenn ein Eingang von 0-1 wechselt soll der zugehörige Text gedruckt werden. Wenn ein weiterer Eingang von 0-1 wechselt soll nur dieser und nicht der vorherige gedruckt werden. ---> JA, es könnten auch mehrer Meldungen, wenn auch selten, gleichzeitig kommen. Da wäre es natürlich wünschenswert wenn alle ausgedruckt werden.
Jeder Eingang muss also seine Nummer in diesen Datenbaustein schreiben. 

Jetzt sollte das ganze halt nicht in einem seitenlangen Programmtext enden.

Ich hoffe jetzt ist es noch klare, was ich bräuchte.

Dank euch allen!


----------



## vierlagig (1 Oktober 2010)

*ROFL* *ROFL*

die forensoftware ist geil!

meine antwort auf den beitrag von 8:55 habe ich bereits 8:54 erstellt

*ROFL* *ROFL*


----------



## Gebs (1 Oktober 2010)

Hallo 4L,

bei Deinen Links fehlt noch "WWW."

Kann es sein, dass Du dich mit Lichtgeschwindigkeit bewegst?
Dann kannst Du auch auf Beiträge antworten, die noch nicht geschrieben wurden!:-D

Grüße
Gebs


----------



## Mordor_FRI (1 Oktober 2010)

@ Vierlagig 
Thats Life

Sprünge im Programmcode


----------



## vierlagig (1 Oktober 2010)

Gebs schrieb:


> Kann es sein, dass Du dich mit Lichtgeschwindigkeit bewegst?
> Dann kannst Du auch auf Beiträge antworten, die noch nicht geschrieben wurden!:-D



sieht ja stark danach aus



			
				Mordor_FRI schrieb:
			
		

> Sprünge im Programmcode



und kannst du die aussage von deinem chef noch irgendwie mit argumenten untermauern? ansonsten ist es ja doch nur heiße luft und nicht der mühe wert, diskutiert zu werden


----------



## Mordor_FRI (1 Oktober 2010)

Habe inzwischen einen neuen Chef (Chef = Abteilungsleiter), sollte auch nicht diskutiert werden, war nur ne bemerkung am rande, das man bei sprüngen seeehhrrr vorsichtig sein muss (eigene Erfahrung)


----------



## vierlagig (1 Oktober 2010)

Mordor_FRI schrieb:


> Habe inzwischen einen neuen Chef (Chef = Abteilungsleiter), sollte auch nicht diskutiert werden, war nur ne bemerkung am rande, das man bei sprüngen seeehhrrr vorsichtig sein muss (eigene Erfahrung)



dann berichte doch von deinen erfahrungen, ist doch sicher für einige andere auch hilfreich


----------



## PN/DP (1 Oktober 2010)

Moin Alexus85,

jetzt kann man mit Deiner genauen Aufgabenbeschreibung in Beitrag #12 was anfangen.
Leider habe ich jetzt nicht die Zeit zum helfen, doch vielleicht hilft Dir mittlerweile jemand anders ...

Harald


----------



## Mordor_FRI (1 Oktober 2010)

*Eigene Erfahrung*

@ Vierlagig (und die die es interresiert)
Es ging um eine Filterabsaugung 37 Filter mussten nach einer individuellen Maske abgereinigt werden. Nebenbei Stop der Automatik Handanwahl, Manuelle absaugung, Notfallprogramm sobald ein Filter voll meldet usw. habe nur den Teil des Programmes geschrieben und die VISU. (WINCC) 
War mein erstes größeres Programm. Zeit für Inbetriebnahme SA+SO bis 22:00. Habe vorher nur Visual Pascal und ein Wenig C++ programmiert.
Also leicht andere ansätze in der Struktur. hatte im FC nacher  ca 180 Sprünge. Die haben mir das Genick gebrochen. Sprünge wurden nicht sauber ausgeführt etc. Habe nacher alles "neu" geschrieben und auf sprünge verzichtet. (Es waren noch 5 über, ging nicht anders) Neue Inbetriebnahme, wieder 2 Tage, SO Mittag lief die Kiste soweit das Produktion anfahren konnte.


----------



## vierlagig (1 Oktober 2010)

PN/DP schrieb:


> Moin Alexus85,
> 
> jetzt kann man mit Deiner genauen Aufgabenbeschreibung in Beitrag #12 was anfangen.
> Leider habe ich jetzt nicht die Zeit zum helfen, doch vielleicht hilft Dir mittlerweile jemand anders ...
> ...



als lösung für mehrere texte würde mir aufbauend auf der schleifenlösung ein meldungspuffer einfallen, der indirekt übers AR2 adressiert wird und alle geänderten zustände einträgt ... nach dem senden an den drucker wird der puffer dann wieder gelöscht...


----------



## vierlagig (1 Oktober 2010)

Mordor_FRI schrieb:


> Sprünge wurden nicht sauber ausgeführt etc.



ich behaupte: die sprünge waren nicht richtig terminiert! das ein sprung nicht ausgeführt wird obwohl z.b. vke=1 ist mir noch nie untergekommen


----------



## PhilippL (1 Oktober 2010)

Zitat von *Mordor_FRI* 

 
_Sprünge wurden nicht sauber ausgeführt etc._

Hi,

#Offtopicmodus AN
Ja das ist dann der Fall wenn ein Bit querliegt und nicht sauber durch die Leitung geht. Oder das Bit hat den Signalzustand 0,5 angenommen.
#Offtopicmodus AUS

Gruß

PhilippL

@all: Sorry mußte einfach sein *ROFL*


----------



## Alexus85 (5 Oktober 2010)

@vierlagig


```
*
//Adressregister initialisieren
      LAR1  P#0.0
[COLOR=Red][B]      AUF   DB [#iDBNo][/B][/COLOR]
//Schleife vorbereiten
      L     200
next: T     #iLoopCounter
//Eingang Abfragen
      U     E [AR1,P#0.0]
      FP    [COLOR=red][B]DBX[/B][/COLOR][AR1,P#0.0]
      SPBN  nich
//Nummer berechnen und ausgeben
      L     -1
      L     #iLoopCounter
      *I    
      +     200
      T     #iNumber
//Adressregister erhöhen und solange Schleifenzähler > 0 zurück zu next
nich: +AR1  P#0.1
      L     #iLoopCounter
      LOOP  next
```

Also ich hab mal den quellcode eigegeben und versucht zu verstehen was da gemacht wird. Ganz bin ich nicht durchgestiegen, aber auf alle fälle hab ich nicht das gewünschte Ergebnis. -> Er zähl mir nämlich im OB die einzelnen Eingänge zusammen. Ich brauch ja eine Anzeige von genau dem Eingang der sich geändert hat.

Ich hab das auch schon mit folgendem versucht zu lösen:


```
L MW 0
L EW 0
XOW 
L EW 0
UW
T DB10.DBW0
```
Das ganze eig. mit DWORD. Damit kann ich sehen wo im EW 0 eine postive Flanke vorkam und mir das in den DB schreiben lassen. 
ABER -> er rechnet ja von binär in dezimal um

E 0.1 : 0000 0001 = 1 -> passt!
E 0.2 : 0000 0010 = 2 -> passt!
E 0.3 : 0000 0100 = 4 -> game over!

Noch hab ich nix passendes gefunden. Ich hoffe ihr habt die entscheidende Idee für die Lösung meines Problems.


----------



## M-Ott (5 Oktober 2010)

Alexus85 schrieb:


> Also ich hab mal den quellcode eigegeben und versucht zu verstehen was da gemacht wird. Ganz bin ich nicht durchgestiegen, aber auf alle fälle hab ich nicht das gewünschte Ergebnis. -> Er zähl mir nämlich im OB die einzelnen Eingänge zusammen. Ich brauch ja eine Anzeige von genau dem Eingang der sich geändert hat.


 
Irgendwas machst Du falsch. Bei mir funktioniert's.

Hast Du vielleicht eine der Lokalvariablen verkehrt deklariert?


----------



## Alexus85 (5 Oktober 2010)

M-Ott schrieb:


> Irgendwas machst Du falsch. Bei mir funktioniert's.
> 
> Hast Du vielleicht eine der Lokalvariablen verkehrt deklariert?



Ich bin davon ausgegangen, dass " i# " für integervariable steht. 
Da hat gleich garnichts funktioniert. Erst alls ich aus den Lokalvariablen allgemein gültige (MW...) gemacht hab hats wenigstens soweit funktioniert, dass er vernünftige Zahlen in den DB schrieb.


----------



## vierlagig (5 Oktober 2010)

```
*
DATA_BLOCK DB 2
TITLE =
VERSION : 0.1


  STRUCT 	
   aFlag : ARRAY  [0 .. 119 ] OF BOOL ;	
  END_STRUCT ;	
BEGIN 
END_DATA_BLOCK

FUNCTION FC 6 : INT
TITLE =
VERSION : 0.1


VAR_INPUT
  iInDBNo : INT ;	
  iInFirstByte : INT ;	
  iNumberOfIns : INT ;	
END_VAR
VAR_TEMP
  iDbNo : INT ;	
  iLoopCounter : INT ;	
  iNumber : INT ;
  dAR1Temp : DWORD ;
  dAR2Temp : DWORD ;	
END_VAR
BEGIN
NETWORK
TITLE =

	  TAR1  #dAR1Temp
	  TAR2  #dAR2Temp

      L     #iInDBNo; 
      T     #iDbNo; 

//Adressregister initialisieren
      L     #iInFirstByte; 
      SLD   3; 
      LAR1  ; 
      LAR2  P#0.0; 
      AUF   DB [#iDbNo]; 
//Schleife vorbereiten
      L     #iNumberOfIns; 
next: T     #iLoopCounter; 
//Eingang Abfragen
      U     E [AR1,P#0.0]; 
      FP    DBX [AR2,P#0.0]; 
      SPBN  nich; 
//Nummer berechnen und ausgeben
      L     -1; 
      L     #iLoopCounter; 
      *I    ; 
      L     #iNumberOfIns; 
      +I    ; 
      T     #iNumber; 
//Adressregister erhöhen und solange Schleifenzähler > 0 zurück zu next
nich: +AR1  P#0.1; 
      +AR2  P#0.1; 
      L     #iLoopCounter; 
      LOOP  next; 
      
      LAR1  #dAR1Temp
	  LAR2  #dAR2Temp

      L     #iNumber; 
      T     #RET_VAL; 

END_FUNCTION

ORGANIZATION_BLOCK OB 1
TITLE = "Main Program Sweep (Cycle)"
VERSION : 0.1


VAR_TEMP
  OB1_EV_CLASS : BYTE ;	//Bits 0-3 = 1 (Coming event), Bits 4-7 = 1 (Event class 1)
  OB1_SCAN_1 : BYTE ;	//1 (Cold restart scan 1 of OB 1), 3 (Scan 2-n of OB 1)
  OB1_PRIORITY : BYTE ;	//Priority of OB Execution
  OB1_OB_NUMBR : BYTE ;	//1 (Organization block 1, OB1)
  OB1_RESERVED_1 : BYTE ;	//Reserved for system
  OB1_RESERVED_2 : BYTE ;	//Reserved for system
  OB1_PREV_CYCLE : INT ;	//Cycle time of previous OB1 scan (milliseconds)
  OB1_MIN_CYCLE : INT ;	//Minimum cycle time of OB1 (milliseconds)
  OB1_MAX_CYCLE : INT ;	//Maximum cycle time of OB1 (milliseconds)
  OB1_DATE_TIME : DATE_AND_TIME ;	//Date and time OB1 started
  sTemp : STRING  [11 ];	
END_VAR
BEGIN
NETWORK
TITLE =

      CALL FC     6 (
           iInDBNo                  := 2,
           iInFirstByte             := 0,
           iNumberOfIns             := 120,
           RET_VAL                  := MW    10);
      NOP   0; 
END_ORGANIZATION_BLOCK
```

übersetz dir mal die quelle...


----------



## Alexus85 (5 Oktober 2010)

Ok, ok, ich nehme alles zurück. Es funktioniert tatsächlich.

Hat wohl auch schon vorher funktioniert, aber eine Frage wäre da noch offen.

Ich hab das ganze über eine Variablentabelle simuliert und mir den DB anzeigen lassen. In dem steht aber immer die Summer der aktiven Eingänge. Aber drucken tut er anscheinend den richtigen. Deswegen dachte ich zunächst auch es funktioniert nicht.

Also 
E0.1 kommt -> im DB steht die 1 -> gedruckt wird Meldung 1 
E0.3 kommt danach -> Im DB steht die 5 -> gedruckt wird Meldung 3

Wie kommt das zu stande?

Seh ich das richtig, dass dieser Quellcode nun ausreicht für Meldungen weit über 100 Stück? Bzw. dass ich das mit #iNumberofIns festlegen muss?

Danke nochmals!!


----------



## M-Ott (5 Oktober 2010)

Geh mal in Deinem Baustein mit dem Cursor auf das 'FP' und drück F1. Das sollte Deine Frage beantworten.


----------



## vierlagig (5 Oktober 2010)

Alexus85 schrieb:


> Also
> E0.1 kommt -> im DB steht die 1 -> gedruckt wird Meldung 1
> E0.3 kommt danach -> Im DB steht die 5 -> gedruckt wird Meldung 3
> 
> Wie kommt das zu stande?



der DB stellt nur den flanken-puffer zur verfügung ... also die helpflags für die auswertung der positiven flankenauswertung der "1000" eingänge, für jeden eingang eine...



Alexus85 schrieb:


> Seh ich das richtig, dass dieser Quellcode nun ausreicht für Meldungen weit über 100 Stück? Bzw. dass ich das mit #iNumberofIns festlegen muss?
> 
> Danke nochmals!!



ja, du kannst weit über 100 eingänge auswerten und gibst die anzahl über #iNumberOfIns an, das startbyte kannst du auch festlegen. einzig auf die arraygröße im db mußt du noch achten.

achtung: viele schleifendurchläufe verbraten natürlich viel zeit! du bekommst auch immer nur den höchsten (neu getriggerten) eingang angezeigt ... hier ist noch room for improvement siehe stichwort meldungspuffer oder schleife nach gefundenen eingang abbrechen, je nachdem was du willst...


----------



## Alexus85 (14 Oktober 2010)

Ich bins nochmal!

Nachdem das Programm auf meiner Test-CPU funktioniert hat, habe ich es jetzt auf die eigentliche CPU geschrieben. 

Und sieh da, es funktioniert NICHT?!

Wenn ein Eingang von 0 auf 1 wechselt wird immer die 0 ausgewertet und nie die Nummer des Eingangs. Das heisst es kommt egal bei welchem Eingang immer die erste Meldung.

Ein zweites Phänomen dem ich auf der Spur bin wäre, dass ich eine Verzögerung von 4 Meldungen habe. Wo kann man das einstellen, dass die Meldungen in Echtzeit, also Meldung kommt -> Meldung wird sofort gedruckt, verarbeitet werden??

Ich hab so das gefühlt kurz vor der Ziellinie zu sein, und etz kleb ich auf der Laufbahn fest


----------



## M-Ott (14 Oktober 2010)

Sind da noch andere Bausteine auf deiner CPU, die evtl. auf die gleichen Speicherbereiche zugreifen, wie Deine Auswertung?


----------



## Alexus85 (14 Oktober 2010)

Alle verwendeten Merker, Merkerworte etc. sind frei und werden nicht beeinflusst. 
Ich hab mir eine VAT-Tabelle angelegt und da kann ich manchmal sogar sehen wie er für einen Bruchteil einer Sekunde die richtige Dezimalzahl reinschreibt. Ich hab iwie das Gefühl dass es mit der Zykluszeit zusammenhängen könnte. Aber wissen tu ich es nicht.


----------



## vierlagig (14 Oktober 2010)

Alexus85 schrieb:


> Alle verwendeten Merker, Merkerworte etc. sind frei und werden nicht beeinflusst.
> Ich hab mir eine VAT-Tabelle angelegt und da kann ich manchmal sogar sehen wie er für einen Bruchteil einer Sekunde die richtige Dezimalzahl reinschreibt. Ich hab iwie das Gefühl dass es mit der Zykluszeit zusammenhängen könnte. Aber wissen tu ich es nicht.



er schreibt die meldung ja auch nur in einem zyklus rein, wenn du sie danach oder vor der nächsten bearbeitung wieder ablöschst, is sie, öhm, WEG!


----------



## Alexus85 (14 Oktober 2010)

ok, heisst das, dass in diesem einem zyklus dann nicht der befehl zum drucken kommt?

Hab immernoch keine Erklärung und vorallem keine Lösung


----------



## vierlagig (14 Oktober 2010)

Alexus85 schrieb:


> ok, heisst das, dass in diesem einem zyklus dann nicht der befehl zum drucken kommt?



wie setzt du den druckbefehl denn ab?


----------



## Alexus85 (14 Oktober 2010)

Da gibt es ein Anstoßbit. Wenn das Bit von 0 auf 1 wechselt wird der Drucker aktiviert.

Ich hab auf der Test-CPU es hier eingesetzt:


//Eingang Abfragen
      U     E [AR1,P#0.0]; 
      FP    DBX [AR2,P#0.0]; 
      FP M1.0                 <----- hier
      SPBN  nich;  

Bei meinem Testprogramm hat das wunderbar funktioniert. Jetzt bei der eigentlichen CPU nicht mehr. Das Anstoßbit ist NICHT vergeben.

Zum Test hab ich es einmal manuell ansteuern lassen, sprich im OB 1:

U E0.3
FP M1.0

-> Dann hats geklappt, aber der Drucker hat Meldung 1 gedruckt


----------



## M-Ott (14 Oktober 2010)

Wenn ich mir den Code von 4L genauer angucke fällt mir was auf:
Versuch mal, die Variable "iNumber" durch ein Merkerwort zu ersetzen.
Dann müsste jede Zahl solange anstehen, bis die nächste Flanke kommt.
Da "iNumber" in 4Ls Code nicht vorbelegt wird, kann sie sogar unter Umständen einen völlig falschen Wert ausgeben, anscheinend hast Du aber "Glück" und bekommst nur "0" zurück.


----------



## Alexus85 (14 Oktober 2010)

@M-Ott

So, ich ab das jetzt mal beherzigt und "iNumber" durch ein MW ersetzt.

Jetzt wenn ichs mir in der VAT-Tabelle ansehe bleibt es halt bestehen bis zum nächsten wechsel -> ok

Trotzdem druckt er immernoch die Meldung für 0 aus!!

Es ist mir echt unerklärlich warum?!?!

Genauso unerklärlich wieso auf der Test-CPU das mit dem Anstoßbit ...

//Eingang Abfragen
      U     E [AR1,P#0.0]; 
      FP    DBX [AR2,P#0.0]; 
      FP M1.0                 <----- hier
      SPBN  nich;  

... funktioniert hat.

Falls das jetzt nicht gehen sollte, wie schreib ich am einfachsten, dass wenn einer der 350 Eingänge kommt, das Anstoßbit kurz auf 1 springt??


----------



## M-Ott (14 Oktober 2010)

Zum Thema 'falsche Meldung':
Erhälst Du denn den richtigen Wert abhängig vom gesetzten Bit?

Zum Thema 'Anstoß-Bit'
FP ...
FP ...
funktioniert, ist aber ungewöhnlich.
FP ...
= ...
hat den gleichen Effekt.
Auf welche CPUs hast Du das Programm bisher aufgespielt?
Vieleicht sind auch die Zykluszeiten auf der Maschine so kurz, dass Dein Signal zu kurz ist, um den Drucker anzustoßen. In dem Fall müsstest Du Dein Anstoßbit verlängern, was aber (je nach Schalthäufigkeit Deiner Eingänge)  dazu führen könnte, dass Dir Signale verloren gehen.


----------



## Alexus85 (14 Oktober 2010)

Also wenn ich ich das Anstoßbit über einen Eingang ansteuere, dann arbeitet auch der Drucker. 
Der Drucker sollte aber anhand des Datenbausteins erkennen welche Meldung er drucken soll. 
Die Nummer im RET_VAL stimmt aber genau mit dem jeweiligen Eingang überein. Wenn ich das MW asu RET_VAL nochmals in einen extra DB schreib steht ebenfalls der richtige Wert.

Die Frage ist, warum übernimmt der Drucker nicht die ihm vorgegebene Zahl aus dem Datenbaustein?


----------



## M-Ott (14 Oktober 2010)

Ehrlich gesagt, klingt das immer mehr, als ob das Porblem nicht in der SPS sondern in Deinem Drucker läge, vor allem, wo Du betonst, dass die Werte alle stimmen.


----------



## Alexus85 (14 Oktober 2010)

Naja, das möcht ich aber ausschließen, weil der Drucker ja an der Test-CPU einwandfrei funktioniert hat. Er druckt ja auch die Teile der anderen Datenbausteine aus, die da wären Datum und Zeit. Zudem druckt er die Meldung 0 sauber aus. 

Och menno, hat doch alles schon so gut funktioniert


----------



## M-Ott (14 Oktober 2010)

Wie lang sind denn auf der Maschinen-CPU und auf der Test-CPU jeweils die Zykluszeiten? Vielleicht liegt hier ja der Hund begraben.


----------



## Alexus85 (14 Oktober 2010)

Bei beiden 150ms

Hab die Zeit sowohl schrittweise bis auf 50ms verkürzt als auch bis auf 300ms verlängert


----------



## vierlagig (14 Oktober 2010)

Alexus85 schrieb:


> Bei beiden 150ms
> 
> Hab die Zeit sowohl schrittweise bis auf 50ms verkürzt als auch bis auf 300ms verlängert



nich die maximale sondern die tatsächliche.
ich geh davon aus, dass der drucker noch busy ist und deswegen alle anderen befehle ignoriert, wo wir wieder auf den, von mir angesprochenen meldungspuffer zurück kommen ...

dass die initialisierung angeblich gefehlt hat ist nicht der grund des nicht funktionieren, da iNumber BESCHRIEBEN wird ... initialisierung ist nur notwendig, wenn die variable lesend verarbeitet wird.


----------



## Alexus85 (14 Oktober 2010)

Bin jetzt nicht mehr vor Ort. Aber wo kann ich die tatsächliche den rauslesen?


----------



## M-Ott (15 Oktober 2010)

Im Diagnosepuffer.
(Simatic Manager - Station markieren - Menü: Zielsystem - Diagnose/Einstellung - Baugruppenzustand - Zykluszeit)
Da stehen dann Deine tatsächlichen Werte.


----------



## Alexus85 (15 Oktober 2010)

Ok, da hab ich eine max. Zykluszeit von 19ms, minimal von 13ms.


----------



## M-Ott (15 Oktober 2010)

Bei Deiner Test- oder der Maschinen-CPU?
Wie lang ist denn die Zykluszeit bei der anderen CPU?


----------



## Alexus85 (15 Oktober 2010)

Bei meiner Maschinen-CPU.
Kein Ahnung wie sie bei der Test-CPU war. Ich hab aber auch net vor wieder alles umzubauen.


----------

