3. Steuerungstechnik (Grundlagen und Vorgehensweise)  Stand: 16.01.2008

Struktur_Steuerungsprogramm , Struktur_Hauptprogramm

Retten_von_Variablen remanente und nicht-remanente Variable, Variable EEPROM

Retten von Daten bei Spannungsausfall   Wann war der letzte Spannungsausfall?   NEU

Automatischer Start_bei_Spannungswiederkehr  (z.B. mit Kondensator)

Parallele_und_serielle_Abläufe , Ablauf- und Verknüpfungssteuerung

Flanken  Flanken-Ersatz , Zähler NEU

Aufrufbit  Melden und Befehlen, Verriegelungsbit, Meldebit und Meldenummer

Wartezeit und Überwachungszeit sowie Einschaltverzögerung, Ausschaltverzögerung, Zeitbegrenzung

Schrittsteuerung  (Ablaufsteuerung)

Schrittregister_mit_if_then

Schrittregister_mit_Wartezeit    Verzweigung der Schrittsteuerung ,

Schritt_mit_Überwachungszeit

Schrittregister_mit_on_goto

Bedienung   Taster_mit_Flanke   Taster_ohne_Flanke  Prellen von Schaltern, Stromstoßschalter

Gegenseitige_Verriegelung und Ansteuerverriegelung

Sollwerte_eingeben Takten mit steigender Geschwindigkeit

Begrenzungen für Eingaben, Zähler und Rechenergebnisse NEU

Datenregister  Bit-Register, Byte-Register, Word-Register 


Ordnung und Übersichtlichkeit sparen Zeit und ersparen Fehler.

3.0) Strukturen

3.0.1) Struktur eines Steuerungsprogramms

(1)   Definitionen Variable

für Ports, Word, Byte, Bit usw.

Define Sollwert Byte

' Liste der Belegung EEPROM-Variable

' 4 = Betiebsstundenzähler (Minuten)

' 6 = Uhrzeit Start Stunde , Minute

(2)   a) Definition Festwerte

Define Obergrenze 70

b) Definition Pseudo-Variable

#Grenzwert RETURN Sollwert + 3

(3)   Vorbesetzung von Variablen

bei Start und Spannungswiederkehr

Sollwert = 40

(4)   Hauptprogramm (Grobstruktur)

#Anfang  Schleife

if  Istwert < Sollwert then goto Ein

if  Istwert > Grenzwert then goto  ....

gosub xyz

#Ein

K1 = ON

Goto weiter

#Aus

K1 = OFF

#weiter

(weitere Programmteile)

Goto Anfang Schleife

(5)   Unterprogramme für gosub

#xyz

if Istwert > Obergrenze then K2 = OFF

RETURN

3.0.2) Feinstruktur des Hauptprogramms (4)

(0)   Retten bei Spannungsausfall

Falls notwendig

Abfrage Analogport 8 bzw. 7

(1) Zeittakte bilden

SekundenImpuls

(2) Messwerte erfassen

Istwert = T1 / 2 -25

(3) Schrittregister mit Wartezeit

Schritte weiterschalten

Wartezeiten setzen

(4) Bedienung

      Tastatur

 Schalter

(5) Anzeigen

LED, LCD

(6)   Schnittstelle

PC – Anzeige und Eingabe

nach_oben

3.0.3) Retten von Variablen-Werten

In der Steuerungstechnik unterscheidet man nicht-remanente, teil-remanente und voll-remanente Variable.

(1) Nicht-remanente Variable werden vom Betriebssystem  nach einem Reset oder nach Spannungsausfall auf Null gesetzt.

Das sind die Variablen Byte 1 bis 24 und bei Erweiterung (siehe Solpersteine) Byte 25 bis 28 sowie Datum und Uhr.

(2) Teil-remanente Variable behalten ihren letzten Wert auch nach Reset und Start.

Jedoch bei einem Spannungsausfall können sie ihren Wert nur bei Batterie-Pufferung der c-contol retten.

Remanente Variable sind Byte 59 und 60 sowie 69 bis 72.

Erweiterung des Bereichs siehe Stolpersteine „mehr Variable“.

Remanente Variable sind notwendig, wenn bei Wiederanlauf bei Reset oder nach einem Spannungsausfall  das Programm mit letztem Sollwert oder Richtungsbit Vorwärts/Rückwärts fortgesetzt werden soll.

Auch bei Neu-Laden des geänderten Programms behalten sie ihren Wert. So bleibt z.B. der Wert des Betriebsstundenzählers erhalten.

Sie können natürlich auch bei Reset und Wiederanlauf durch die Vorbesetzung (siehe 3.0.1) auf Null gesetzt werden.

(3) Voll-remanente Variable sind Speicherwerte im EEPROM .

Sie behalten ihren Wert bei Reset und bei Spannungsausfall, auch wenn keine Pufferbatterie verwendet wird.

Bei Neuladen des Programms werden sie jedoch überschrieben, wenn nicht besondere Vorkehrungen getroffen werden. Deshalb werden sie am Ende des EEPROMs abgelegt.

Wenn man Datum und Uhrzeit in EEPROM-Variable sichert, kann man z.B. nach Reset die Werte bei Wiederanlauf rückladen und hat sofort Werte bevor die Funkuhr synchronisiert.  Jede Minute darf  nicht gespeichert werden, weil die Lebensdauer des EEPROMs begrenzt ist. Weitere Nutzung siehe Softwarebausteine und das folgende Beispiel.

nach_oben

3.0.4) Retten von Daten bei Spannungsausfall (Netzausfall)

Die Station meldet den Ausfall der Netzspannung an einem intern angeschlossenen Analogport.

Dadurch kann man Daten retten, sofern eine Batteriepufferung vorhanden ist. Außerdem kann man die Steuerung abschalten, um nicht die Batterie durch eingeschaltete Relais, LCD, usw. unnötig zu belasten.

