Bascom Probleme mit DEBOUNCE und einem 16x2 LCD

Hallo Cassio, :hello:

ja ist denn schon Weihnachten??? Das ist nun wirklich mehr Hilfe als man erwarten kann - tausend Dank dafür!!! :adore: Ich werde mir dein Programm natürlich zu Gemüte führen und dir vom Weiterkommen berichten, ist doch klar!

Schöne Grüße
Robin
 
Hallo Cassio,

ich habe nun mal mein IF - Then - Arrangement umgeschrieben, voila! Viel gelernt dabei - Umwandlung von bytes in string, Festlegung der Dezimalstellen durch Formatierung und ich habe einen Einblick in die Anwendung der Case-Nutzung bekommen. Wie hilfreich ein Praxisbeispiel doch sein kann!!!!!! Hier mal der Code:

Code:
$regfile "m8def.dat"
$crystal = 1000000
$framesize = 64
$hwstack = 64
$swstack = 64

Config Lcdpin = Pin , Rs = Portc.5 , E = Portc.4 , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0
Config Lcd = 16 * 4

Cursor Off
Cls


Config Pind.4 = Input
Portd.4 = 1

Config Pind.0 = Output


Dim X As Bit
X = 1
Dim Y As Byte
Y = 0


Config Debounce = 100

Config Clock = Soft , Gosub = Sectic
Time$ = "00:00:00"

Enable Interrupts


Dim Flag_x As Byte
Dim Flag_y As Byte
Dim Flag_z As Word


Dim Sec_flag As Bit
[COLOR="#008000"]Dim Str_temp As String * 3[/COLOR]

Dim B As Byte




Do

Debounce Pind.4 , 0 , Anzeigen , Sub


If Sec_flag = 0 Then
   Locate 1 , 5
   Lcd Time$
   Sec_flag = 1
  Else
End If



Loop


'******************************


Anzeigen:

Cls

Locate 2 , 1

Select Case Y
   Case 0 : Lcd " Gut so         "
   Case 1 : Lcd " Weiter so      "
   Case 2 : Lcd " aha            "
   Case 3
         Do
         Str_temp = Str(flag_y)
         Str_temp = Format(str_temp , "000")
         Locate 3 , 3
         Lcd Str_temp

         [COLOR="#B22222"]Waitms 100[/COLOR]

         Loop Until Pind.4 = 0
         Bitwait Pind.4 , Set

   Case 4
         Do
         Str_temp = Str(flag_x)
         Str_temp = Format(str_temp , "000")
         Locate 3 , 3
         Lcd Str_temp

         [COLOR="#A52A2A"]Waitms 100[/COLOR]

         Loop Until Pind.4 = 0
         Bitwait Pind.4 , Set

   Case 5
         Do
         Str_temp = Str(flag_z)
         Str_temp = Format(str_temp , "00000")
         Locate 3 , 3
         Lcd Str_temp

         [COLOR="#A52A2A"]Waitms 100[/COLOR]

         Loop Until Pind.4 = 0
         Bitwait Pind.4 , Set

End Select



[COLOR="#A52A2A"]Waitms 100[/COLOR]
Bitwait Pind.4 , Set

If Y < 5 Then
   Incr Y
Else
   Y = 0
End If


Return

'********************************

Sectic:
Toggle Portd.0
Sec_flag = 0

Incr Flag_x
Decr Flag_y
Decr Flag_z

Return


Das Programm funktioniert soweit jetzt ganz gut, wirft aber noch einige Fragen auf:
  • Str_temp As String * 3 hattest du mit 5 Zeichen gesetzt, warum? Ich hatte mal 3 eingesetzt, 2 byte für Flag_z as word + 1 für die Null-byte- Geschichte innerhalb des strings. Mit 3 läuft's auch oder gibt es da besondere Gründe?
  • Wenn das Programm per Tastendruck durchlaufen wird, werden die ersten drei Anzeigen "Gut so" etc. problemlos dargestellt. Ab Case 3, wenn die Flags angezeigt werden, wird es für mich nicht nachvollziehbar: Mit dem vierten Tastendruck wird mir die abwärtszählende Flag_y angezeigt, auch richtig. Ein weiterer Tastendruck zeigt nun den letzten angezeigten Flagwert, sozusagen eingefroren, an, wie in einer Hold-Funktion. Dass nun die Uhrzeit zusätzlich angezeigt wird, ist für mich ein Zeichen dafür, dass das Programm in der Hauptschleife weiterläuft, anstatt zu Case 4 zu springen. Das ist nicht weiter schlimm, mich würde es aber schon interessieren, weshalb das Programm ausgerechnet dann in die Hauptschleife höppelt.
  • Die Wartezeiten innerhalb der Sub "Anzeigen" machten richtig Ärger, zuerst als sie fehlten oder auch, wenn sie zu klein ( <100 ms) oder zu groß (>400 ms) gewählt werden. Wie geht man mit diesen Zwangspausen eigentlich richtig um und wann ist es sinnvoll, sie überhaupt zu setzen? Mir haben sie Stunden des Herumpriemens gekostet, ganz zu schweigen vom Frust der sich aufbaut, wenn's nicht funktionieren will obwohl (nach Kenntnisstand) es eigentlich passen müsste.

    Aber was behauptete einst Hanns Dieter Hüsch von den Rheinländern? Sie wissen eigentlich nichts, können aber alles erklären! Letzteres trifft für mich, jedenfalls was das Programmieren betrifft, nicht einmal zu! Na dann mal:cheers:

Schöne Grüße
Robin
 
Hallo Robin!

Ich habe mal wieder nicht viel Zeit, aber ich wollte dir kurz noch mal etwas schreiben. :wink:


Str_temp As String * 3 hattest du mit 5 Zeichen gesetzt, warum?

Die String-Variable "Str_temp" muss immer so hoch gesetzt werden, wie der maximale String auch Zeichen bzw. Stellen hat!
Wenn du also einen String mit 5 Zeichen hast...... zum Beispiel: "12345" .....dann musst du es auch mit STRING * 5 dimensionieren.

Mit den Bytes für den String hast du zwar recht.... hast dabei aber einen Denkfehler gemacht.
In einem String (wie in meinem Beispiel: 12345) benötigt jede Stelle ein Byte! :cool:

