PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Zeitfunktionen in Bascom



mafoba
08.11.2008, 14:21
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!

Michael
08.11.2008, 15:01
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

for_ro
08.11.2008, 15:18
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

mafoba
08.11.2008, 15:32
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!

mafoba
08.11.2008, 15:37
Oh, Danke Rolf.
Das hilft mir weiter. Gut, dann nehme ich einen externen Quarz. =D>

Michael
08.11.2008, 16:01
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

for_ro
08.11.2008, 16:07
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

Michael
08.11.2008, 16:19
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

for_ro
08.11.2008, 19:43
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

Michael
08.11.2008, 20:45
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, 21: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.

StevieL
09.11.2008, 11:06
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.

wodka
14.02.2009, 07:39
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