Speichert man jeweils die Uhrzeit bei Spannungsausfall und bei Spannungswiederkehr, kann auf diese Weise die Ausfallzeit bestimmt werden.

Vor Neu-Laden eines Programms unterbreche ich die Netzversorgung und erzwinge damit die Speicherung der Uhrzeit. Beim Start des Programms habe ich dadurch die Uhrzeit mit nur geringer Abweichung, selbst wenn die Synchronisation mit der Funkuhr noch nicht erfolgt ist.

Mit dem folgenden Beispiel kann auch Datum und Uhrzeit des letzten Spannungsausfalls auf dem Bildschirm angezeigt werden.

Definition

Define  Spg230V  AD[8]   ' Wert 255 bei vorhandener Netzspannung

weitere Definitionen siehe Softwarebausteine Teil EEPROM-Variable

Vorbesetzung, Rückladen der geretteten Daten bei Start 

if year < 90 then goto UhrGesetzt  ' year ist 97 ohne Funkuhr

' In diesem Beispiel wurde das Jahr nicht gespeichert.

year = 1                ' Vorbesetzung, wenn Funkuhr nicht gestellt

Zeiger = 76 : input# wert12      ' Datum holen letzte Speicherung (Platz 76)

day = wert1 : month = wert2    ' Datum setzen

input# wert12                        ' Uhrzeit holen letzte Speicherung (Platz 78)

hour = wert1 : minute = wert2 ' Uhrzeit setzen

#UhrGesetzt

 

Hauptprogramm

'Datum und Uhrzeit retten bei Spannungsausfall

if Spg230V > 100 then goto SpannungOK

 ' Spannungsausfall

wert1 = day : wert2 = month      'Retten Datum letzter Spannungsausfall

Zeiger = 76 : print# wert12          'in EEPROM-Variable 76

wert1 = hour : wert2 = minute    'Retten Uhrzeit

print# wert12                             ' in EEPROM-Variable 78

Abschalten bei Spannungsausfall

#Ausfall 'Schleife bei Spannungsausfall

K1 = OFF : K2 = OFF                     'Brenner aus , Pumpe aus

if  Spg230V < 200 then goto Ausfall  'Festhalten in Schleife (keine Bildschirmanzeige)

#SpannungOK

Anzeige des letzten Spannungsausfalls

Zeiger = 76 : input# wert12          ' Datum holen letzte Speicherung (Platz 76)

print  "Letzter Spannungsausfall: ";wert1;".";wert2;

input# wert12                            ' Uhrzeit holen letzte Speicherung  (Platz 78)

print  ". Uhr ";wert1;":";wert2;"    "

Weitere Informationen siehe Kapitel Softwarebausteine Teil  EEPROM

nach_oben

3.0.5) Start der Station bei Spannungswiederkehr nach Netzausfall

Es gibt es mehrere Lösungen für einen automatischen Start:

(1)     12 Volt-Batterie mit Abfrage Analogport 8 (siehe vorhergehenden Punkt 3.0.4)

Die folgenden Lösungen bewirken auch einen automatischen Start, wenn die c-control nicht von Hand gestartet war. Die Funktion der Starttaste als Einschalt-Taste ist also aufgehoben. Der Programmierer muss für ein sicheres Verhalten sorgen.

(2)     Drahtbügel mit Pappplättchen und  damit Starttaste dauernd gedrückt halten

(3)     Schalter einbauen, der die Starttaste überbrückt (Abschalten vor Laden eines Programms)

(4)     Kondensator einlöten (die Seite von Conrad ist wieder erreichbar, siehe Linkliste)


 

nach_oben

3.0.6) Parallele und serielle Abläufe

Die Steuerung mehrerer Rollladenantriebe sind parallele Abläufe. Sie können unabhängig von einander die Rollladen öffnen oder schließen.

Dagegen ist eine Heizungssteuerung ein serieller Ablauf, da erst die Pumpe und danach der Brenner eingeschaltet wird.

Abläufe werden mit Schritten strukturiert. Man spricht dann von einer Ablaufsteuerung.

Bei einer Verknüpfungssteuerung wird die Ausführung von Befehlen vorwiegend mit AND, OR, usw. verknüpft ist. Diese Vorgehensweise stammt von der Projektierung von Schützen- und Relaissteuerungen sowie der Hardware-Elektronik.

Nach Einführung der Software-Steuerungen etwa ab Jahr 1970 setzten sich die Ablaufsteuerungen mit ihrer Schritt-Struktur durch.

Die Aufgabenstellung liegt immer in Klartext vor (Pflichtenheft). Durch Unterteilung der Aufgabe in Schritte gelangt man direkt zur Schrittsteuerung.

 

3.1) Flanken

In der Steuerungstechnik gibt es nicht nur die Zustände „EIN“ und „AUS“ , sondern auch die Änderung von „EIN“ nach „AUS“ und umgekehrt.

Die Änderung nennt man Flanke. Es gibt als Flankenmerker die Ein-Flanke (auch positive Flanke oder steigende Flanke genannt), die Aus-Flanke und Doppelflanke (beide).

define Zaehler              byte

define Anzahl               byte

define Bit81_88           byte[11]          ' byte 11 (statische Bits 81 bis 88)

define Flanke1             Bit[81]            'Flankenbit

define FlankeSekpuls   Bit[82]            'Flankenbit für Sek-Takt

define Flanke2              Bit[83]            'Flankenbit

define Aufrufbit             Bit[86]

define Heizung              Bit[87]

define Motor                 Bit[88]

3.1.1) Ein-Flanke (Aus-Flanke sinngemäß)

if Motor = ON then goto setz ' Motor Ein? Ja, dann setze EIN-Flanke

Flanke1 = OFF ' Reset Ein-Flanke (bei Motor Aus)