Der String "12345" sieht dann im Speicher eigentlich so aus:
Byte1= &H31
Byte2= &H32
Byte3= &H33
Byte4= &H34
Byte5= &H35
Byte6= &H00

Das letzte Byte (Byte6) mit dem &H00-Abschluss für den String setzt BASCOM automatisch und du musst es nicht bei der Angabe berücksichtigen.


Wenn du also alle fünf Stellen deines Words (Flag_z) darstellen möchtest, dann MUSS deine Stringvariable auch FÜNF Zeichen lang sein (String * 5).

Anderenfalls kann es dir passieren, dass der Speicherbereich überschrieben wird und dein Programm plötzlich Dinge macht, die unverständlich, fehlerhaft und nicht nachvollziehbar sind. :wink:




Nun hast du wieder mit der DO-LOOP Schleife innerhalb von "CASE 3" und "CASE 4"gearbeitet.
Das ist ja auch OK und völlig in Ordnung.
Dein Problem ist aber, dass du nur mit einem Taster arbeitest.... dem PIND.4 !

Einerseits benötigst du den Taster um in die Sub zu springen..... andererseits möchtest du damit aber auch die DO-LOOP Schleife abbrechen.
Natürlich kann man das so machen, allerdings musst du dann die BITWAIT-"Bremse" auch gleich noch zu Beginn verwenden.
Anderenfalls kann es dir passieren, dass du nicht schnell genug den Taster loslassen kannst und dein Programm scheinbar den Menüpunkt überspringt.

Du musst also diesen Bereich:
Code:
         Do
         Str_temp = Str(flag_y)
         Str_temp = Format(str_temp , "000")
         Locate 3 , 3
         Lcd Str_temp

         Waitms 100

         Loop Until Pind.4 = 0
         Bitwait Pind.4 , Set

mindestens in "CASE 3" und "CASE 4" noch mal ändern!


Zu Beginn würde ich dir aber empfehlen einfach einen zweiten Taster zu verwenden! :cool:
Das erleichtert dir die Programmierung und das Lernen beim Programmablauf. :wink:


Grüße,
Cassio
 
Hallo Cassio :hello:,

habe den Code nochmals überarbeitet, anstatt in einer Sub in die Hauptschleife gesetzt (Deine Tips aus anderen Beiträgen befolgt:D), habe dann noch einen "automatischen" Anzeigedurchlauf dazu "gedichtet" und kann nun per Tastendruck zwischen einer automatisch durchlaufenden Anzeige und einer manuell fortlaufenden Anzeige der Werte, ebenfalls per Tastendruck, wählen. Das Hochzählen der Variablen x und y habe ich nun nur noch in den Subs stehen. Da die restlichen Programmteile nun in der Hauptschleife stehen, ist die Do - Loop until - Geschichte überflüssig geworden. Ich denke nun erkannt zu haben, welche Vorteile in der Ausnutzung der Hauptschleife und in spartanisch gehaltenen Subs liegen. So löste sich auch das Problem der auf dem LCD verbliebenen und nicht überschriebenen Anzeigenreste fast wie von selbst, da sich mir andere Programmiermöglichkeiten eröffneten. Et löppt, und zwar ganz zufriedenstellend!

Ich habe aber noch mal eine Frage beim Dekrementieren eines PWM1a- Wertes, aber nicht mehr heute.

Hier noch der Quellcode, den ich noch nicht von überflüssigen Resten befreit habe, und dann gehe ich schlafen. Die letzten Nächte hatte ich mir hiermit um die Ohren geschagen, nun ist gut, erstmal!

Code:
$regfile "m8def.dat"
$crystal = 1000000
$framesize = 100
$hwstack = 100
$swstack = 100

Config Lcdpin = Pin , Rs = Portc.5 , E = Portc.4 , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0
Config Lcd = 16 * 4
Config Lcdbus = 4

Cursor Off
Cls

Config Pind.4 = Input
Portd.4 = 1

Config Pind.5 = Input
Portd.5 = 1
Taster_set Alias Pind.5

Config Pind.0 = Output
Config Pinb.0 = Output
Config Pinb.1 = Output
Config Pind.6 = Output
Config Pind.7 = Output


Config Timer0 = Timer , Prescale = 8
Timer0 = 131
Enable Timer0
On Timer0 Cls_isr


Dim A As Byte
A = 0

Dim X As Byte
X = 0
Dim Y As Byte
Y = 0
Dim B As Byte
B = 1
Dim W As Bit
W = 1

Config Debounce = 100

Config Clock = Soft , Gosub = Sectic
Time$ = "00:00:00"

Enable Interrupts


Dim Flag_x As Byte
Flag_x = 0

Dim Flag_xx As Byte
Flag_xx = 0

Dim Flag_y As Byte
Flag_y = 255

Dim Flag_z As Word
Flag_z = 0

Dim Flag_c As Byte
Flag_c = 0


Dim Sec_flag As Bit
Dim Str_temp As String * 5




Do


Locate 1 , 4
Lcd Time$

Debounce Pind.4 , 0 , Man_anzeige , Sub
Debounce Pind.5 , 0 , Auto_man , Sub




'******************************************
'Automatik
'******************************************

Select Case W
Case 0 :
  Portd.7 = 1
  Portd.6 = 0


'##################################################
'Manuell
'##################################################


Locate 2 , 1

Select Case Y
   Case 0 : Lcd " Gut so         "
   Case 1 : Lcd " Weiter so      "
   Case 2 : Lcd " aha            "


   Case 3
         Str_temp = Str(flag_y)
         Str_temp = Format(str_temp , "000")
         Locate 3 , 3
         Lcd Str_temp



   Case 4
         Str_temp = Str(flag_x)
         Str_temp = Format(str_temp , "000")
         Locate 3 , 3
         Lcd Str_temp



   Case 5
         Str_temp = Str(flag_z)
         Str_temp = Format(str_temp , "00000")
         Locate 3 , 3
         Lcd Str_temp


End Select



'###############################################################################
'Automatik
'###############################################################################


Case 1 :

      Portd.7 = 0
      Portd.6 = 1

        If Flag_xx > 3 Then
         Flag_xx = 0
         Incr X
        End If



        Locate 4 , 2
         Lcd Flag_xx ; "  "


