Step 7 Counter mit If anweisung in AWLfür PWM - Probleme

murmelkopf2

Level-1
Beiträge
9
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leute,
Ich bin noch recht frisch in der SPS-Programmierung und brauche für mein Projekt eine PWM steuerung.

Mein plan war es nun den OB 35 zu benutzen und dort einen Counter von 0-100 zählen und wieder rücksetzen zu lassen.
Der wert soll in einem DB-variablen mit den namen count1 gespeichert werden.
In einem anderen FC soll dann der Zählerstand gelesen werden und mit dem Puls/pausen verhältnis verglichen werden.

Sprich der zähler steht auf 60 und puls pausen verhältnis steht auf 60% dann soll der Ausgang auf 0 gesetzt werden und von 0-59 auf 1


Nun das Problem:
Es wird immer der Sprungbefehl ausgeführt und der vergleich wird nicht berücksichtigt.
Sprich es wird nur das beachtet was bei "els" steht.
Ich habe schon sämtliche Sprungbefehler ausprobiert sowie vergleichsoperationen und auch direkt zahlen eingegeben (z.b. "L 5" statt 1)

L "ProzessDaten".count1
L 100
>I
SPB els
L "ProzessDaten".count1
L 1
+I
T "ProzessDaten".count1

els: L 22
T "ProzessDaten".count1


Wo steckt dort mein Fehler? Oder hat jemand eine bessere Lösung für mich ?
Vielen Dank!
 
Es wird immer der Sprungbefehl ausgeführt und der vergleich wird nicht berücksichtigt.
Sprich es wird nur das beachtet was bei "els" steht.
Wie kommst Du darauf? Du solltest den Code mal beobachten. :cool:

Tatsächlich ist es so, daß nach dem Inkrementieren der count-Variable IMMER auch noch die Anweisungen nach der "els"-Sprungmarke ausgeführt werden. Ist das nicht erwünscht, dann müssen diese Anweisungen durch einen extra Sprungbefehl übersprungen werden.

Dein Code ist außerdem auch logisch falsch. Wenn er funktionieren würde, dann würde er bis 101 zählen ...


Code:
// IF
L "ProzessDaten".count1
L 100
[COLOR="#0000FF"][B]>=I[/B][/COLOR]
SPB els

// THEN
POP  //gelesenen Wert von "ProzessDaten".count1 zurück in AKKU1 (TAK geht auch)
+ 1
T "ProzessDaten".count1
[COLOR="#0000FF"][B]SPA M002[/B]  //"els"-Anweisungen überspringen[/COLOR]

// ELSE
els: L [COLOR="#0000FF"][B]0[/B][/COLOR]
T "ProzessDaten".count1

// Weiter
[COLOR="#0000FF"][B]M002: NOP 0[/B][/COLOR]


Bessere Variante des freilaufenden Zählers:
Code:
L "ProzessDaten".count1
+ 1
L 101
MOD
T "ProzessDaten".count1 // wird hier garantiert 0..100


Mein plan war es nun den OB 35 zu benutzen und dort einen Counter von 0-100 zählen und wieder rücksetzen zu lassen.
[...]
In einem anderen FC soll dann der Zählerstand gelesen werden
Vorsicht: wenn Du die DB-Variable auch außerhalb der OB35-Aufrufebene liest, dann darfst Du den Wert nur einmal lesen. Zwischen dem ersten und dem zweiten Lesen könnte ein OB35-Aufruf gewesen sein und das zweite mal ein anderer Wert gelesen werden.


brauche für mein Projekt eine PWM steuerung.
Wie hoch soll die Ausgabefrequenz des PWM-Signal sein? Ist Deine OB35-Idee da nicht zu langsam?
Welche SPS-Hardware hast Du zur Verfügung?

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
Erstmal vielen dank für die Hilfe ich bin gestern schon fast verrückt geworden an dem fehler.
Die geschichte mit dem 101 ist nicht so wild mir ging es erstmal um die grundlegende funktion dass meine IF schleife funktioniert.
Den OB 35 habe ich auf 10ms eingestellt und ist eigentlich schon zu schnell.