Goto Ende

#setz

if Flanke1 = ON then goto Ende ' Ein-Flanke gesetzt? Ja, dann Ende

Flanke1 = ON ' Setze Ein-Flanke (Sperre für weiteres Setzen)

Zaehler = Zaehler +1 ' Beispiel: zählt die Anzahl Motor-Einschaltungen

Aufrufbit = ON ' Beispiel: Aufruf einer Funktion (siehe 3.2)

#Ende

nach_oben

3.1.2) Doppelflanke (Ein und Aus)

meldet, dass ein Wechsel von EIN nach AUS oder AUS nach EIN stattfand.

if Motor = Flanke2 then goto Ende2' Wenn Motor (Ein-Aus) gleich Flanke, dann „nichts tun“

Flanke2 = Motor ' andernfalls setze Flanke = Motor (Ein-Aus) setzen

Anzahl = Anzahl +1 ' Beispiel: zählt die Anzahl Ein- und Ausschaltungen

#Ende2

3.1.3) Indirekte Flanke (Flanken-Ersatz)

Man kann auch ohne Flankenbit auskommen.

(1) Relais als Flanke

If   K1 = ON    then  goto weiter

K1 = ON

Zaehler = Zaehler + 1 ' Anzahl Ein 

#weiter

(2) Relais als Flanke (Selbstmordschaltung)

If   K1 = OFF    then  goto weiter

K1 = OFF

Zaehler = Zaehler + 1 ' Anzahl Aus 

#weiter

(3) Wert als Flanke

Im folgenden Beispiel sollen Mitternacht der Betriebsstundenzähler und Zähler der Brennerstarts auf Null gesetzt werden.

If   Brennerstarts = 0   then goto ende3

if hour >< 0 or  minute >< 0 or  year > 90    then goto ende3

Brennerstarts = 0

wert12 =0 : Zeiger = 4 : print# wert12    ' Betriebstundenzähler  Null setzen

#ende3

Ohne Abfrage Brennerstarts würde Mitternacht 1 Minute lang auf das EEPROM geschrieben (schädlich wegen begrenzter Lebensdauer).

Indem die Variable Brennerstarts auf Null gesetzt und ausgewertet wird, kann auf das EEPROM nur einmal geschrieben werden.

Die Abfrage „Year > 90“ verhindert, dass bei Neustart eines Programms die Zähler Null gesetzt werden. Bei Neustart steht year auf 97.

Die Abfrage „Brennerstarts“ kann natürlich mit „OR“ in der Zeile der Zeitabfrage eingebunden werden.

(4) Zeit als Flanke

If  MinutenImpuls = OFF  then goto ende4

if hour >< 0 or minute >< 0 or year > 90    then goto ende3

Brennerstarts = 0

wert12 =0 : Zeiger = 4 : print# wert12    ' Betriebstundenzähler  Null setzen

#ende4

Durch den Minuten-Impuls wird bei Minute = 0 nur einmal je Tag bearbeitet.

nach_oben

3.2) Melden und Befehlen

Soll der Baustein zu einer Funktion gezwungen werden z.B. „Parkposition anfahren“, dann handelt es sich um ein Aufrufbit (aktives Befehlsbit).

Meldet es den Vollzug, dann spricht man von einem Meldebit. Dies kann wiederum als Verriegelungsbit im aufrufenden Baustein verwendet werden.

Das Verriegelungsbit ist auch ein Befehlsbit (passiv) und verhindert den Start eines Vorgangs in einem anderen Softwarebaustein. 

 

3.2.1) Aufrufbit (Aufruf einer Funktion)

In einem Softwarebaustein (siehe 3.1.1) wird ein Aufrufbit gesetzt, das hier in diesem Baustein ausgewertet wird.

Das Aufrufbit veranlasst einen Vorgang in einem anderen Softwareteil (Softwarebaustein).

if Aufrufbit = OFF then goto Ende321 ' Wenn „Aus“, dann „nichts tun“

Heizung = ON ' Wenn Aufrufbit gesetzt, dann Funktion ausführen

if T1 < 50 then goto Ende321 ' Wenn Temperatur kleiner Abschaltwert, dann ..

Aufrufbit = OFF ' Wenn Funktion erledigt , dann Aufrufbit ausschalten, usw.

Heizung = OFF

#Ende321

In diesem Beispiel schaltet der aufrufende Baustein nur ein. Der ausführende Baustein wickelt den Vorgang einschließlich dem Ausschalten ab.

Natürlich kann der aufrufende Baustein auch die volle Befehlsgewalt haben, z.B.

Heizung = Aufrufbit AND  T1 < 50 '  Aufrufbit schaltet ein (abhängig von der Temperatur) und aus.

 

3.2.2) Aufruf durch Ereignis (Beispiel schneller Zähler)

In dem Beispiel sollen schnelle Zähl-Impulse am Frequenz-Eingang während einer Einschaltdauer oder Zeitdauer erfasst werden.

Am Frequenz-Eingang freq oder freq2 werden während der sogenannten Torzeit 1 sec lang die Impulse gezählt.

if  Ereignis = OFF then goto Ende 322 ' Wenn „Aus“, dann „nichts tun“

if second >< oldsec then goto Ende 322 ' Wenn „Sekunde ausgewertet“, dann „nichts tun“

oldsec = second '  (Altwert als Flanke)

Zaehler = Zaehler +  Freq2 ' Wert der vergangenen Sekunde dazu addieren

#Ende 322

3.2.3) Meldebit und Meldenummer

Ein Byte kann nur 8 Meldebits haben, aber 256 Meldenummern (0 bis 255).

Während die Meldebits gleichzeitig melden können, kann es gleichzeitig nur eine Meldenummer geben.

In folgender Software wird jeweils der letzte Vorgang gemeldet. Vorteilhaft ist dabei, dass Bits nicht rückgesetzt werden müssen.