Locate 3 , 4

Select Case X

Case 0 : Lcd "Weiter so  "

Case 1 : Lcd "Gut so     "

Case 2 : Lcd "aha        "

Case 3 :

        Str_temp = Str(flag_x)
        Str_temp = Format(str_temp , "000")
        Lcd Str_temp

Case 4 :
        Str_temp = Str(flag_y)
        Str_temp = Format(str_temp , "000")
        Lcd Str_temp

Case 5 :
        Str_temp = Str(flag_z)
        Str_temp = Format(str_temp , "00000")
        Lcd Str_temp


End Select

Locate 2 , 1
Lcd X ; "  "

If X > 5 Then
X = 0
End If



End Select


Loop





'Wechsel zwischen automatischer
'und manueller Anzeige
Auto_man:

Toggle W
Cls

Return



'********************************

Sectic:
Toggle Portd.0
Incr Flag_x

Decr Flag_y
Decr Flag_z
Incr Flag_xx

Return




Man_anzeige:

If Y < 5 Then
   Incr Y
Else
   Y = 0
End If
 Cls
Bitwait Pind.4 , Set


Return



Cls_isr:


Return


Schönen Dank nochmals, Deine Tips waren, wie immer, sehr, sehr hilfreich!:flowers:

Robin
 
...... anstatt in einer Sub in die Hauptschleife gesetzt (Deine Tips aus anderen Beiträgen befolgt:D)


Hallo Robin!

Dazu soll ich dir geraten haben? :hmmmm:
Bist du sicher?

Gerade ich, als verfechter der Subroutinen, würde dir das doch bestimmt nicht empfohlen haben.


So richtig gefällt mir dein Programm jetzt auch nicht mehr.
Die saubere Struktur ist nun verloren gegangen.

Stattdessen ist die Hauptschleife nun ein "verschachteltes Etwas" und dein LCD unterliegt jetzt auch wieder dem Dauerfeuer.

Sei doch so gut und schau dir mein Beispielprogramm noch mal genau an!
Ich habe zum Beispiel das Bit "Sec_flag" eingesetzt.
Das "Sec_flag-Bit" sorgt dafür, dass dein LCD nur dann mit Daten angesteurt wird, wenn es auch etwas neues anzuzeigen gibt.
Ohne das Bit würde dein LCD bei jedem DO-LOOP Durchlauf mit Daten versorgt werden..... auch wenn sich der Inhalt der Anzeige nicht geändert hat.
Tja und dein alter Schleifendurchlauf, als du noch die Sub "Anzeigen" verwendet hast, lag bei etwa 30µs! :wink:


Lange Rede, kurzer Sinn....
Lieber mehrere Subroutinen erstellen, als eine unübersichtliche DO-LOOP Schleife!

Als nächstes solltest du dir mal dein Programm im Simulator ansehen.... wenn du mit der Bedienung vertraut bist.
Anderenfalls wäre für dich auch eine serielle Terminalanbindung sehr hilfreich.

Was möchtest du also lieber verwenden?
Den Simulator, oder ein serielles Terminal?


Grüße,
Cassio
 
Hallo Cassio,

nun bin ich wieder geplättet, doppelt sogar! Ich hätte Stein und Bein darauf geschworen, dass du hier im Forum vehement die Ansicht vertreten hattest, die Hauptschleife vorrangig zu nutzen und in Subs nur das Wesentliche unterzubringen. Gut, wenn du's schreibst, kennst dich und deine Vorlieben halt besser als ich; akzeptiert!:)

Die Vorteile, die ich in der letzten Version sehe, liegen für mich darin, dass ich die Do - Loops until ... nicht mehr benötige, ich keine Schwierigkeiten beim Löschen der Anzeige habe, da beim Hochzählen von Y problemlos ein cls gesetzt werden kann und die Taster schalten satt, der "Hold-Effekt" ist nebenbei auch noch weg. Aus meiner Sicht war das schon sehr komfortabel, aber du hast halt die Routine auf deiner Seite und ich nehme alles an, wozu du mir rätst!

Tja, obwohl das Gefühl oft ein schlechter Ratgeber ist, tendiere ich erst einmal zum Simulator.

Schöne Grüße

robin
 
Ich hätte Stein und Bein darauf geschworen, dass du hier im Forum vehement die Ansicht vertreten hattest, die Hauptschleife vorrangig zu nutzen und in Subs nur das Wesentliche unterzubringen.


Hallo!

Damit es hinterher nicht wieder zu einer fehlerhaften Interpretation kommt....
Deine Aussage von oben ist natürlich auch OK. :wink:

Generell sollte eine Subroutine kurz und bündig sein und den Controller nicht lange in einer Schleife binden.
Ausnahmen bestätigen aber auch hier die Regel. :cool:

Grundsätzlich würde ich es mal so ausdrücken.....
In die Hauptschleife kommt alles, was sich ändern könnte (Taster, Sensoren usw.).
Die Ausführung der Änderung, oder die Erfassung/Auswertung eines Sensors sollte aber besser in Subroutinen geschehen.

Ein goldenes Rezept wird es aber wohl nie geben..... nur eben "geordnete" Strukturen im Programm. :wink:
Es kommt einfach auf das Programm und den Verwendungszweck an!

Ich habe auch schon mal ein Programm geschrieben, bei der in einer Hauptschleife nichts passiert..... außer den Controller schlafen zu schicken. Der Rest wird ausschließlich in Subroutinen erledigt.
Das kann bei batteriebetriebenen Geräten schon mal ganz praktisch sein. :wink:


Lass dich also nicht weiter "durcheinander" bringen und schreibe dein Programm erst mal so, wie du es am Besten verstehen kannst.
In laufe der Zeit wirst du hinter die ein oder andere "Technik" kommen und diese dann auch immer weiter verbessern.
Irgendwann findet halt jeder seinen Programmierstil. :)



Dein Gefühl mit dem Simulator trügt dich aber bestimmt nicht.
Allerdings musst du auch den Simulator erst einmal erlernen, damit du die wertvollen Informationen wirklich findest und nutzen kannst.
Erwarte aus den ersten Übungen also bitte nicht zuviel!