Ich brauche es nur um eine Heizspirale in der Leistungs zu drosseln. Dafür brauche ich keine hohe frequenz.

Zur verfügung habe ich eine S7 314-2ptp wenn ich das gerade richtig in erinnerung habe.
Ich werde es heute Nachmittag gleich ausprobieren.
Vielen Dank!
 
Klingt als wäre OB35 für deine Anwendung übertrieben.
Wenn du am einfachsten an ein paar Takte kommen willst könntest du...

A) Das interne Taktmerkerbyte nehmen.
Das musst du zunächst in den Hardwareeinstellungen der CPU unter dem Reiter "Zyklus/Taktmerker" mit dem Häkchen aktivieren. Übersetzen und auf die CPU laden.
Dann hast du bei Standardeinstellung auf MB0 folgende Aufteilung. Das Byte ist sowieso praktisch für Blinktakte bei Anzeigelampen etc.
Code:
Takt_10Hz	M       0.0	BOOL	
Takt_5Hz	M       0.1	BOOL	
Takt_2,5Hz	M       0.2	BOOL	
Takt_2Hz	M       0.3	BOOL	
Takt_1,25Hz	M       0.4	BOOL	
Takt_1Hz	M       0.5	BOOL	
Takt_0,625Hz	M       0.6	BOOL	
Takt_0,5Hz	M       0.7	BOOL
Dann könntest du für deine Anwendung eine Takt aussuchen und diesen dann folgendermaßen programmieren.
Code:
 U M0.0  //10 Hz - Ein 0-100 Durchlauf (PWM-Periode) dauert 10s
FP M10.0 //Flanke da die Taktmerker ein 50/50 Ein/Aus-Verhältnis haben
SPBN Ma01

L Zählwert
+ 1
L 101
MOD
T Zählwert

Ma01: Nop 0
Dann brauchst du den OB35 nicht.


B) Du kannst deinen eigenen Takt mit einem Timer schreiben.


Deinen Ausgang könntest du dann einfach so programmieren...
Code:
U M20.0  //Irgendeine Startbedingung
U(
L Zählwert
L Soll_Verhältnis_PWM 
<=I
)
= Ausgang_PWM
Ich würde dann auch noch wenn keine Startbedingung da ist, den Zählwert auf 0 setzen damit die PWM beim ersten Durchlauf nicht irgendwo in der Mitte anfängt.
 
Zuletzt bearbeitet:
Vielen Dank es funktioniert.
Nun muss ich nur noch einen regelkreis implementieren, der den Ansteuergrad bestimmt =)


L "ProzessDaten".count1
+ 1
L 101
MOD
T "ProzessDaten".count1
NOP 0
// PWM vergleich + startbedingung

U "ProzessDaten".relais_1
U "ProzessDaten".var1 //Freigabe
U(
L "ProzessDaten".count1 //gelesenen Wert von "ProzessDaten".count1 zurück in AKKU1 (TAK geht auch)
L "ProzessDaten".AA0 // laden pwm aussteuergrad
<=I // vergleich Zähler u Aussteuergrad
)
= "ProzessDaten".XSSR1

U "ProzessDaten".relais_1
U "ProzessDaten".var2 //Freigabe
U(
L "ProzessDaten".count1 //gelesenen Wert von "ProzessDaten".count1 zurück in AKKU1 (TAK geht auch)
L "ProzessDaten".AA1 // laden pwm aussteuergrad
<=I // vergleich Zähler u Aussteuergrad
)
= "ProzessDaten".XSSR2

NOP 0
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich würde dir jedoch raten den Counter, wenn du keine Freigabe hast, auf 0 zu setzen.
Du müsstest dann halt 2 getrennte Counter für jeden Ausgang machen.

Wenn du zum Beispiel einen Ansteuerungsgrad von 50 hast und die Freigabe kommt wenn der Counter bei
48 ist, dann schaltet dein Ausgang im ersten Durchlauf nur sehr kurz. Je nachdem was für eine Schaltstufe du hast kann das zu Beschädigungen führen.
 