MeldeNr = 0

If HandAus then goto Markise_zurück

MeldeNr = 1

If Wind > 49 then goto Markise_zurück

MeldeNr = 2

If  Sonne < 99 then goto Markise_zurück

MeldeNr = 10

If HandEin then goto Markise_vor

MeldeNr = 11

If  Sonne > 150 then goto Markise_vor

goto ...

#Markise_zurück

goto..

#Markise_vor

goto

Auf einfache Weise kann der zugehörige Text ausgegeben werden.

On MeldeNr goto print „Text0“, print „Text1“, print „Text2“, ... usw

nach_oben

3.3) Wartezeit und Überwachungszeit

In der Steuerungstechnik unterscheidet man nur diese zwei Zeittypen.

Die Wartezeit läuft im Normalfall immer zu Ende. Hierzu gehören die Zeitverzögerung unterschieden in Einschaltverzögerung und Ausschaltverzögerung sowie die Zeitbegrenzung und die Zeitverlängerung (Impulsverlängerung).

Dagegen läuft die Überwachungszeit im Normalfall nicht zu Ende. Mit ihr wird ein Vorgang überwacht, z.B. eine Rolllade muss in einer bestimmten Zeit auf oder geschlossen sein.

Läuft die Überwachungszeit ab, dann wird ein anderer Steuerungsschritt z.B. Meldung des Fehlers eingeleitet. Der Fehler wird also erst nach Ablauf der Überwachungszeit von der Steuerung erkannt; so gesehen ist die Überwachungszeit eine Notlösung. Im Fall der Rolllade könnte die Hemmung sofort durch Messung der Stromaufnahme oder durch einen Drehzahlwächter festgestellt werden. Dieser Aufwand ist meist zu groß und bringt weitere Fehlermöglichkeiten mit sich, deshalb ist die Überwachungszeit eine weit verbreitete Lösung.

Wartezeit und Überwachungszeit werden zweckmäßig in Verbindung mit dem Schrittregister_mit_Wartezeit angewendet, dadurch werden nur zwei Byte für die Zeiten benötigt, weil in jedem Schritt beide Zeiten mit neuen Zeitwerten gesetzt werden können.

define Wert1                byte [7] ' Zwischenspeicher 1 (Rechenwerte und Zahlenübergabe)Bit 49-56

define Sekpuls             Bit[6]    ' Bit 4-Sekunden Impuls

define FlankeSekpuls   Bit[82]  ' Flankenbit für 4-Sek-Takt

define wert1Bit0          Bit [49] ' Wert = 1 (für Bit-Handling des Byte wert1)

define wert1Bit1          Bit [50] ' Wert = 2

define wert1Bit2          Bit [51] ' Wert = 4

Als Zeittakt werden Zeit-Impulse benötigt. Die Impulse stehen z.B. im Abstand von 4 Sekunden nur während eines Programmdurchlaufs.

Zeittakt mit TIMER siehe Kapitel Tipps

Sekpuls = OFF' Reset Sekunden-Impuls nach einem Programmdurchlauf

wert1 = second 'Uhrzeit wird nach Byte geladen (Bit 2 wechselt alle 4 Sekunden)

if wert1Bit2 = FlankeSekpuls then goto EndeSekpuls' wenn Wert1 Bit 2 gleich Flankenmerker , dann „nichts tun“

FlankeSekpuls = wert1Bit2 ' andernfalls Flankenmerker = Bitwert setzen

Sekpuls = ON ' Aufrufbit alle 4 sec als Zeittakt für Wartezeit und Überwachungszeit

#EndeSekpuls

(1) Beispiel: Zeitbegrenzung, Relais K1 wird nach Zeitablauf ausgeschaltet.

If K1 = ON then goto AUS

If  ... then goto EIN

Goto weiter

#EIN

K1 = ON

Wartezeit = 21

Goto weiter

#AUS

if Sekpuls = OFF then goto weiter

if Wartezeit = 0 then K1 = OFF else Wartezeit = Wartezeit –1

#weiter

(2) Beispiel: Zeitbegrenzung mit einem byte Wartezeit für mehrere Relais, die nicht gleichzeitig benutzt werden.

if Sekpuls = OFF then goto weiter1

if Wartezeit = 0 then goto weiter1

Wartezeit = Wartezeit –1

#weiter1

If K1 = ON then goto AUS1

If K2 = ON then goto AUS2

If  ... then goto EIN1

If  ... then goto EIN2

Goto weiter2

#EIN1

K1 = ON

Wartezeit = 21

Goto weiter2

#AUS1

if Wartezeit = 0 then K1 = OFF 

goto weiter2

#EIN2

K2 = ON

Wartezeit = 47

Goto weiter2

#AUS2

if Wartezeit = 0 then K2 = OFF 

#weiter2

(3) Beispiele für Wartezeit (Ein- bzw. Ausschaltverzögerung) und Überwachungszeit siehe weiter unten.

nach_oben

3.4) Schrittsteuerung (Ablaufsteuerung)

„Teile und herrsche“ war ein alter römischer Grundsatz.

In der Steuerungstechnik teilt man die Aufgabe in Teile, um sie besser zu beherrschen.

if  Lüfter = ON then goto Ausschalten ' Wenn der Lüfter läuft, wird nur das Ausschalten bearbeitet

if Temperatur > Sollwert then Lüfter = ON ' Vorteil: evt. Änderungen gelten nur für das Einschalten

goto EndeX

#Ausschalten

if Temperatur < (Sollwert + Diff) then Lüfter = OFF ' Vorteil: evt. Änderungen gelten nur für das Ausschalten

#EndeX

nach_oben

3.4.1) Schrittregister Größere Abläufe werden in Schritte unterteilt.

'Die Steuerung wird in Ablaufschritte strukturiert.

