2. Tipps und Tricks    Teil 2  (Stand: 28.2.2008)    (zurück zu Teil_1)

Sparen_von_Variablen , Konstante, Pseudo-Variable  (mehr Variable siehe Stolpersteine)

Beispiele: Istwerte und Sollwerte

Zähler_9_Bit  bzw. Erweiterung Zähler-Byte mit  Bits (Wert 0 bis 511 bzw. 1023) 

Temporäre_Variable , gepackte Variable, Mittelwertbildung , Messwertberuhigung

Byte_und_word_als_Zwischenspeicher, Byte_und_Bit_als_Zwischenspeicher

Negative_Zahl_im_Byteformat  z.B. Minus-Temperatur im Byte

Messung_der_Zykluszeit eines Programmdurchlaufs, Einsparen_von_Zykluszeit Bedienungstakt

5 statt 4 GOSUB

Störungsverlauf  bereits vor Eintritt der Störung speichern (Fehleranalyse)  NEU

Teil 2 Fortsetzung  Uhr     (Stand: 25.9.2008)

Sytem-Uhr und Funk-Uhr , Ausgabe Dow-Text  Mo Di Mi Do Fr Sa So  Zugriff auf Tabelle

Letzter Tag im Monat , Sommerzeit_bestimmen    Remanentes Merker-Bit  

Teil 2 Fortsetzung   Datum_berechnen  (Stand: 25.9.2008)

Tagnummer im Jahr, DOW Tagnummer in der Woche, Wochen-Nummer im Jahr

Osterdatum und Rosenmontag, Karfreitag, Himmelfahrt, Pfingsten  NEU überarbeitet

 Datum von Buß- und Bettag, Muttertag, Sommerzeit  berechnen, Advent

 Steuern mit Feiertagsbit für Heizung und Rollladen

Weiter zu Tipps und Tricks Teil 3

Zeittakte mit Uhrzeit und TIMER, Wartezeit,

(Schaltuhr siehe Softwarebausteine)

Weiter zu Tipps und Tricks Teil  4

Überschreitung von 32767 beim Rechnen, Begrenzen      

Zählen bis 65535 im word, Zahl  0 bis 65535, Anzeigen mit 1 bis 2 Kommastellen

Zahlen über 65535  Zähler, Addition, Multiplikation, Division NEU 


Phantasie ist wichtiger als Wissen.  (Albert Einstein)

2.2.1) Sparen von Variablen

 Die Anzahl von Variablen ist bei der C-Control Station zunächst auf 24 Byte begrenzt (mehr Variable siehe Stolpersteine).

Mit den folgenden Tricks kann man Variable sparen.

(1) Istwerte nicht abspeichern

sondern dann lesen und berechen, wenn sie gebraucht werden. Beispiel Temperatur-Istwert:

define T1                 AD[5]     '   Temperatursensor 1

Define Sollwert           byte     ' Sollwert ist eine Variable

Define wert1               byte     ' Zwischenwert wird auch von anderen Programmteilen benutzt

Wert1 = T1 / 2 - 25  ' Istwert Temperatur T1 wird berechnet und in Zwischenspeicher gelegt.

If  wert1 > Sollwert then  ....

Mehrere Sollwerte

werden als Konstante in Abhängigkeit eines Grundsollwerts erzeugt.

Define Obergrenze 8     ' Konstante ist keine Variable

Define Untergrenze -5

If  wert1 > (Sollwert + Obergrenze) then  ....

If  wert1 < (Sollwert + Untergrenze) then  ....

Die Klammern sind nicht notwendig, sondern dienen nur der Lesbarkeit.

nach_oben

Pseudo-Variable

sind  im Prinzip Unterprogramme, die nicht mit gosub aufgerufen werden.

define T1 AD[5]                                 ' Temperatursensor 1

Define Sollwert           byte                 ' Sollwert ist eine echte Variable

Define Obergrenze 8                          ' Konstante

Goto EndePseudoVar ' überspringen

#Temperatur  RETURN T1 / 2 - 25   ' Temperatur ist eine Pseudo-Variable und liefert den Rechenwert.