Ich habe noch ein Problem:

Wenn ich der SPS den Strom wegnehme und wieder anschalte macht die SPS einfach mit dem Letzten Zustand weiter:
Ich möchte aber, dass alle Ausgänge auf 0 gesetzt werden.


Auszug aus OB100
L 0 // Alle Ausgänge auf Null
T PAB 124
L 0
T PAB 125
CLR
R "ProzessDaten".relais_1
R "ProzessDaten".relais_2
R "ProzessDaten".relais_3
R "ProzessDaten".relais_4
R "ProzessDaten".relais_5
R "ProzessDaten".relais_6
R "ProzessDaten".relais_7
R "ProzessDaten".var1
R "ProzessDaten".var2

Es funktioniert leider nicht!
Obowohl es eigentlich Doppelt auf 0 gesetzt werden soll. Relais 1 - 7 sind A124.0-6
 
Zuviel Werbung?
-> Hier kostenlos registrieren
normalerweise sollte es duch die erste Anweisung
L 0
T PAB 124

schon erledigt sein.

Das andere hab ich noch zum ausporbieren dahinter geschrieben da ersteres nicht gereicht hat.

OB1 hat folgendes drinnen:
// Eingänge Lesen und and DB schicken
L PEB 124
T DB1.DBB 34
// DB Lesen und an Ausgänge schicken
L DB1.DBB 37
T PAB 124
L DB1.DBB 38
T PAB 125


Wenn ich der SPS den Strom weg nehme und wieder anschalter sollte doch eigentlich der OB 100 durchlaufen werden bevor OB1 aufgerufen wird.
Demnach sollte im DB alle ausgänge zurückgesetzt werden

Aber das scheint ja nicht gemacht zu werden. Oder der OB 100 wird nicht aufgerufen
 
normalerweise sollte es duch die erste Anweisung erledigt sein.
L 0
T PAB 124

Aber das scheint ja nicht gemacht zu werden. Oder der OB 100 wird nicht aufgerufen
Wird erledigt, Boss...
Wird gemacht, Boss... ;)
Die Steuerung ist stur und macht immer das was du ihr sagst.

OB1
// DB Lesen und an Ausgänge schicken
L DB1.DBB 37
T PAB 124
L DB1.DBB 38
T PAB 125
Und wer hat jetzt den Wert aus DB1.DBB37 und DB1.DBB38 gelöscht? Da steht immer noch dasselbe drin wie vor dem Stromausfall.
Die nächste Frage ist dann ob die Bedingungen (im normalen Programmablauf) zum setzen der Ausgänge nicht womöglich nach dem Neustart erhalten bleiben.
 
Das was ich sehe macht:

1. im OB 100 PAB124+125 zu Null
2. im OB1 PAB 124+125 zu Db1.DBB37+DBB38

Wie siehst du, dass die PAB Null werden, das geht viel zu schnell.
Wo bringst du DB1.DBB37+38 auf Null?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich weiß Nicht wie ich denn die Werte im DB noch anders auf 0 setzen soll
bei
L 0
T "ProzessDaten".relais_1

Gibt er mir Syntax fehler genauso wenn ich mit = 0 etwas zuweisen will

Edit:
Super vielen Dank mit dem Tipp: DBB
L 0
T DB1.DBB 37
L 0
T DB1.DBB 164
Läuft jetzt

Ich hatte auch folgendes Versucht. Warscheinlich lag es an dem fehlenden Leerzeichen
L 0
T DB1.DBX37.0
 
Zuletzt bearbeitet:
"ProzessDaten".relais_1 Ist ja auch ein Bit.

Du sollst DB1.DBB 37 und DB1.DBB 38 auf 0 setzen.
Schließlich ist es ja das was du in jedem OB1-Zyklus auf PAB124/125 und somit auch auf die Ausgänge A124.0-6 oder "ProzessDaten".relais_1-7 drüberschreibst.