Dies hat den Vorteil, dass vom Programm nur das bearbeitet wird, was im aktuellen Steuerungsschritt programmiert ist. Man kann im Schritt gezielt ergänzen, ohne dass dies Auswirkungen in anderen Schritten hat.

Die Programmteile der anderen Schritte können nicht stören, weil sie nicht bearbeitet werden.

In einem Schritt wird man niemals Relais EIN und Relais AUS programmieren, sondern dies in verschiedene Schritte legen.

if (Schritt = 1) then goto Schritt1 ' Heizen einschalten?

if (Schritt = 2) then goto Schritt2 ' Pumpe ein

if (Schritt = 3) then goto Schritt3 ' Heizen einschalten

if (Schritt = 4) then goto Schritt4 ' Heizen ausschalten?

Schritt = 1 ' Neustart der Ablaufkette (wird die Schrittabfrage durchlaufen, wird Schritt 1 gesetzt )

Goto Ende12 '----------------->>>

#Schritt1 ' Heizen einschalten?

if (Istwert > Sollwert) then goto Ende12' Istwert größer als Sollwert ---- > nicht einschalten

Goto Schrittweiter ' dort wird die Schritt-Nr um 1 erhöht

#Schritt2 'Pumpe ein

K2 = ON ' Pumpe Ein (Relais K2)

Goto Schrittweiter

#Schritt3 ' Heizen ein

K1 = ON ' (Brenner ein)

Goto Schrittweiter

#Schritt4 ' Heizen ausschalten? Heizen aus

Ausschaltwert (mindestens 5 Grad Differenz)

if (Istwert < Sollwert +5 ) then goto Ende12' Istwert kleiner als Sollwert +5 ---- > nicht ausschalten

K1 = OFF 'Brenner Aus

#Schrittweiter

Schritt = Schritt + 1 ' Schritt-Nummer um 1 erhöhen

#Ende12

nach_oben

3.4.2) *** Schrittsteuerung mit Wartezeiten ***

'In jedem Schritt kann eine Wartezeit gesetzt werden, die rückwärts gegen Null läuft.

Ein Vorteil besteht darin, dass nur ein Byte für die Wartezeit gebraucht wird, die in jedem Schritt mit neuem Zeitwert gesetzt werden kann.

Nach Ablauf  der Wartezeit wird der eingeschaltete Schritt bearbeitet.

if (Wartezeit = 0) then goto Schritt 'Wartezeit abgelaufen? ja ---> geh zu Schritt

if (sekpuls = OFF) then goto Ende12

Wartezeit = Wartezeit -1 'Wartezeit minus 1 x 4 sek (Zeittakt siehe oben)

goto Ende12

#Schritt ' Schrittregister bei Wartezeit NULL (Beispiele)

if (Schritt = 2) then goto Schritt2 ' Pumpe ein, Wartezeit

if (Schritt = 3) then goto Schritt3 ' Heizen einschalten

goto Ende12

#Schritt2 'Pumpe ein

K2 = ON ' Pumpe Ein (Relais K2)

Einschaltverzögerung für K1 in Schritt 3

Wartezeit = 10 'x 4 sec Wartezeit setzen

Goto Schrittweiter

#Schritt3 ' Heizen ein

K1 = ON ' (Brenner ein)

If T1 < 60 then goto Ende 12 ' Temperatur nicht erreicht

K1 = OFF

Ausschaltverzögerung für K2 in Schritt 4

Wartezeit = 7'x4 sec Wartezeit setzen

Goto Schrittweiter

#Schritt4 ' Pumpe aus

K2 = OFF ' (Pumpe aus)

nach_oben

3.4.3) Verzweigung der Schrittsteuerung mit Wartezeiten

Während die Wartezeit läuft, wird in einem eigenen Schrittregister gearbeitet, z.B. weil bei bestimmten Bedingungen die Wartezeit abgebrochen werden soll.

Nach Ablauf oder Abbruch wird der eingeschaltete Schritt bearbeitet.

Die Wartezeit kann auch vor Ablauf neu gesetzt werden (nachtriggern).

if (Wartezeit = 0) then goto Schritt 'Wartezeit abgelaufen? (Verzweigung)

if (sekpuls = OFF) then goto SchrittWartezeit

Wartezeit = Wartezeit -1 'Wartezeit minus 1 x 4 sek (siehe Zeittakt 4 sec)

#SchrittWartezeit ' Schrittregister bei Wartezeit läuft (Zweig 1)

if (Schritt = 1) then goto Schritt1w ' Wartezeit abbrechen?

Goto Ende12

#Schritt1w 'Schritt 1 bei Wartezeit läuft

if .... then  Wartezeit  = 23 ' Wartezeit neu setzen (nachtriggern)!

if (Istwert > 38) or (NachtSenkung = ON) then goto Ende12

wartezeit = 0 ' Wartezeit abbrechen!

Goto Ende12

#Schritt ' Schrittregister bei Wartezeit NULL (Zweig 2)

if (Schritt = 0) then goto Schritt0

if (Schritt = 1) then goto Schritt1 ' Heizen einschalten? (usw. siehe vorhergehende Abschnitte)

nach_oben

3.4.4) Schrittsteuerung ergänzt mit Überwachungszeit

#Schritt0

Überwachungszeit = 0 ' Reset im Schritt vor der Nutzung

#Schritt1 ' Heizen einschalten?

if Überwachungszeit > 240 then Pumpe = OFF ' Abfrage Überwachungszeit (kein Heizbedarf)

GOSUB Üzeit ' Überwachungszeit läuft vorwärts

if (Istwert > Sollwert) then goto Ende12' Istwert größer als Sollwert ---- > nicht einschalten

Goto Schrittweiter ' dort wird die Schritt-Nr um 1 erhöht

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

#Üzeit ' Unterprogramm Überwachungszeit

if sekpuls = OFF then RETURN