#GrenzwertL  RETURN Sollwert + Obergrenze   ' Grenzwert  ist eine Pseudo-Variable bestehend aus Sollwert und Konstante

#EndePseudoVar

Programm

If  Temperatur > Sollwert  then  ....            ' Temperatur wird wie eine Variable benutzt

If  Temperatur > GrenzwertL  then  ....   ' Zwei Pseudo-Variable

Aber Vorsicht! Pseudo-Variable kann man nur lesen (holen).

Ohne genau ins Programm zu schauen, fügt man vielleicht später „Grenzwert = Grenzwert +1“ ein.

Diesen Irrtum kann man auszuschließen, indem ein L angehängt wird (GrenzwertL) als Kennzeichen, dass nur gelesen werden kann .

 

(2) Port als Prorammverzweigung nutzen

Die Meldung eines Betriebszustandes kann gleichzeitig als Programmverzweigung benutzt werden.

define LED1 Port [ ]

if  LED1 = ON then goto Zweig2

' ab hier wird Zweig1 bearbeitet

(3) Zähler-Byte erweitert mit  Bits  (anstelle von word)

 Jedes der beiden Verfahren  kann auch mit mehr Bits erweitert werden.

Zähler 9 Bit   (Erweiterung Byte mit 1 Bit)

define ByteZaehler         byte '  Zählerbyte    

define Bit81_88        byte  '11 (belegt von Bit 81 bis 88)

define BitZaehler       Bit[87] ' Bit wert= 256

Goto EndePseudoVar ' überspringen

 

#Zaehler RETURN  ByteZaehler – BitZaehler * 256 ' Bitwert = -1  bei ON

' z.B. 100 – (-1 *256) ergibt 100+ 256 =356

#EndePseudoVar

Abfrage im Programm:

 if  Zaehler > 300 then ..... ' Zählerwert 0 bis 511 (9 Bit)

Zähler um 1 erhöhen:

if (ByteZaehler > 254) and  BitZaehler = ON then goto Ende13  ' Zählgrenze 511

if  (ByteZaehler = 255) then BitZaehler = ON 'Bitwert 256

ByteZaehler = ByteZaehler +1 ' (nach Byte = 255 folgt 0)

 

Zähler 10 Bit   (Erweiterung Byte mit 2 Bit)

define ByteZaehler         byte '  Zählerbyte    

define Bit81_88          byte [11] ' (belegt von Bit 81 bis 88)

define Bit8Zaehler       Bit[84] ' Bit wert= 256 (z.B. Bit84)

define Bit9Zaehler       Bit[87] ' Bit wert= 512

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

define Wert2               byte[8] ' Zwischenspeicher 2

define Wert12           word[4]'= Byte 7,8

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

define wert1Bit1           Bit [50]

Goto EndePseudoVar ' überspringen

 

#Zaehler RETURN  ByteZaehler – Bit8Zaehler *256- Bit9Zaehler *512 ' Bitwert = -1  bei ON

#EndePseudoVar

Abfrage im Programm:

 if  Zaehler > 700 then ..... ' Zählerwert 0 bis 1023 (10 Bit)

Zähler um 1 erhöhen:

wert12 = Zaehler  'Pseudovariable  laden

if wert12 > 1022 then goto Ende13 ' Zählergrenze 1023

wert12 = wert12 + 1 ' Zähler + 1

ByteZaehler = wert2 'Byte rückladen

Bit8Zaehler = wert1Bit0

Bit9Zaehler = wert1Bit1 'Bits rückladen

nach_oben

(4) Temporäre Byte-Variable

Einstellwerte (zum Beispiel die Uhrzeit der Nachtabsenkung oder Schritt-Nr) müssen ständig gespeichert bleiben.

Andere Werte können temporär ein Byte belegen. Im Programm lauten sie Wert1 , Wert2 und Wert3.

Das sind Rechenwerte, die bei Bedarf für die Steuerung oder Anzeige berechnet werden, Zwischenwerte bei Berechnungen und Zahlenübergaben an die LCD-Anzeige.