Ach so....
Wenn du dein Programm im Simulator testen möchtest, dann solltest du gleich zu Beginn des Programms $sim angeben.
Nach dem Kompilieren ist das Programm dann für den Simulator auch "optimiert"!


Grüße,
Cassio
 
Hi
Auch wenn ich von BASCOM nicht grad viel Ahnung hab, möchte ich noch mal den Vorteil von Sub-Routinen ansprechen. Ich weiß, da hat jeder sein eigenes Rezept, aber auch ich bin ein Verfechter von Sub-Routinen. Der Grund ist relativ einfach:
Wie baut man ein Programm auf ? Nun, man beginnt nach der Initialisierung und Variablendeklaration mit der Programmschleife. Das ist (fast) immer so. Wenn man so ganz ohne Vorbereitung einfach drauf los schreibt, dann ist nach einer Woche der Durchblick in der Regel zumm teufel. Daher hat ein schlauer Mensch den Begriff "Struktur" erfunden. Wie sieht aber ein Programmaufbau mit Struktur aus ?
Kern einer Programmschleife ist
Daten erfassen (Eingabe)
Daten verarbeiten (Verarbeiten)
Daten ausgeben (Ausgabe)
Hat man die drei Blöcke (EVA-Prinzip) definiert, beginnt die Feinarbeit.
In Assembler sieht das in etwa so aus
Code:
Loop:
   RCALL Read_IO
   RCALL Do_Something
   RCALL Write_IO
RJMP  Loop
;------- Bereich Subroutinen ---------
Read_IO:

RET
;------------------------------------
Do_Something:

RET
;------------------------------------
Write_IO:

RET
Genauso geht es in jeder Sprache. Wie du siehst, es steht noch nichts in den Sub-Routinen drin, und das ist auch der Anfang. Mit diesem Konstrukt bleibt dein Programm lauffähig und du kannst Block für Block dein Programm mit Aufgaben belegen. Es ist auch relativ einfach, den Überblick zu behalten, da du fertige Subroutinen nicht mehr anfassen mußt. Wenn die Aufgabe perfekt erledigt wird, werden sie immer den Dienst fehlerfrei erledigen. So kannst du dir zum Beispiel eine Liste anlegen und den Fortschritt dokumentieren. Bei großen Programmen behälst du den Überblick. Soll noch eine Datenübertragung zugefügt werden, kein Problem:
Code:
RCALL  Send_To_PC
in die Programmschleife und
Code:
Send_To_PC:

RET
in den Bereich der Subroutinen. Und wenn dir noch weitere Funktionen einfallen, was solls. Der Vorgang bleibt gleich. So erkennst du schnell, wie dein Programm wachsen kann, ohne das du irgendwelche Klimmzüge machen mußt. In Bascom geht das genau so.
Gruß oldmax
 
Hallo zusammen!

Ich hatte in den letzten Tagen leider keine Zeit, mich für Eure Beiträge zu bedanken und darauf zu antworten, was ich nun nachholen möchte!

Ja, Dino, die weit ausgerückten " , für die ich selbst in "Experten-Codes" nie eine Erklärung fand, hatte ich einfach mal übernommen und hatte damit Erfolg, ohne Cls einbauen zu müssen. Aber bis ich mal darauf kam, vergingen Tage des Grübelns. Leider findet man diese Tips auch in keinem Buch oder sonst irgendwo - vielleicht in einem Nebensatz eines Forenbeitrags, der aber kaum gefunden werden kann. Und spätestens da lernt man die Direkthilfe eines Forums wie dieses hier, sehr zu schätzen!!!

Cassio, ich meinte es scherzhaft und bin heute schon an die Grenzen meiner "Hauptschleife" gestoßen, als ich noch 2 Taster für die Uhrzeiteinstellung einfügen und dies anzeigen wollte. Der Schritt zu Subs ist fest eingeplant:yes4:

Oldmax, das EVA-Prinzip ist eine hervorragende Eselsbrücke, die man sich einfach merken muss und auch deine Erfahrung spricht ebenfalls dafür, dass das Anlegen der Subs deutliche Vorteile hat, will man ein Programm umfangreicher gestalten. Vielen Dank auch nochmals für deine Ausführung, über die ich mich auch sehr gefreut habe!

Ich werde am Wochenende mal den letzten Code in Subs umschichten und mich mal mit dem Simulator befassen und dann mal über die gewonnenen Eindrücke berichten. Mal sehen, was dabei rauskommt.

Schöne Grüße und ein schönes Wochenende!

Robin
 
Hi Robin,

...
Der Schritt zu Subs ist fest eingeplant:yes4:
...
...und auch deine Erfahrung spricht ebenfalls dafür, dass das Anlegen der Subs deutliche Vorteile hat, will man ein Programm umfangreicher gestalten.
...
Ich werde am Wochenende mal den letzten Code in Subs umschichten und ...
Subs/Unterroutinen/Prozeduren/... haben neben der Struktur die man erhält noch einen weiteren entscheidenden Vorteil. Man baut sich einen Satz an fertigen funktionsfähigen Programmblöcken die man wie Legosteine bei neuen Programmen wiederverwenden kann. Man muß das Rad dann nicht immer wieder neu erfinden. Versuch also bei den Subs eine Struktur zu finden die du gut in zukünftigen Projekten wiederverwerten kannst. Wichtig dabei sind zB sprechende Variablennamen.

Gruß
Dino
 
Aber bis ich mal darauf kam, vergingen Tage des Grübelns. Leider findet man diese Tips auch in keinem Buch oder sonst irgendwo


Hallo Robin!

Nun ja, beim Ausprobieren meines Beispielprogrammes für dich, hätte der Groschen doch eigentlich schon fallen müssen. :wink:

Schau mal hier, bei "Case 6":
Code:
   Case 4
      Locate 3 , 1
      Lcd " X-Zaehler="
      For Flag_x = 255 To 0 Step -1
         Str_temp = Str(flag_x)
         Str_temp = Format(str_temp , "000")
         Locate 3 , 13 : Lcd Str_temp
         Waitms 100
      Next Flag_x
   Case 5
      Locate 4 , 1
      Lcd "Z-Zaehler= "
      For Flag_z = 0 To 65535
         Str_temp = Str(flag_z)
         Str_temp = Format(str_temp , "00000")
         Locate 4 , 12 : Lcd Str_temp
         Waitms 10
      Next Flag_z