if Überwachungszeit > 254  then RETURN' 1 Byte, Zeit bleibt bei 255 stehen !

Überwachungszeit = Überwachungszeit +1 : RETURN

nach_oben

3.4.5) Schrittregister mit On .. goto..

Alternativ zum Schrittregister if ... then goto... kann die Verzweigung auch mit on... goto .. erfolgen.

On Schritt goto Schritt0, Schritt1, Schritt2, Schritt3, Schritt4, Schritt5, Schritt6

Der zeilenmäßige Aufbau des if-Registers kann jedoch besser kommentiert werden.

Vorteilhaft ist es für Text-Zuordnung zum Schritt oder DOW:

On Schritt goto Text0, Text1, Text2, Text3, Text4, Text5, Text6

#Text0

print „xyz“ : goto  EndeText

#Text1

print „abc“ : goto  EndeText

nach_oben

3.5) Bedienung mit Tast-Schaltern

define Sollwert             byte [6]

define Wert1                byte [7]    ' Zwischenspeicher 1 und Bit 49-56

define Bit81_88           byte [11]  ' (statische Bits)<<(Bit 81 bis 88)<<

define wert1Bit0          Bit   [49]  ' für bit-Handling des byte wert1 (Zwischenspeicher)

define wert1Bit2          Bit   [51]

define wert1Bit4          Bit   [53]

define Flanke1             Bit   [81]  'Flankenbit

define FlankeZeitpuls   Bit   [82]  'Flankenbit für Zeittakt

define AbfrageImpuls   Bit   [87]  'z.B. Bit HalbSekundenImpuls (ca. 0,6 sec)

 

Leichte Bedienung kann zweckmäßig mit Zeit-Impulsen erfolgen.

AbfrageImpuls = OFF :

wert1 = TIMER  '(max 255 x 20 ms = 5,1 SEK)

if wert1bit4 = ON then goto weiter21 ' bzw. wert1Bit2

FlankeZeitpuls = OFF : goto Ende2

#weiter21

if FlankeZeitpuls = ON then goto Ende2

FlankeZeitpuls = ON : AbfrageImpuls = ON ' für Bedienung der Tasten

#Ende2

nach_oben

3.5.1) Taster mit Flanke  Jeder Tasten-Druck schaltet einmalig.

Mechanische Schalter prellen, d.h. beim Schließen des Schalters öffnet er noch mehrmals während einer Zeit von z.B. 100 Millisekunden.

Ist die Zykluszeit des Programms größer (Messung siehe Tipps), sind keine Probleme zu erwarten.

if  not F1  then goto setz ' Taste gedrückt? Ja, dann setze EIN-Flanke

Flanke1 = OFF ' Reset Ein-Flanke

Goto Ende

#setz

if Flanke1 = ON then goto Ende3 ' Ein-Flanke gesetzt? Ja, dann Ende

Flanke1 = ON ' Setze Ein-Flanke (Sperre für weiteres Setzen)

Sollwert = Sollwert + 1 '(Beispiel für Sollwert erhöhen)

Relais = not Relais '(Beispiel für Funktion Stromstoßschalter)

#Ende3

3.5.2) Taster mit Flanke  Jeder Tasten-Druck schaltet einmalig mit Maßnahme gegen Prellen.

Ist die Zykluszeit des Programms kleiner als der Prellvorgang, kann dies zu Problemen führen z.B. ein Zähler zählt mehrmals.

Fragt man Schalter nur bei gesetztem  Bit Abfrage-Impuls ab, dann wird nur ein Schaltvorgang ausgewertet.

If  AbfrageImpuls  = OFF then goto Ende3 ' Impuls aus? Ja, dann keine Schalterabfrage

Diese Befehlszeile wird vor obige Schalterabfrage 3.5.1) eingefügt.

Grenzschalter (Endschalter) mit sehr kurzer Betätigung können so nicht abgefragt werden.

nach_oben

3.5.3) Taster ohne Flanke (Takten)

Festhalten der Taste bewirkt taktweißes Hochschalten.

Außerdem spart man durch dieses Verfahren viele Flanken-Impulse.

Wenn das gesamte Programm lang ist, ergibt sich auch ohne Abfrage-Impuls eine Taktzeit.

Dann wird direkt gosub Schalter verwendet.

if AbfrageImpuls = ON then gosub Schalter

Goto Ende

#Schalter

if F1 then goto weiterF2' F 1 frei -->

Sollwert = Sollwert + 1

Return

#weiterF2

if F2 then return' F 2 frei -->

Sollwert = Sollwert - 1

Return

 

3.5.4) Mehrfache Nutzung von Tastern

(5)   Bedienungsmenue

Mit einem eigenen Schrittregister baut man ein Bedienmenue auf, indem z.B. mit Taste 1 die Schritt-Nr hoch getaktet wird.

Die Schritt-Nr nennt man Anzeige-Nr, damit der Bediener informiert ist, welches Menue wirksam ist.

Die Tasten 2 bis 4 schalten je nach Anzeige-Nr  andere Funktionen.

Zum Beispiel bei Anzeige-Nr = 1 wird mit Taste 3 bzw. 4 ein Sollwert höher bzw. niedriger gestellt, bei Anzeige-Nr = 2 ein anderer Sollwert und bei „3“ wird ein- bzw. ausgeschaltet. 

(6)   Bedienungszeit

Das Schrittregister mit Wartezeit gestattet die Abfrage, ob eine Taste lange oder kurz betätigt wurde. Nach Ablauf der Wartezeit wird in Schritt 2 lediglich abgefragt, ob der Taster noch gedrückt ist. Bei „Ja“ wird nach Schritt 3 geschaltet bzw. bei „Nein“ nach Schritt 4.

(7)   Gleichzeitige Tastenbetätigung