Wert1 = HOUR : GOSUB ZAHL2   Das Unterprogramm GOSUB benutzt Wert1 als Zwischenspeicher.

Danach steht der Zwischenspeicher sofort wieder zur Verfügung und wird neu belegt:

Wert1 = MINUTE : GOSUB ZAHL2  

(5) Temporäre Bit-Variable (Maskierung)

Feste Bitwerte sind Befehle wie zum Beispiel „Nachtabsenkung Ein“. Der Minuten-Impuls wird jedoch nur einmal je Minute am Programmanfang erzeugt und im Steuerungsprogramm benutzt. Anschließend im Programm-Abschnitt LCD-Anzeige wird er nicht mehr benötigt.

Die Anzeige-Nummer (Bild-Nr.) steht z.B. im Byte [1] und belegt nur das rechte Nibble also die Bits 1 bis 4 (maximaler Wert 15 zulässig). Die Bits 5/6/7/8 werden im Steuerungsteil gesetzt, ausgewertet und bei Auswertung der Anzeige-Nr. gelöscht.

AnzeigeNr = AnzeigeNr SHL 4 : AnzeigeNr = AnzeigeNr SHR 4 ' Maskierung Byte AnzeigeNr (wirkt als Reset Bit 4,5,6,7)

Oder einfacher Modulo-Division: Nach Division durch 16 bleibt der Rest (Modulo) übrig. Das ist das rechte Nibble also die Anzeige-Nr.   

AnzeigeNr  = AnzeigeNr  MOD 16

nach_oben

(6) Gepackte Variable (zwei Werte in ein Byte HEX-Format)

Die Uhrzeiten der Nachtabsenkung (Beispiel: NachtEin 21 Uhr, NachtAus 6 Uhr) sollen einstellbar sein und müssen deshalb gespeichert werden.

Hierfür werden üblich 2 Bytes benötigt. Man kommt mit 1 Bytes aus, wenn statt 21 Uhr eine Drei (=3 Stunden vor Mitternacht) gespeichert wird.

Bei der Auswertung wird sie von 24 Uhr abgezogen.

Die Stundenwerte werden in das linke und rechte Nibble eines Bytes gespeichert und vor der Auswertung maskiert in die Zwischenspeicher Wert1 und Wert2 abgelegt.

Vorbesetzung bei Start des Programms: NachtZeit = &H36 (Darstellung in HEX-Format)

Stellen der Uhrzeit NachtEin: NachtZeit = NachtZeit +16 bzw. -16 (in HEX-Format: 10, d.h. Linkes Nibble + bzw.- 1)

Stellen der Uhrzeit NachtAus: NachtZeit = NachtZeit +1 bzw. -1 (in HEX-Format: 01, d.h. Rechtes Nibble + bzw.- 1)

Auswertung (GOSUB Nachtzeit): Wert1 = NachtZeit / 16 : Wert2 = NachtZeit MOD 16

...für LCD-Anzeige NachtEin: Wert1 = 24 – Wert1 LCD-Anzeige NachtAus: Wert1 = Wert2

...für Nachtabsenkung: if (Hour < (24 – Wert1)) and (Hour >= Wert2) then goto Tagbereich

Auch hier kann zweckmäßig die Pseudo_Variable angewendet werden.

#NachtAnfangL RETURN (24 – Nachtzeit /16)

#NachtEndeL RETURN ( Nachtzeit MOD 16)

...für Nachtabsenkung: if (Hour < NachtAnfangL) and (Hour >= NachtEndeL) then goto Tagbereich

Aber Vorsicht! Pseudo-Variable können nur gelesen werden (um einen Irrtum auszuschließen, hänge ich ein L an).

Die Nachtzeit ist nur änderbar wie oben beschrieben

oder in einem Unterprogramm GOSUB NachtanfangPlus  (für linkes Nibble +1).

#NachtanfangPlus   NachtZeit = NachtZeit +16 : RETURN ' (statt dezimal in Hex Nachtzeit + $H 10)