Es hat keinen Sinn "ProzessDaten".relais_1-7 zu beeinflussen wenn du danach mit...
L DB1.DBB37
T PAB124
wieder drüberschreibst. Da kannst du dich noch so verbiegen.

Nachdem du also im OB100 -- DB1.DBB37 und DB1.DBB38 erfolgreich auf 0 gesetzt hast, musst du auch noch dafür sorgen dass sie danach nicht gleich im OB1 wieder mit frischen Werten überschrieben werden. Irgendwoher müssen ja die Werte für DB1.DBB37/38 ja wohl kommen.
 
Zuletzt bearbeitet:
vielen dank hab die Lösung gefunden.
Ich dachte mit R "Porzessdaten".realis_1 schreibe ich den Wert 0 in den DB. an der Stelle 37.0
Dem scheint wohl nicht so zu sein.

Zu deiner Frage wo die Werte Herkommen:
Die Werte kommen vom einem Simatic Panel Touch. Der schreibt einfach den Wert in den Datenbaustein, wenn ich den Button dazu anklicke.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
R "Porzessdaten".realis_1 schreibe ich den Wert 0 in den DB. an der Stelle 37.0
Dem scheint wohl nicht so zu sein.
HEUREKA!! Langsam lüften sich die Rätsel...
Langsam graut mir dein Datenbaustein-Aufbau.
"Porzessdaten".realis_1..7 liegt im Datenbaustein als Bit deklariert an Addresse 37.0 aufwärts.
Deshalb willst du gleich das ganze Byte37 auf das PAB übertragen.

Da du uns den Zusammenhang zwischen deine Symbolen und Adressen aber bis jetzt nicht wirklich verraten hast konnte man nur raten.

Dann hast du im Endeffekt im OB100 auch alles richtig gemacht.
Code:
[COLOR=#ff0000][B]CLR[/B][/COLOR] 
 R "ProzessDaten".relais_1
 R "ProzessDaten".relais_2
 R "ProzessDaten".relais_3
 R "ProzessDaten".relais_4
 R "ProzessDaten".relais_5
 R "ProzessDaten".relais_6
 R "ProzessDaten".relais_7
 R "ProzessDaten".var1
Ist bis auf den Fehler mit dem CLR ja dasselbe wie
Code:
L 0
 T db1.dbb37
Nur musst du Wissen dass CLR das Verknüfungsergebnis auf 0 setzt. Die Reset-Befehle tun also nichts
Richtig wäre entweder:
Code:
[COLOR=#ff0000]
[B]SET[/B][/COLOR]                      //Setze Verknüpfungsergebnis auf 1
R "ProzessDaten".relais_1  //Rücksetze

oder

[COLOR=#ff0000][B]CLR[/B][/COLOR]                     //Setze Verknüpfungsergebnis auf 0
[COLOR=#ff0000][B]=[/B][/COLOR] "ProzessDaten".relais_1        //Zuweisung
 
Zuletzt bearbeitet:
Nun nochmal eine Komplexere Frage:
Gibt es die möglichkeit auf meiner SPS s7 314 eine Temperaturregelung mit 2 Stellgliedern zu implementieren ?
Ich habe einen Klimaschrank mit Kühlkompressor und Heizspirale.
Wobei der Kompressor nur eingeschaltet bzw ausgeschaltet werden kann. Sehr langsame schaltzeiten, sodass nicht an PWM zu denken ist.
Die Heizspirale kann ich mit einem PWM Signal steuern.

Nun hab ich schon gelesen, dass es 2 PID regelungen gibt ( FB 58 FB 59) allerdings können diese nur ein Stellglied verarbeiten.
Die Regelstrecke für Heizen als auch Kühlen ist bekannt.

Leider komme ich hier mit einem 2Punkt Regler nicht sehr weit, da beide Stellglieder sehr träge sind und noch langezeit nachheizen, bzw nachkühlen.

Hat hier noch jemand einen Tipp für mich ?
 
Zurück
Oben