[B][COLOR="#FF0000"]   Case 6
      Locate 2 , 1 : Lcd "                "
      Locate 3 , 1 : Lcd "                "
      Locate 4 , 1 : Lcd "                "[/COLOR][/B]
End Select


Da passierte doch genau das, was Dino hinterher geschrieben hatte.......
und du hättest nicht tagelang grübeln müssen. :cool:


Grüße,
Cassio
 
Hallo zusammen,

ja, Dino, die Vorteile der Subs sind schon beachtlich, aber auch erst, wenn man sie richtig zu nutzen versteht. Und genau da hapert es noch bei mir. Auf sprechende Variablen hatte ich jetzt noch verzichtet, da der Code für mich noch recht übersichtlich ist. Ich habe allerdings jetzt schon mal das Voransetzen der Pins etc. aus Quelltexten, die Cassio hier eingestellt hatte, übernommen, da dies ein dauerndes Durchsuchen des Textes erspart; ebenfalls eine sehr große Hilfe beim schreiben eines Programms.

Die Abstände zwischen den " " sind mir schon aufgefallen, doch ich maß ihnen nicht die Bedeutung zu, die sie verdient gehabt hätten:( Natürlich auch bei deiner Hilfe, Cassio, hatte ich dies übersehen. Als mir dann die Auswirkung der " bewusst wurde, ....:banghead:

Hier mal der Quelltext:
Code:
[COLOR="#008000"]'Pind.2 =       LED Sekundentakt (1s an, 1s aus)
'PinB.4 =       LED Automatische Anzeige der Werte
'PinB.5 =       LED Manuelle Anzeige der Werte

'PinD.4 =       Taster Uhrzeit einstellen
'PinD.5 =       Taster Aufwärtszählen der Uhrzeit
'PinD.6 =       Taster Abwärtszählen der Uhrzeit
'PinD.7 =       Taster fürs manuelle Durchschalten des LCD
'PinB.0 =       Taster fürs Umschalten zwischen manueller und automatischer Anzeige

'Flag_auto =    Variable legt die Anzeigedauer in der sub Auto_anzeige in sec fest
'X         =    Variable legt die Anzahl und die Reihenfolge der Anzeigen in der sub Auto_anzeige fest[/COLOR]


$regfile "m8def.dat"
$crystal = 1000000
$framesize = 64
$hwstack = 64
$swstack = 64

Config Lcdpin = Pin , Rs = Portc.5 , E = Portc.4 , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0
Config Lcd = 16 * 4

Cursor Off
Cls

Config Pinb.4 = Output
Portb.4 = 0

Config Pinb.5 = Output
Portb.5 = 0

Config Pind.2 = Output

Config Pind.4 = Input
Portd.4 = 1
Taster_uhr_set Alias Pind.4

Config Pind.5 = Input
Portd.5 = 1
Taster_uhr_up Alias Pind.5

Config Pind.6 = Input
Portd.6 = 1
Taster_uhr_down Alias Pind.6

Config Pind.7 = Input
Portd.7 = 1
Taster_man_anzeige Alias Pind.7

Config Pinb.0 = Input
Portb.0 = 1
Taster_auto_man Alias Pinb.0


Dim X As Byte
X = 0
Dim Y As Byte
Y = 0


Config Debounce = 50


Config Clock = Soft , Gosub = Sectic
Time$ = "00:00:00"

Enable Interrupts


Dim Flag_x As Byte
Dim Flag_y As Byte
Dim Flag_z As Word

Dim Flag_auto As Byte
Flag_auto = 0


Dim Sec_flag As Bit
Dim Str_temp As String * 5

Cls


Do


If Sec_flag = 0 Then
   Locate 1 , 5
   Lcd Time$
   Sec_flag = 1
  Else
End If


Debounce Pind.7 , 0 , Man_anzeige , Sub
Debounce Pinb.0 , 0 , Auto_anzeige , Sub


Loop


'*******************************************************************************


'###############################################################################
'Automatik
'###############################################################################

Auto_anzeige:


      Portb.5 = 0
      Portb.4 = 1

Do

    If Flag_auto > 3 Then
     Flag_auto = 0
      Incr X
    End If

    Locate 4 , 1
     Lcd Flag_auto


     If Sec_flag = 0 Then
      Locate 1 , 5
       Lcd Time$
       Sec_flag = 1
      Else
     End If



    Locate 3 , 1

    Select Case X

         Case 0 : Lcd "    Weiter so    "

         Case 1 : Lcd "    Gut so       "

         Case 2 : Lcd "    aha          "

         Case 3

                Str_temp = Str(flag_x)
                Str_temp = Format(str_temp , "    000")
                Locate 3 , 1
                Lcd Str_temp

         Case 4

                Str_temp = Str(flag_y)
                Str_temp = Format(str_temp , "    000")
                Locate 3 , 1
                Lcd Str_temp

         Case 5

                Str_temp = Str(flag_z)
                Str_temp = Format(str_temp , "    00000")
                Locate 3 , 1
                Lcd Str_temp


         End Select


       Locate 2 , 1
        Lcd X ; "  "


      If X > 5 Then
       X = 0
      End If

'Loop
Loop Until Pind.7 = 0

Return


'##################################################
'Manuell
'##################################################

Man_anzeige:

Locate 4 , 1
     Lcd "  "
Locate 2 , 1
     Lcd Y


      Portb.5 = 1
      Portb.4 = 0


Locate 3 , 1

Select Case Y
   Case 0 : Lcd "    Gut so       "
   Case 1 : Lcd "    Weiter so    "
   Case 2 : Lcd "    aha          "


   Case 3
         Do
         Str_temp = Str(flag_y)
         Str_temp = Format(str_temp , "    000")
         Locate 3 , 1
         Lcd Str_temp
         Waitms 200
         Loop Until Pind.7 = 0


   Case 4
         Do
         Str_temp = Str(flag_x)
         Str_temp = Format(str_temp , "    000")
         Locate 3 , 1
         Lcd Str_temp
         Waitms 200
         Loop Until Pind.7 = 0


   Case 5
         Do
         Str_temp = Str(flag_z)
         Str_temp = Format(str_temp , "    00000")
         Locate 3 , 1
         Lcd Str_temp
         Waitms 200
         Loop Until Pind.7 = 0


End Select


If Y < 5 Then
   Incr Y
Else
   Y = 0
End If


Return

'***************************************************************************


Sectic:
Toggle Portd.0
Incr Flag_x

Decr Flag_y
Decr Flag_z


Sec_flag = 0

Incr Flag_auto

Return


Das Programm läuft jetzt fast so, wie ich es mir vorstellte. Unerklärlich ist für mich nur noch, dass in der Sub Man_anzeige ab Case 3 pro weiterem Tastendruck ein Zwischenschritt eingelegt wird. Dann wird erst der letzte Wert von Flag_y dauerhaft angezeigt, bevor durch erneutem Tastendruck in Case 4 die hochzählende Variable angezeigt wird.

Den internen Simulator hatte ich hierbei auch schon mal bemüht, doch da bleibt der linke, türkisfarbene Pfeil stets an den beiden Debounce-Anweisungen hängen. Da werde ich die "Gebrauchsanweisung" nochmals bemühen müssen. Danach werde ich mich wieder melden, wenn ich darf. Vielen Dank für eure Hilfe und schöne Grüße

Robin
 
Hallo,
nachdem nun noch die kleineren Fehler (die ich nachträglich noch erkennen konnte) beseitigt sind, habe ich den Quellcode nun um eine Schaltuhr erweitert. Mit der Schaltuhr hatte ich schon vor etwa einem halben Jahr begonnen, hatte einerseits aus Zeitmangel und andererseits aus Unkenntnis heraus, wie man die Darstellungen der Ein - Ausschaltzeiten richtig vornimmt, erst einmal zurückgestellt. Dank Cassios Hilfe, wie man ein Byte richtig formatiert, stand nun der Vollendung nichts mehr im Wege!:dance3::dance3:

Der hauseigene Simulator von Bascom macht für mich noch nicht wirklich Sinn. Nach Laden der OBJ-Datei dümpelt das Simulationsprogramm irgendwie vor sich hin und auf der einblendbaren LCD-Anzeige erscheint mal das, was ich auf meinem LCD längst sehe. Aber: Kommt Zeit, kommt Rat, kommt Oberrat, haben wir früher immer gesagt! Da werde ich mich noch mal intensiver mit auseinander setzen.

Parallel dazu werde ich nun noch eine Dimmung integrieren. Mal schauen, was dabei heraus kommt! Ach ja: Nach Entfernen der Wait-Bremsen teste ich nun, wie "ganggenau" sich die Uhr in den beiden Anzeigevarianten verhält.

Im Datenblatt hatte ich gestern gesehen, dass man den Mega8 mit einem Uhrenquarz an den Pins 6 + 7 betreiben, wohl dafür die 22pF Kondensatoren entfernen und CKOPT-Fuse setzen muss. Dabei ist CKSEL auf 1001 zu setzen. Nun ändere ich die Fusebits eigentlich über AVR-Studio 4.19. Da sind diese nicht mehr zu erkennen. Lohnt sich dafür, wieder eine Uraltversion zu installieren? Welche Erfahrungen habt Ihr machen können?



Code:
'PinB.3 =       LED Beleuchtung ein/aus
'PinB.4 =       LED Automatische Anzeige der Werte
'PinB.5 =       LED Manuelle Anzeige der Werte

'PinD.2 =       LED Sekundentakt (1s an, 1s aus)

'PinD.4 =       Taster Uhrzeit einstellen
'PinD.5 =       Taster Aufwärtszählen der Stunden / Minuten / Sekunden
'PinD.6 =       Taster Abwärtszählen der Stunden / Minuten / Sekunden

'PinD.7 =       Taster fürs manuelle Durchschalten der LCD - Anzeige
'PinB.0 =       Taster fürs Umschalten von manueller auf automatisch wechselnde Anzeige

'Sec_flag       Sekundenvariable, in der das LCD die Zeitinformation erhält
'Flag_auto =    Variable legt die Anzeigedauer in der sub Auto_anzeige in sec fest
'X         =    Variable legt die Anzahl und die Reihenfolge der Anzeigen in der sub Auto_anzeige fest



$regfile "m8def.dat"
$crystal = 1000000
$framesize = 64
$hwstack = 64
$swstack = 64

Config Lcdpin = Pin , Rs = Portc.5 , E = Portc.4 , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0
Config Lcd = 16 * 4

Cursor Off
Cls

Config Pinb.3 = Output
Portb.3 = 0

Config Pinb.4 = Output
Portb.4 = 0

Config Pinb.5 = Output
Portb.5 = 0

Config Pind.3 = Output

Config Pind.4 = Input
Portd.4 = 1
Taster_uhr_stellen Alias Pind.4

Config Pind.5 = Input
Portd.5 = 1
Taster_uhr_hoch Alias Pind.5

Config Pind.6 = Input
Portd.6 = 1
Taster_uhr_runter Alias Pind.6

Config Pind.7 = Input
Portd.7 = 1
Taster_man_anzeige Alias Pind.7

Config Pinb.0 = Input
Portb.0 = 1
Taster_auto_anzeige Alias Pinb.0


Dim X As Byte
X = 0
Dim Y As Byte
Y = 0


Config Debounce = 50


Enable Interrupts


Dim Flag_x As Byte
Dim Flag_y As Byte
Dim Flag_z As Word

Dim Flag_auto As Byte
Flag_auto = 0

Dim Sec_flag As Bit
Dim Str_temp As String * 5


Config Clock = Soft , Gosub = Sectic
Time$ = "00:00:00"

Dim Einschalt_std As Byte
Dim Einschalt_min As Byte
Dim Ausschalt_std As Byte
Dim Ausschalt_min As Byte

Einschalt_std = 0
Einschalt_min = 1
Ausschalt_std = 0
Ausschalt_min = 2

Dim Str_ein_std As String * 2
Dim Str_ein_min As String * 2
Dim Str_aus_std As String * 2
Dim Str_aus_min As String * 2


Cls

'##############################################################################
'##############################################################################


Do


If Sec_flag = 0 Then
   Locate 1 , 5
   Lcd Time$
   Sec_flag = 1
  Else
End If

Debounce Taster_uhr_stellen , 0 , Uhr_stellen , Sub
Debounce Taster_man_anzeige , 0 , Man_anzeige , Sub
Debounce Taster_auto_anzeige , 0 , Auto_anzeige , Sub


'Umwandlung der Byte-Variablen in eine Stringvariable mit zweistelliger Formatierung
               Str_ein_std = Str(einschalt_std)
               Str_ein_std = Format(str_ein_std , "00")

               Str_ein_min = Str(einschalt_min)
               Str_ein_min = Format(str_ein_min , "00")

               Str_aus_std = Str(ausschalt_std)
               Str_aus_std = Format(str_aus_std , "00")

               Str_aus_min = Str(ausschalt_min)
               Str_aus_min = Format(str_aus_min , "00")


'Vergleich des Einschaltzeitpunkts der Beleuchtung
If _hour >= Einschalt_std And _min >= Einschalt_min Then
   Gosub Einschalten
  Else
End If

'Vergleich des Ausschaltzeitpunkts der Beleuchtung
If _hour >= Ausschalt_std And _min >= Ausschalt_min Then
  Gosub Ausschalten
  Else
End If


Loop


'###############################################################################
'###############################################################################
'Automatik
'###############################################################################

Auto_anzeige:

'LED Kontrolle Beleuchtung ein / aus
      Portb.5 = 0
      Portb.4 = 1

Do

    If Flag_auto > 3 Then
     Incr X
      Flag_auto = 0
    End If

    Locate 2 , 14
     Lcd Flag_auto


     If Sec_flag = 0 Then
      Locate 1 , 5
       Lcd Time$
       Sec_flag = 1
      Else
     End If





    Select Case X

         Case 0
'Anzeige der Uhrzeit, wenn Var. Sec_flag=0 wird
If Sec_flag = 0 Then
  Locate 1 , 5
   Lcd Time$
    Sec_flag = 1
   Else
End If

'Anzeige der Ein - Ausschaltzeiten der Beleuchtung
    Locate 3 , 1
      Lcd "    Ein: " ; Str_ein_std ; ":" ; Str_ein_min ; " "
    Locate 4 , 1
      Lcd "    Aus: " ; Str_aus_std ; ":" ; Str_aus_min ; " "

    Locate 3 , 1
      Lcd "    Ein: " ; Str_ein_std ; ":" ; Str_ein_min ; " "
    Locate 4 , 1
      Lcd "    Aus: " ; Str_aus_std ; ":" ; Str_aus_min ; " "


         Case 1
               If Sec_flag = 0 Then
                 Locate 1 , 5
                  Lcd Time$
                   Sec_flag = 1
                 Else
               End If

                   Locate 4 , 1
                  Lcd "                "
                Locate 3 , 1
               Lcd "    Gut so       "

         Case 2
               If Sec_flag = 0 Then
                 Locate 1 , 5
                  Lcd Time$
                   Sec_flag = 1
                    Else
               End If

                Locate 3 , 1
               Lcd "    aha          "

         Case 3
               If Sec_flag = 0 Then
                 Locate 1 , 5
                  Lcd Time$
                   Sec_flag = 1
                  Else
                End If

                Str_temp = Str(flag_x)
                Str_temp = Format(str_temp , "000")
                Locate 3 , 1
                Lcd "     " ; Str_temp

         Case 4
               If Sec_flag = 0 Then
                 Locate 1 , 5
                  Lcd Time$
                   Sec_flag = 1
                  Else
                 End If

                Str_temp = Str(flag_y)
                Str_temp = Format(str_temp , "000")
                Locate 3 , 1
                Lcd "     " ; Str_temp

         Case 5
               If Sec_flag = 0 Then
                 Locate 1 , 5
                  Lcd Time$
                   Sec_flag = 1
                  Else
                End If

                Str_temp = Str(flag_z)
                Str_temp = Format(str_temp , "00000")
                Locate 3 , 1
                Lcd "     " ; Str_temp


         End Select


       Locate 2 , 1
        Lcd X ; "  "


      If X > 5 Then
       X = 0

      End If



 If _hour >= Einschalt_std And _min >= Einschalt_min Then
   Gosub Einschalten
  Else
End If

If _hour >= Ausschalt_std And _min >= Ausschalt_min Then
  Gosub Ausschalten
  Else
End If





Loop Until Pind.7 = 0

Return


'##################################################
'Manuell
'##################################################

Man_anzeige:

Cls

Locate 2 , 1
     Lcd Y ; "              "

'LED Kontrolle Beleuchtung ein / aus
      Portb.5 = 1
      Portb.4 = 0




Select Case Y
   Case 0
         If Sec_flag = 0 Then
          Locate 1 , 5
           Lcd Time$
            Sec_flag = 1
           Else
         End If


'Anzeige der Uhrzeit, wenn Var. Sec_flag=0 wird
     Locate 3 , 1
       Lcd "    Ein: " ; Str_ein_std ; ":" ; Str_ein_min ; " "

     Locate 4 , 1
       Lcd "    Aus: " ; Str_aus_std ; ":" ; Str_aus_min ; " "

     Locate 3 , 1
       Lcd "    Ein: " ; Str_ein_std ; ":" ; Str_ein_min ; " "

     Locate 4 , 1
       Lcd "    Aus: " ; Str_aus_std ; ":" ; Str_aus_min ; " "


   Case 1
         If Sec_flag = 0 Then
          Locate 1 , 5
           Lcd Time$
            Sec_flag = 1
           Else
         End If

         Locate 4 , 1
          Lcd "               "
           Locate 3 , 1

         Lcd "    Weiter so   "


   Case 2
         If Sec_flag = 0 Then
          Locate 1 , 5
           Lcd Time$
            Sec_flag = 1
           Else
         End If

         Locate 4 , 1
          Lcd "              "
           Locate 3 , 1

         Lcd "    aha        "


   Case 3
         Do

         If Sec_flag = 0 Then
          Locate 1 , 5
           Lcd Time$
            Sec_flag = 1
           Else
         End If

         Str_temp = Str(flag_y)
         Str_temp = Format(str_temp , "000")
         Locate 3 , 1
         Lcd "    " ; Str_temp ; "       "

         Loop Until Pind.7 = 0


   Case 4
         Do

         If Sec_flag = 0 Then
          Locate 1 , 5
           Lcd Time$
            Sec_flag = 1
           Else
         End If

         Str_temp = Str(flag_x)
         Str_temp = Format(str_temp , "000")
         Locate 3 , 1
         Lcd "    " ; Str_temp ; "       "
         Loop Until Pind.7 = 0


   Case 5
         Do

          If Sec_flag = 0 Then
          Locate 1 , 5
           Lcd Time$
            Sec_flag = 1
           Else
         End If

         Str_temp = Str(flag_z)
         Str_temp = Format(str_temp , "00000")
         Locate 3 , 1
         Lcd "    " ; Str_temp ; "    "
         Loop Until Pind.7 = 0


End Select


If Y < 5 Then
   Incr Y
Else
   Y = 0
End If


Return

'***************************************************************************


Uhr_stellen:


'**************************************************************
'Uhrzeit einstellen
'**************************************************************


Cls
Locate 1 , 1
Lcd "Uhrzeit stellen:"

Wait 1
Cls


'**************************************************************
'Stunden
'**************************************************************

Do

Locate 2 , 2
Lcd "Stunden: " ; _hour ; "  "

If Taster_uhr_hoch = 0 Then
If _hour < 23 Then
Incr _hour

Else

_hour = 0

End If

Waitms 300

End If


If Taster_uhr_runter = 0 Then
If _hour < 23 Then
Decr _hour

If _hour < 1 Or _hour > 23 Then
_hour = 0
End If

End If
Waitms 300
End If


Loop Until Taster_uhr_stellen = 0
Waitms 80

Bitwait Taster_uhr_stellen , Set

'********************************************************
'Minuten
'********************************************************

Do
Locate 3 , 2
Lcd "Minuten: " ; _min ; "  "

If Taster_uhr_hoch = 0 Then
If _min < 59 Then
Incr _min

Else

_min = 0

End If
Waitms 300

End If


If Taster_uhr_runter = 0 Then
If _min < 59 Then
Decr _min

If _min < 1 Or _min > 59 Then
_min = 0
End If

End If
Waitms 300
End If

Loop Until Taster_uhr_stellen = 0
Waitms 80

Bitwait Taster_uhr_stellen , Set


'*********************************************************
'Sekunden
'*********************************************************

Do
Locate 4 , 1
Lcd "Sekunden: " ; _sec ; "    "

If Taster_uhr_hoch = 0 Then
If _sec < 59 Then
Incr _sec

Else
_sec = 0

End If
Waitms 300

End If

If Taster_uhr_runter = 0 Then
If _sec < 59 Then
Decr _sec

If _sec < 1 Or _sec > 59 Then
_sec = 0
End If

End If
Waitms 300
End If

Loop Until Taster_uhr_stellen = 0
Waitms 80

Bitwait Taster_uhr_stellen , Set

Cls

'####################################################################
'Schaltzeiten
'####################################################################

'********************************************************
'Einschaltzeit
'********************************************************


Locate 1 , 1
Lcd "Einschaltzeit: "

Wait 1

Do

Locate 3 , 2
Lcd "Stunden: " ; Einschalt_std ; "    "


If Taster_uhr_hoch = 0 Then


If Einschalt_std < 23 Then
Incr Einschalt_std

Else

Einschalt_std = 0

End If
Waitms 300
End If


If Taster_uhr_runter = 0 Then
If Einschalt_std < 23 Then
Decr Einschalt_std

If Einschalt_std < 1 And Einschalt_std > 23 Then
Einschalt_std = 0
End If

End If
Waitms 300
End If

Loop Until Taster_uhr_stellen = 0
Waitms 80

Bitwait Taster_uhr_stellen , Set

'********************************************************
'Minuten
'********************************************************

Do

Locate 4 , 2
Lcd "Minuten: " ; Einschalt_min ; "    "

If Taster_uhr_hoch = 0 Then

If Einschalt_min < 59 Then
Incr Einschalt_min

Else

Einschalt_min = 0

End If
Waitms 300
End If

If Taster_uhr_runter = 0 Then
If Einschalt_min < 59 Then
Decr Einschalt_min

If Einschalt_min < 1 Or Einschalt_min > 59 Then
Einschalt_min = 0
End If

End If
Waitms 300
End If

Loop Until Taster_uhr_stellen = 0
Waitms 80

Bitwait Taster_uhr_stellen , Set

Cls


'################################################################
'Ausschaltzeit
'################################################################

'****************************************************
'Stunden
'****************************************************

Locate 1 , 1
Lcd "Ausschaltzeit: "

Wait 1

Do

Locate 3 , 2
Lcd "Stunden: " ; Ausschalt_std ; "    "

If Taster_uhr_hoch = 0 Then


If Ausschalt_std < 23 Then
Incr Ausschalt_std

Else

Ausschalt_std = 0

End If
Waitms 300
End If


If Taster_uhr_runter = 0 Then
If Ausschalt_std < 23 Then
Decr Ausschalt_std

If Ausschalt_std < 1 Or Ausschalt_std > 23 Then
Ausschalt_std = 0
End If

End If
Waitms 300
End If

Loop Until Taster_uhr_stellen = 0
Waitms 80
Bitwait Taster_uhr_stellen , Set


'**********************************************************
'Minuten
'**********************************************************

Do

Locate 4 , 2
Lcd "Minuten: " ; Ausschalt_min ; "    "

If Taster_uhr_hoch = 0 Then
If Ausschalt_min < 59 Then
Incr Ausschalt_min

Else

Ausschalt_min = 0

End If
Waitms 300
End If

If Taster_uhr_runter = 0 Then
If Ausschalt_min < 59 Then
Decr Ausschalt_min

If Ausschalt_min < 1 And Ausschalt_min > 59 Then
Ausschalt_min = 0
End If

End If
Waitms 300
End If

Loop Until Taster_uhr_stellen = 0
Waitms 80

Bitwait Taster_uhr_stellen , Set

Cls

Return

'##############################################################


Sectic:

Toggle Portd.3

Incr Flag_x

Decr Flag_y
Decr Flag_z


Sec_flag = 0

Incr Flag_auto

Return

'###############################################################

Einschalten:

Portb.3 = 1

Return

'###############################################################

Ausschalten:

Portb.3 = 0

Return



Schöne Grüße

robin
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)