Zum Beispiel kann man mit 2 Tasten 3 Funktionen schalten. Wenn beide Tasten gleichzeitig gedrückt werden, erhält man die zusätzliche Funktion.

In einfachen Fällen reicht der Vorrang beider Tasten.

If Taste1 and Taste2 then goto AUSSCHALTEN

If Taste1 then goto LINKSLAUF

If Taste2 then goto RECHTSLAUF

Sicherheitshalber nutzt man wie bei Bedienzeit ein Zeitfenster. Taste 1 schaltet auf Schritt 1 und Taste 2 auf Schritt 2. In beiden Schritten wird nun verzweigt, je nachdem, ob der andere Taster nach Ablauf der Wartezeit betätigt ist.

Sogar 4 Funktionen kann man erreichen. Je nach Reihenfolge von Taste 1 und 2 wird ja  Schritt 1 oder 2 eingeschaltet und dort wird nun unterschiedlich reagiert.

nach_oben

3.6) Gegenseitige Verriegelung

Werden zwei gleichrangige Funktionen verriegelt z.B. vorwärts und rückwärts oder Linkslauf und Rechtslauf, dann spricht man von „Gegenseitiger Verriegelung“.

Gegen gleichzeitige Bedienung (Tastendrücken) muss verriegelt werden. Der Bedienungsfehler muss vom Programm „abgefangen“ werden.

If  LinksTaster AND not RechtsTaster then gosub Linkslauf

If  RechtsTaster AND not LinksTaster then gosub Rechtslauf

Werden beide Tasten betätigt, wird keine Funktion ausgeführt.

Auch wenn der LinksTaster betätigt wird, fragt das Programm den RechtsTaster ab, was unsinnig ist.

Besser als der Befehl gosub ist hier die Verwendung des Befehles goto, da er direkt das Programm strukturiert.

If  LinksTaster  then goto Linkslauf

If  RechtsTaster then goto Rechtslauf

Bei Betätigung  LinksTaster wird RechtsTaster nicht mehr abgefragt.

Werden beide Tasten betätigt, hat Linkslauf Vorrang. Wird dies nicht gewünscht, wird die Ansteuerverriegelung angewendet.

If  LinksTaster AND not RechtsTaster then goto Linkslauf

If  RechtsTaster AND not LinksTaster then goto Rechtslauf

Die Schütze (Relais) müssen wegen ihrer Ein- bzw. Abschaltzeit (30 bis 100 msec) zusätzlich gegenseitig verriegelt sein, d.h. jeweils die Ansteuerung (Spule) wird über einen Öffner des anderen Schützes geführt.

3.7) Folgeverriegelung, Plausibilitätsprüfung

siehe Kapitel Hardware

nach_oben

3.8) Sollwerte eingeben (Takten mit steigender Geschwindigkeit)

Muss der Sollwert um eine größere Zahl erhöht werden, ist zweckmäßig nicht nur mit +1 zu erhöhen sondern variabel.

Je länger die Taste gedrückt wird, desto größer werden die Sprünge.

Kurzes Drücken bewirkt nach wie vor Erhöhung +1.

Define  x  byte

if  not F1  then goto PlusVar ' Taste gedrückt? Ja, dann Takte                                                                                             

x = 1 ' Reset Geschwindigkeit

Goto Ende37

#PlusVar

Sollwert = Sollwert + x ' Erhöhung Sollwert

if  x > 200 then goto Ende4 ' Begrenzung

x = x + 1 ' Erhöhung der Geschwindigkeit

#Ende37

nach_oben

3.9) Begrenzungen für Eingaben, Zähler und Rechenergebnisse

(1)   Byte +1

If  Zaehler = 255 then goto ... (bzw. Return)

Zaehler = Zaehler + 1 : goto... (bzw Return)

Alternativ  Zaehler = MIN (255 , Zaehler +1)

(2)   Byte – 1

If  Zaehler = 0 then goto ... (bzw. Return)

Zaehler = Zaehler – 1 : goto... (bzw Return)

Alternativ  Zaehler = MAX (0 , Zaehler – 1)

(3)   Byte + x

If  Zaehler + x < 255 then Zaehler = Zaehler + x else Zaehler = 255

Alternativ  Zaehler = MIN (255 , Zaehler + x)

(4)   Byte – x

If  Zaehler x  > 0 then Zaehler = Zaehler – x else Zaehler = 0

Alternativ  Zaehler = MAX (0 , Zaehler – x)

(5)   Word +1

If  Zaehler = 32767 then goto ...(bzw. Return)

Zaehler = Zaehler + 1 : goto ...  (bzw. Return)

(6)   Word + x  (für x = 0 bis 32767)

Vorsicht: Die folgende Abfrage ist fehlerhaft, denn wird 32 767 überschritten, wird die Zahl negativ und ist dadurch kleiner.

If Zaehler + x <= 32767 then Zaehler = Zaehler + x else Zaehler = 32767

Richtig ist folgende Abfrage:

If Zaehler + x – 32767 < 0 then Zaehler = Zaehler + x else Zaehler = 32767

Oder man prüft, ob das Vorzeichen plus bleibt, wenn der Befehl ausgeführt wird:

If SGN (Zaehler + x) >= 0 then Zaehler = Zaehler + x else Zaehler = 32767

Oder anschließende Korrektur, wenn das Ergebnis kleiner 0 (= negativ) ist.

Zaehler = Zaehler + x

If Zaehler < 0 then Zaehler = 32767

Oder anschließende Korrektur bei negativem Vorzeichen der ausgeführten Rechnung:

Zaehler = Zaehler + x

If SGN (Zaehler)  = -1 then Zaehler = 32767

(7)   Word – x  (für x = 0 bis 32767)

If  Zaehler – x  >= 0 then Zaehler = Zaehler – x  else Zaehler = 0

Alternativen sinngemäß wie vor.