nach_oben

(7) Bytes von Datum / Uhr verwenden

Wenn man auf Datum / Uhr verzichten kann und für Zeitimpulse den TIMER benutzt,

 kann man mit dem Befehl second = 0 die Uhr sperren.

Dadurch hat man die folgenden 6 Bytes für Werte 0 bis 255 frei:

MINUTE , HOUR , DOW , DAY , MONTH , YEAR

Außerdem sind die zugehörigen Altwerte frei, die allerdings nur indirekt benutzt werden können (siehe RAM im Kapitel „Softwarebausteine“ Teil 3).

Zeit-Impulse für Zähler, Datenloggen, usw. siehe Teil 4.

nach_oben

2.2.2) Mittelwertbildung

Mittelwert = Summe der Messungen / Anzahl der Messungen

Im folgenden Beispiel wird der Mittelwert der Vorlauftemperatur eines Tages ermittelt. Sinngemäß kann der Mittelwert der Tagestemperatur gebildet werden.

Das Besondere an dem folgenden Verfahren ist der Teiler „Anzahl der Messungen“. Die Temperatur wird jede Minute gemessen. Die Anzahl ist also identisch mit der Minutenzahl des Tages.

(1) Messung je Minute

if (Min1puls = OFF) then goto Ende24  ' Aufrufbit einmal je Minute

'Mittelwert des Tages bilden, am Tagesanfang wird der Mittelwert rückgesetzt.

If (hour * 60 + minute)  > 0 then TempMittelwert = TempMittelwert + VorlaufTemp  else TempMittelwert = VorlaufTemp

(2) Anzeige des Mittelwertes aus word bis 32676

Die 1. Messung erfolgte bei Tagesminute gleich Null. Deshalb wird bei der Anzahl der Minuten +1 addiert.

print  TempMittelwert  / (hour*60+ minute + 1) ;

Die Anzahl der Messungen (Tagesminuten +1) beträgt maximal 1440. Dadurch wird 32767 (word) schon bei mittlerer Temperatur 23 Grad ( 23 * 1440) überschritten.

Einzelne Messwerte dürfen natürlich darüber liegen. Kritisch ist immer nur die hohe Anzahl, das ist am Ende des Tages. Selbst eine vorübergehende Überschreitung ist nicht kritisch, sofern sie nicht angezeigt oder ausgewertet wird. Dies gilt auch für die folgenden Möglichkeiten.

Höhere mittlere Temperaturen können erfasst werden mit folgenden Maßnahmen einzeln oder kombiniert:

(3) Anzeige des Mittelwerte aus Word bis 65535

Die mittlere Temperatur darf  45 Grad nicht überschreiten ( 45 * 1440).

Sobald der Mittelwert 32767 überschreitet, ist die Zahl in c-control negativ interpretiert. Deshalb werden Nenner und Zähler durch 2 dividiert (SHR 1).  

if  TempMittelwert  < 0 then neg

wert12 = TempMittelwert  / (hour*60+ minute +1)  'TempMittelwert bis 32767

goto Ausgabe

#neg ' TempMittelwert 32768 bis 65535

wert12 = (TempMittelwert SHR 1 and &H7FFF) / ((hour*60+ minute + 1 ) SHR 1)

#Ausgabe

print wert12;

(4) Nur jede zweite Minute statt jede Minute messen

Dadurch beträgt die Anzahl der Messungen nur 720. Die mittlere gemessene Temperatur darf dadurch bei (2) und (3) doppelt so hoch sein.

(5) Zeitliche Einschränkung  (Tages- oder Nachttemperatur)

Die Messung erfolgt nur am Tag z.B. von 8 Uhr bis 20 Uhr

    If  hour < 8 or hour > 20 then  keineMessung

Die Anzahl der Messungen je Minute beträgt hierdurch auch nur 720. Die mittlere gemessene Temperatur darf mit dieser Ergänzung bei (2) und (3) doppelt so hoch sein.

Die Anzeige lautet anstelle (2):

If hour > 8 then wert12 = (hour – 8)*60 + minute + 1 else  wert12 = 1

