Archiv verlassen und diese Seite im Standarddesign anzeigen : Zeitfunktionen in Bascom
Hallo Leute.
Vorweg: Ich bin noch ein Anfänger O:)
Ich versuche mich gerade an einer automatischen Bewässerungsanlage, bei der einmal am Tag die Pflanzen gegossen werden sollen. Wie schaffe ich es, dass ca. alle 24 Stunden ein H-Pegel für z.B. 10 sec an einem Ausgang anliegt? Geht das nur mit einem DCF-Modul oder auch ohne? Ob mit oder ohne, wäre nett wenn jemand eine BASCOM-Lösung dazu parat hätte. Ich benutze einen Mega8.
Danke!
Hallo mafoba,
das geht auch ohne DCF Modul.
Dazu solltest du einen Timerinterrupt benutzen.
Nach einer vorgegebenen Anzahl Prozessortakte springt das Programm dabei in eine extra Routine. Dort wird eine Variable aufsummiert. Erreicht die Variable einen bestimmten Wert, ist z.B. eine Sekunde vergangen.
Eine weitere variable summiert dann die Sekunden zu Minuten, die Minuten zu Stunden, etc.
In deinem Hauptprogramm prüfst du dann die Variablen, und schaltest je nach Bedarf deinen Ausgang.
Gruß, Michael
Hallo,
wichtig zu wissen wäre noch, wie du den Mega8 antreibst, über einen externen Quarz oder die interne Zeitbasis.
Der Quarz ist normalerweise so genau, dass du die Abweichung über einige Tage kaum merkst. Beim internen Oszillator sieht das schon anders aus. Der kann an einem Tag schon eine halbe Stunde abweichen.
Das DCF Modul würde die Abweichung auch über einen längeren Zeitraum verhindern.
Ansonsten lässt du einen Timer laufen und zählst du die Überläufe. Nach der geeigneten Anzahl gibst du den Ausgang für 10 Sekunden frei.
Z.B. so:
$regfile = "m8def.dat"
$crystal = 1000000
Dim Ovfl_count As Long
Dim Giessen As Byte
Config Timer0 = Timer , Prescale = 1024
On Timer0 Timer0_isr
Timer0_startwert Alias 8 '1.000.000/1024/(256-8=244) '~ 0,25 x pro Sekunde, entspricht waitms 250
Timer0 = Timer0_startwert
Enable Timer0
Enable Interrupts
Do
If Giessen = 1 Then
Portc.1 = 1 'bzw =0, je nachdem, wie der Ausgang funktionieren soll, deinen Port angeben
End If
Loop
End
Timer0_isr:
Timer0 = Timer0_startwert
Incr ovfl_count
If Ovfl_count = 40 Then '4 mal pro Sekunde Mal 10 Sekunden = 40
Giessen = 0
End If
If Ovfl_count = 345600 Then '4 mal pro Sekunde mal 86400 Sekunden in 24 Stunden = 346600
Ovfl_count=0
Giessen = 1
End If
Return
Dies sollte 10 Sekunden lang an sein und dann die restliche Zeit des Tages aus.
Gruß
Rolf
Hallo Michael,
schonmal Danke für die Antwort, das würde ich gerne mal testen. Die Sekunden zu Minuten aufsummieren etc. würde ich auch hinbekommen. Aber wie genau programmiere ich die Prozessortaktabfrage? Ich würde 1MHz als Takt benutzen. Also müsste eine Variable alle 1mio Takte hochzählen, oder? Kannst Du mir vielleicht eben den Code dafür posten?
Danke!
Oh, Danke Rolf.
Das hilft mir weiter. Gut, dann nehme ich einen externen Quarz. =D>
Hallo mafoba,
for_ro hat es bereits in ein Programm gepackt.
Der Timer wird mit einem bestimmten Wert vorgeladen und läuft dann über.
Die Anzahl der Takte bis zum Überlauf bestimmt die Zeit, die ja dann zu Sekunden, etc. aufsummiert wird.
Ich hätte es vielleicht etwas anders gelöst, aber da kommst du eines Tages auch noch selber drauf ;)
1MHz als Takt klingt nach internem Oszillator. Der ist nicht wirklich genau, wie for_ro bereits schrieb.
Gruß, Michael
Ich hätte es vielleicht etwas anders gelöst, aber da kommst du eines Tages auch noch selber drauf ;)
Warum hättest du das anders gelöst? Ist da etwas nachteilig dran?
Gruß
Rolf
Hallo for_ro,
ich hätte einen Prescaler gewählt, der die Taktfrequenz in ganze Zahlen teilt.
Außerdem hätte ich im Interrupt nur die Sekunden, Minuten, Stunden aufsummiert, mit Abfrage dann im Hauptprogramm. So kannst du später weitere Abfragen und z.B. das Stellen der Uhr im Hauptprogramm unterbringen.
Dein Programm funktioniert aber für den gewünschten Zweck erstmal, ich wollte mafoba halt kein fertiges Programm präsentieren, das er dann vielleicht nicht versteht.
Gruß, Michael
Hallo Michael,
wieso du die Taktfrequenz in ganze Zahlen teilen willst, verstehe ich nicht. Das ist doch vollkommen egal. Du brauchst doch eh fast nie eine absolut genaue Zeit. Ich bevorzuge immer den höchsten Prescaler der möglich ist. Der Teil wird in Hardware gemacht und da soll er möglichst weit runter kommen. Besonders wenn ich dann bei der ISR nicht noch eine Variable hochzählen muss, um auf die gewünschte Zeit zu kommen.
Ob Mafoba dann später mal ein Display dranhängen will um dann die Zeit einstellen zu können, damit er dann die Zeit fürs Giessen einstellen kann ist schon möglich. Aber bis dahin würde ich keine Sekunden, Minuten und Stunden addieren.
Und ja, die Abfrage kann man natürlich auch noch im Hauptprogramm machen, birgt aber die Gefahr, dass du das Ereignis verpasst. Falls möglich, gehe immer so vor, dass in Interrupt Routine der Status so abgelegt wird, dass Zeit genug ist für die Auswertung. Also mit einem Flag, dass die Bedingung in der Routine erfüllt war. Da kann niemand dazwischen kommen.
Ich denke, das sind unterschiedliche Philosophien und jeder macht es dann so wie es am besten passt.
Ich fand deinen Kommentar nur ein wenig von oben herab. Aber mit sowas muss man in vielen Foren leben.
Gruß
Rolf
Hallo for_ro,
Du brauchst doch eh fast nie eine absolut genaue Zeit
wenn du ganze Zahlen hast, hast du eben keinen Fehler. Sonst kannst du ja gleich mit Wait arbeiten.
Da mafoba offensichtlich ein Anfänger ist, hätte ich ihn den Begriff Timer nähergebracht und dann die Vorteiler erklärt. Und daß er die Interrupts mit einer Variable aufsummieren kann, bis genau eine Sekunde vorbei ist. (im Rahmen der Quarzgenauigkeit)
Das geht aber nur mit ganzen Zahlen.
Ich fand deinen Kommentar nur ein wenig von oben herab.
ich hab ihn mir nochmal durchgelesen und fand es eher nicht. Sogar ein Smilie hab ich verwendet.
Gruß, Michael
stefan_Z
08.11.2008, 22:38
Ein DCF77 Modul ist allerdings inzwischen billig und einfach in der Ansteuerung.
Pollin hat eins für 5 EUR - da baut man noch nen Schmittrigger zwischen, dann gehts super.
Hallo,
schon mal an einen Uhrenquarz und die in Bascom vorhandene Echtzeituhr gedacht? Da erstreckt sich der Code auf "Config Clock = Soft" und eine Abfrage der Uhrzeit.
Hallo,
ich bin gerade bei und versuche die Uhr mit einem DCF77 Signal zu stellen. Nun benutze ich folgendes Beispiel über Bascom:
$eeprom
$eepromhex
$regfile = "m32def.dat" ' Prozessortyp ATmega32
$crystal = 1000000 ' Taktrate
$hwstack = 32
$swstack = 10
$framesize = 40
$baud = 4800
Config Lcd = 20 * 2
Config Lcdpin = Pin , Db4 = Porta.0 , Db5 = Porta.1 , Db6 = Porta.2 , Db7 = Porta.3 , E = Porta.5 , Rs = Porta.4
Cls
Cursor Off
Config Dcf77 = Pind.6 , Inv = 0 , Upd = 0 , Timer = 1 , Timer1sec = 0 , Debug = 1 , Check = 2 , Switchpower = 0 , Powerlevel = 1
Enable Interrupts
Config Date = Dmy , Separator = .
Dim I As Integer
Dim Sec_old As Byte , Dcfsec_old As Byte
Sec_old = 99 : Dcfsec_old = 99
Do
For I = 1 To 78
Waitms 10
If Sec_old <> _sec Then
Exit For
End If
If Dcfsec_old <> Dcf_sec Then
Exit For
End If
Next
Waitms 220
Sec_old = _sec
Dcfsec_old = Dcf_sec
Locate 1 , 5
Lcd Time$ ; " "
Locate 2 , 5
Lcd Date$ ; " "
Locate 2 , 15
Lcd Bdcf_impuls ; " "
Loop
End
Am Display zählen die Sekunden fröhlich hoch und die Variable "Bdcf_impuls" zeigt zwischen 35-40 einen Wert an! Scheint die Empfangsstärke zu sein??
Leider ist die Uhr nach 30min immer noch nicht gestellt. Ist das mit dem Code so überhaupt möglich? Ist ein Bascom Beispiel.
Den DCF77 Empfänger habe ich aus einem Wecker und mit einem BC547b verstärkt. Laut "Bdcf_impuls" passiert ja auch was. Habe leider kein Ossi zur Signal überprüfung hier.
Hoffe ihr habt noch eine Idee.
Gruß
Stefan
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.