(8)   Word + x  (für x = -32767 bis +32767)

If x < 0 then goto negativ else goto positiv

Vorgeschaltet wird die Entscheidung, welcher Rechenweg gegangen werden muss.

nach_oben

3.10) Datenregister

Hier werden „echte“ Variable (byte oder word ) benutzt. Im Kapitel Softwarebausteine werden EEPROM-Variable behandelt.

(1) Byte-Register (für Historie)

Zur Darstellung vergangener Daten nimmt man für einfache Fälle mehrere Bytes.

Define R1 byte

Define R2 byte

Define R3 byte

Define R4 byte

Define Temperatur byte

Define Status byte [6]

Define StatusBit0 bit [41] ' (byte 6 *8 – 7 = BitNR)

Bei einem Ereignis (z.B. Einschaltung) oder zeitlich werden die Daten weitergeschoben.

R4 = R3 : R3 = R2 : R2 = R1 : R1 = Temperatur 1' Erst schieben, dann neue Temperatur speichern.

So einfach kann dieses Programmteil in den Schritt eines Schrittregisters eingefügt werden.

Andernfalls muss ein Zeitimpuls oder das Ereignis mit Flankenauswertung verwendet werden.

If  not ZeitImpuls then goto Ende38

R4 = R3 : R3 = R2 : R2 = R1 : R1 = Temperatur

#Ende38

(2) Bit-Register (für Historie)

Beispielsweise kann zusätzlich der Status des Lüfters (EIN-AUS) gespeichert werden.

Hierzu reicht jeweils ein Bit (Ein-Bit-Register).

Status = Status SHL 1' Erst schieben (Historie)

StatusBit0 = Lüfter ' dann 1. Statusbit setzen

Da das Byte 8 Bit hat, können auch 4 Zustände (Lüfter1-2)

Status = Status SHL 2'  2 Bit schieben (Historie)

StatusBit0 = Lüfter1 : StatusBit1 = Lüfter2 ' dann beide Statusbits setzen

Abfrage Bit 3  der Historie (Beispiel) weitere Abfragen siehe „Tipps und Tricks“

Man teilt durch 8 (oder verständlicher durch &B 0000 1000    <- Bit 3 gesetzt)

Anschließend wird mit Modulo-Division festgestellt, ob ein Rest (=1, also ON) bleibt.

AnzeigeBit = Wert / &B 0000 1000 MOD 2

oder alternativ schiebt man nach rechts um drei Bit

AnzeigeBit = Wert SHR 3 MOD 2

Danach kann abgefragt werde:

If AnzeigeBit = ON then ... ' Achtung  Bit-Abfrage (OFF/ON bzw. 0/–1)

Bei direkter Abfrage ist das Ergebnis eine Zahl 0 bzw. 1.

If Wert SHR 3 MOD 2 = 1 then .. ' Achtung  Wert-Abfrage (0/1)

nach_oben

(3) Wordregister unterteilt in Nibble (4 Bit)

Register schieben und Neuwert einlesen (für Historie)

Das Register hat 3 Word (RW1,usw.) unterteilt in 4 Nibble, also 12 Speicherstellen.

Es kann sinngemäß erweitert werden mit mehr words.

RW3 = RW3 SHL 4  ' Erst schieben um 4 Bit

Dann Übernahme des maskierten Nibble vom anderen Word.

Dabei wird erst das Nibble maskiert (vorrangig durch Klammer),

dann 12 Bit geschoben und zusätzlich noch mal maskiert wegen evt. Bit-Fehler

und dann mit Word zusammen gefügt.

RW3 =(RW2 and &HF000)SHR 12 and &H000F or RW3

RW2 = RW2 SHL 4  ' Erst schieben um 4 Bit

RW2 =(RW1 and &HF000)SHR 12 and &H000F or RW2 ' Übernahme Nibble vom anderen word

RW1 = RW1 SHL 4 ' Erst schieben um 4 Bit

wert1 = Sollwert – TG ' Bildung Neuwert 4 Bit (Sollwert abzüglich Festwert TG)

if sollwert < TG then wert1 = 0 ' Begrenzung auf 0 bis 15 (4 Bit)

if wert1 > 15 then wert1 = 15

RW1 = RW1 or wert1 ' Übernahme Neuwert  0 - 15 (Nibble)

Registerwerte (Nibble) auslesen für Anzeige der Historie

#sp11 return RW1 and &H000F

#sp12 return RW1 SHR 4 and &H000F

#sp13 return RW1 SHR 8 and &H000F

#sp14 return RW1 SHR 12 and &H000F

#sp21 return RW2 and &H000F

#sp22 return RW2 SHR 4 and &H000F

#sp23 return RW2 SHR 8 and &H000F

#sp24 return RW2 SHR 12 and &H000F

#sp31 return RW3 and &H000F

#sp32 return RW3 SHR 4 and &H000F

#sp33 return RW3 SHR 8 and &H000F

#sp34 return RW3 SHR 12 and &H000F

Vorteilhaft wird hier Pseudo-Variable benutzt (hierzu siehe Tipps und Tricks).

Für die Anzeige wird einfach programmiert:

Anzeige =  sp13 ' Anzeige von Speicher Registerwort 1 Nibble 3

Im vorliegendem Beispiel hat man sich auf den Temperaturbereich 30 bis 55 Grad für die gespeicherten Sollwerte beschränkt.

Die Konstante TG muss also wieder hinzugefügt werden (define TG 30).

Anzeige = TG + sp13 ' Festwert TG plus Speicher Registerwort 1 Nibble 3

 

Im Kapitel Softwarebausteine werden Schieberegister mit EEPROM-Variable behandelt.

---------  ENDE  Kapitel Steuerungstechnik ----------- nach_oben

-------------------------   zurück zur   Startseite

Kostenlose Zähler und Statistiken für Ihre Website bei www.motigo.com