If hour > 20 then wert12 = (20 – 8) * 60 ' maximale Anzahl Messungen

print  TempMittelwert  / wert12 ;

Anzeige anstelle (3) muss sinngemäß angepasst werden.

(6) Sockelwert bei der Messung und Ausgabe

Bei einer Vorlauftemperatur interessiert die Temperatur erst ab 20 Grad. Entsprechend darf die Vorlauftemperatur 20 Grad höher sein.

Messung anstelle (1):

Wert12 = VorlaufTemp - 20

If (hour * 60 + minute)  > 0 then TempMittelwert = TempMittelwert + wert12  else TempMittelwert = wert12

Anzeige anstelle (2):   print  TempMittelwert  / (hour*60+ minute + 1) + 20 ;

Anzeige anstelle (3):  auch nur + 20 addieren.

nach_oben

2.2.3) Gleitende-Mittelwertbildung (Messwertberuhigung, Dämpfung)

Anstelle vieler gespeicherter Werte kann man eines der folgenden Verfahren (im Beispiel 10-fach-Speicher) anwenden. Dabei steht der Wert mit einer Kommastelle zur Verfügung.

Speicher = Speicher + NeuWert  -  Speicher/10 ' Zum 10-fach-Speicher wird der Neuwert addiert und ein 10er-Wert subtrahiert, um wieder 10 Werte zu haben.

Speicher = (Speicher + NeuWert) - (Speicher + NeuWert) / 11 ' .....oder ein 11er-Wert subtrahiert, um wieder 10 Werte zu haben.

Speicher = (Speicher + NeuWert)*10/11 ' oder zum 10-fach-Speicher wird der Neuwert addiert, dann von 11 auf 10 Werte reduziert.

Speicher = Speicher *9/10 + NeuWert' Der 10-fach-Speicher wird auf 9 Werte reduziert und dann der Neuwert addiert.

Weitere Varianten siehe Kapitel Regelung MSR.

Bei der Multiplikation mit 10 bzw. 9 besteht eventuell die Gefahr den maximalen Wert  32 767  zu überschreiten.

Dann ist besser das erste oder zweite Verfahren anzuwenden.

Auch bei Start von Null ausgehend , bildet sich der Mittelwert. Man kann natürlich bei Neustart auch einen Wert vorgeben.

Außerdem kann der bisherige Wert auch nach einem Neustart erhalten bleiben (siehe Steuerungstechnik, Remanente Variable).

2.2.4) Gleitende Mittelwertbildung  im Byte

Auch 1 Byte kann reichen. Bei Temperaturwerten von 0 bis 80 Grad kann ein 3-fach-Wert gespeichert werden und dadurch die Genauigkeit (Kommastelle) bei schwankenden Temperaturen (statistisch) erhöht werden, eine Messwert-Dämpfung oder eine Messwert-Beruhigung erzielt werden.

Speicher = (Speicher + NeuWert) *3 / 4 ' Zum 3-fach-Speicher wird der Neuwert addiert, dann von 4 auf 3 Werte reduziert.

Für Anzeige = Speicher / 3 und für Kommastelle = Speicher MOD 3 * 3 (möglich 0 , 3 , 6)

2.2.5) Gepackte-Gleitende-Mittelwertbildung

Falls man nur ein Byte verwenden möchte, kann ein fester Sockelwert vorgesehen werden.

Beispiel: Bei einer Temperaturmessung von 20 bis 80 Grad wird vor dem Speichern der Sockel 20 Grad abgezogen.

Hierdurch können in einem Byte statt 3*80  nun  4* (80 - 20) gespeichert werden. Der Neuwert beträgt also (Temp –20).

Speicher = (Speicher + Temp – 20)*4 / 5

Für die Ausgabe wird der Sockelbetrag wieder addiert:

Mittelwert = Speicher / 4 + 20

Selbstverständlich können alle oben genannten Verfahren der Gleitenden Mittelwertbildung mit Sockelbetrag benutzt werden.

nach_oben

2.2.6) Byte und word als Zwischenspeicher

Zwischenwerte (Rechenergebnisse) können für die weitere Bearbeitung in Zwischenspeicher gelegt werden.

Die Zwischenspeicher werden von anderen Programmteilen auch benutzt.

Außerdem kann durch Überlappung der Speicher Bithandling und Maskierung durchgeführt werden.

define AnzeigeNr byte ' Byte 1

define Bit9_16 byte ' Byte 2 = Bit 9 bis 16

define Wert1 byte ' Byte 3 Zwischenspeicher 1

define Wert2 byte ' Byte 4 Zwischenspeicher 2

define Wert3 byte ' Byte 5 Zwischenspeicher 3

define Wert12 word[2] ' = Byte 3,4 (Überlappung mit Bytes Wert1 und Wert2)

Die Bytes sind hier nicht nummeriert, sondern werden vom System in der Reihenfolge automatisch belegt.

Die Zuweisung ist bei der Definition word[2] gezielt auf dieselben Speicherzellen wie Byte 3 und 4 festgelegt (Überlappung).

Dadurch können Zwischenwerte sowohl als Byte als auch als word benutzt werde.

Beispiel Maskierung:

Wert12 = TIMER ' der Timer-Wert wird in word geladen (=Byte1 und Byte 2)

if wert1 = 3 then goto... ' das obere Byte vom Timer wurde durch das Byte maskiert.

TIMER siehe auch Teil „Softwarebausteine“.

Beispiel für Zusammenfügen zur Speicherung auf EEPROM Speicher 5:

Wert1 = TemperaturA

Wert2 = TemperaturB

Zeiger = 5 : print# wert12  ' Ziel EEPROM-Speicher word 5

Datenquelle ist der Zwischenspeicher Wert12 (word). Ziel ist EEPROM-Datei Speicher 5.

Wert1 und Wert2 sind linkes und rechtes Byte von Wert12 (word).

Schreiben und Lesen der EEPROM-Datei  mit Zeiger (=Speicherplatz) siehe Kapitel „Softwarebausteine“.

 nach_oben

2.2.7) Byte und Bit als Zwischenspeicher

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

define wert1Bit1 Bit [18]

define wert1Bit2 Bit [19]

define wert1Bit3 Bit [20]

define wert1Bit4 Bit [21]

define wert1Bit5 Bit [22]

define wert1Bit6 Bit [23]

define wert1Bit7 Bit [24]

Zur einfacheren Anwendung sind die Bits mit ihren Bitwerten (Hochzahl 0 bis 7) bezeichnet.

Die Zuweisung ist gezielt auf dieselbe Speicherzelle wie Byte 3 (Wert1) festgelegt (Überlappung).

Folgende Bausteine sollen die Anwendung zeigen:

Beispiel 1:

Minpuls = OFF ' Reset Minutenimpuls

Wert1 = Minute ' In den Zwischenspeicher wird der Minuten-Wert der C-Control-Uhr gesetzt

if Wert1Bit0 = FlankeMinute  then goto Ende1 ' Bit 0 wechselt  jede Minute (ON-OFF-ON-...)

FlankeMinute = Wert1Bit0 ' Setze Flanke (nur einmaliger Durchlauf je Minute)

Minpuls = ON ' Aufrufbit einmal je Minute

#Ende1

Beispiel 2:

Minpuls = OFF : ZweiMinpuls = OFF ' Reset Minutenimpulse

Wert1 = Minute ' In den Zwischenspeicher wird der Minuten-Wert der C-Control-Uhr gesetzt

if Wert1Bit0 = FlankeMinute  then goto Ende2 ' Bit 0 wechselt  jede Minute

FlankeMinute = Wert1Bit0 ' Setze Flanke (nur einmaliger Durchlauf je Minute)

Minpuls = ON ' Aufrufbit einmal je Minute

if Wert1Bit0 = ON then ZweiMinpuls = ON ' Bit 0 ist jede zweite Minute ON und setzt Zwei-Minuten-Impuls

#Ende2

Beispiel 3:

Minpuls = OFF : ZweiMinpuls = OFF ' Reset Minutenimpulse

if (second > 5) and (second < 20) then goto setz ' zum Setzen Minuten- und ZweiMinutenImpuls

FlankeMinpuls = OFF ' Reset Flanke für nächste Minute

Goto Ende3

#setz

if (FlankeMinpuls = ON) then goto Ende3 '

FlankeMinpuls = ON ' Setze Flanke (nur einmaliger Durchlauf je Minute)

Minpuls = ON ' Aufrufbit einmal je Minute

Wert1 = Minute ' In den Zwischenspeicher wird der Minuten-Wert der C-Control-Uhr gesetzt

if Wert1Bit0 = ON then ZweiMinpuls = ON ' Bit 0 ist jede zweite Minute ON und setzt Zwei-Minuten-Impuls

#Ende3

nach_oben

2.2.8) Negative Zahl im Byteformat

Negative Zahlen sind nur im Wordformat vorgesehen.

In einem Byte kann jedoch auch eine negative Zahl (z.B. eine Temperatur) gespeichert und verarbeitet werden.

Der Zahlenwert des Byte beträgt 0 bis 255 und im Fall der negativen Zahl + 127 bis – 128. Bit 7 ist das Minus-Bit gleich Wert 128. Dieses Bit ist bei  negativen Zahlen im word-Format bei – 1 bis –128 immer gesetzt und wird das Minus-Bit im Byte-Format.

Wert1 = - 20 bedeutet, dass im Byte „wert1“ die Zahl 256-20 also 236 steht. Will man sie auf der LCD-Anzeige ausgeben, muss sie umgeformt werden.

Wert1 = T1/2-25 ' Temperaturmessung -25 bis 102 Grad (Beispiel minus 20 Grad)

gosub ZAHL2pm ' Die folgende Routine bewirkt Ausgabe Minus-Zeichen und Ausgabe der Zahl 20

Nur diese zwei Befehle müssen gegeben werden, den „Rest“ erledigt die Routine gosub.

----------- Erläuterung zu Routine gosub ZAHL2pm  -----------------------------------------

#ZAHL2pm ' 2 Ziffern plus minus (3 Plätze -99 bis +99)

if (wert1 < 128) then goto Positiv ' Bei minus 20 Grad steht im Byte der Wert 236

wert1 = 256 - wert1 ' nun steht im Byte 256-236 also 20

gosub Minus : goto Zahl2 ' Ausgabe Minuszeichen, 2-stellige Zahl

#Positiv

gosub Plus ' Ausgabe Pluszeichen

#Zahl2 ' 2 Ziffern (2 Plätze 0 bis 99) ausgeben

if (wert1 > 99) then goto ZZ ' Zahl zu groß

Wert3 = Wert1/10 : gosub Ziffer ' Maskierung Zehner + Ausgabe Ziffer

#Einer

Wert3 = Wert1 Mod 10 : goto Ziffer ' Maskierung Einer + Ausgabe Ziffer

#ZZ

CHAR = &HBF : SYS LCD_WRT  ' Zeichen(?) für Zehner ausgeben

' CHAR = &H3F bei anderen LCD Ausgaben

goto Einer ' ausgeben

#Ziffer ' (gosub Ziffer) gibt 1 Ziffer im Speicher "Wert3" auf LCD aus

CHAR = Wert3 + &HB0 : Goto SYS_WRT ' LCD Ausgabe-Routine

' CHAR = ... +&H30 bei anderen LCD Ausgaben

&HBF

#plus

 CHAR=&HAB:  Goto SYS_WRT 'Zeichen +

' CHAR = &H2B bei anderen LCD Ausgaben

#minus

 CHAR=&HAD:  Goto SYS_WRT 'Zeichen –

' CHAR = &H2D bei anderen LCD Ausgaben

 

#SYS_WRT  ' I/O-Treiber siehe Softwarebausteine

SYS LCD_WRT : Return ' Rückkehr zum letzten gosub-Befehl

nach_oben

2.2.9) Messung der Zykluszeit eines Programms

Für Steuerungen ist es oft wichtig die Zykluszeit eines Programms zu kennen, denn nur in diesen Zeitabstand wird der einzelne Befehl bearbeitet.

Besonders bei Maschinen kann es zu erheblichen Problemen kommen, wenn nach Erreichen des Endschalters das Programm z.B. erst 1 Sekunde danach diesen Abschaltbefehl durchführt.

Zur Messung wird der freilaufende 20 ms – Timer benutzt.

define TimerAlt     word ' Altwert Zykluszeitmessung

define Anzeige      word '

Das Messprogramm bildet Differenz des aktuellen Timer-Werts zum vorherigen gespeicherten Altwert.

Anzeige = (Timer – TimerAlt) * 20 ' Anzeige in Millisekunden

TimerAlt = Timer ' Bildung des Altwerts

nach_oben

2.2.10) Einsparen von Zykluszeit

Die Tastatur wird nur alle 2 Sekunden bearbeitet. Bei diesem Durchlauf wird nicht das Anzeigeprogramm durchlaufen.

Außerdem kann durch  Festhalten der Taste, eine taktweiße Funktion erreicht werden z.B. um Zähler zu stellen.

if sek2puls = ON then gosub Tastatur else  gosub Anzeige ' Verzweigung  Tastatur oder  Anzeigen

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

#Tastatur '   Unterprogramm

if not F1 then goto AnzeigeNrstellen 

goto Ende

#AnzeigeNrstellen

Anzeige = Anzeige + 1 '  Taktweißes Erhöhen

nach_oben

2.2.11)      5 statt 4 GOSUB

Die maximal zulässige Schachteltiefe der Unterroutinen ist 4.

Die letzte Befehlsfolge GOSUB : RETURN wird ersetzt durch GOTO, d.h. zur letzten Unterroutine wird mit GOTO gesprungen.

Deren RETURN bewirkt den Rücksprung hinter den ersten GOSUB.

Benötigt man 5 Unterroutinen kann man auf diese Weise 4 GOSUB und 1 GOTO anwenden.

Schachteltiefe bedeutet, dass innerhalb der Unterroutine vor Erreichen des Befehls RETURN ein neuer Befehl GOSUB erfolgt.

Im folgenden Beispiel wird die Reduzierung von zwei GOSUB auf ein GOSUB gezeigt.

Befehl im Hauptprogramm: GOSUB x1 : .........

#x1

GOSUB x2 : RETURN (weiter bei Befehl hinter GOSUB x1) ....Ersatzbefehl: GOTO x2

#x2....................................................................................................... #x2

.... : RETURN (weiter bei Befehl hinter GOSUB x2) ................... : RETURN (weiter bei Befehl hinter GOSUB x1)

nach_oben

2.2.12)      Störungsverlauf bereits vor Eintritt der Störung speichern

Aufgabe:  Wenn eine Störung auftritt, soll die Datenspeicherung 5 Minuten vorher beginnen.

Dies ist scheinbar ein Widerspruch. Wie soll man eine Datenspeicherung vor Eintritt eines Ereignisses starten? Zum Beispiel kann man 10:05 Uhr nicht wissen, dass 10:10 Uhr eine Störung sein wird!

Lösung: Der Messwert wird z.B. alle 30 Sekunden in einen Ringspeicher geschrieben, z.B. 10 Messwerte. Der 11.Messwert wird wieder auf  Speicher 1 geschrieben.

Tritt eine Störung (Ereignis) auf, werden die 10 Messwerte in der Reihenfolge beginnend mit dem ältesten abgespeichert und anschließend noch mehrere Messwerte nach der Störung. So erhält man einen Störungsverlauf zur Fehleranalyse und kann ermitteln, wie es zu der Störung kam.

 

------------------------------------------------  Fortsetzung Teil 2 Uhrzeit und Datum berechnen ------------  nach_oben

 --------------------- weiter zu  Teil 3   Teil 4    zurück zu Tipps und Tricks Teil_1                        Startseite 

 

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