PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Taster zeitgesteuert schalten lassen



Blue72
19.07.2008, 18:49
Hallo,

ich möchte gerne abfragen ob ein Taster gedrückt wurde, was ja nicht
wirklich schwer ist, allerdings möchte ich erst eine Aktion durchführen
lassen wenn der Taster z.B. 3 sec. lang gedrückt wird, um "zufälliges" drücken zu unterbinden. Einen Timer habe ich noch frei, auch schon viel gelsen, nur scheinbar nicht das richtige :D

Hat jemand einen Rat für mich ?

Danke.

Jens

Sauerbruch
19.07.2008, 19:26
Wie wär´s etwa so:

Der Taster geht auf einen Interrupt-Eingang (PinX.Y), den Du auf "Change" konfiguriertst (Auslösen bei jedem H-L oder L-H - Wechsel).

In der ISR wird geprüft, ob der Taster gerade gedrückt oder losgelassen wurde.

Wurde er gedrückt startet der Timer, wurde er losgelassen wird der Timer angehalten und auf einen bestimmten Ausgangswert gesetzt (...):

ISR:
If PinX.Y = 1 then
start timerX
Else
stop timerX
timerX = ...
End if
Return

Den Timer-Vorwert ... musst Du nur noch so berechnen, dass der Timer nach 3 Sekunden überläuft. In der Timer-ISR kannst Du dann die Aktion auslösen lassen.

uwegw
19.07.2008, 19:39
Oder der Timer-Interrupt fragt alle paar Millisekunden den Eingang ab. Falls Taste gedrückt, zählt er ne Variable hoch, ansonsten wird diese zurückgesetzt. Falls ein bestimmter Stand erreicht wurde, wird die Aktion ausgelöst.

So kann die Timer-ISR noch weitere Dinge erledigen, zb weitere tasten abfragen.

Blue72
19.07.2008, 21:15
Vielen Dank für den Tip, aber ich weiss grad nicht wie ich das anwenden kann. Ich habe mir mit print tcnt0 die Werte anzeigen lassen, aber die schwanken ja doch ziemlich stark, da weiss ich nicht wo ich ansetzen soll :(

Jens

Sauerbruch
20.07.2008, 10:26
Poste doch mal den Code - dann findet bestimmt jemand hier einen Ansatz!

izaseba
20.07.2008, 10:47
Hallo Jens,

Du brauchst Dich garnicht um den Wert von tcnt0 kümmern.

Was Du machen mußt, den Timer so laufen zu lassen, daß er meinetwegen alle 50 ms überläuft und den entsprechenden Interrupt einschalten.
Timer starten,stopen ist Quatsch.

Einfach nur laufen lassen.

Im Interrupt machst Du folgendes

pseudocode


if (TasteGedrueckt)
Zaehler = Zaehler +1;
else
Zahler = 0;
if (Zaehler == 60)
/*Tue was, 3 Sekunden sind um*/


Das wäre in etwa der Vorschlag von uwegw

Gruß Sebastian

Blue72
20.07.2008, 14:02
Hallo,

vielen Dank.
Ich werde es direkt zuhause ausprobieren.
Im prinzip würde doch der Code von Dir jetzt schon reichen oder ?
Einen extra Timer starten oder sonstwas muss ich doch eigentlich gar nicht mehr oder seh ich das falsch ?

Ich habe eh eine endlos Abfrage für einen ADC Eingang, dazwischen habe ich jetzt folgenden Code eingefügt (Taster ist Pind.7 ):


Do

If Taster = 1 Then A = A + 1
Else
A = 0
If A = 60 Then Print "60 sind um"



--
--
--

Loop

Gruß
Jens

izaseba
20.07.2008, 17:16
Hallo Jens,

Den Timer brauchst Du um auf Deine 3 Sekunden zu kommen .
Funktioniert denn Dein Programm ?
Wiel lange mußt Du drücken, bis der Print Befehl ausgegeben wird ?

Gruß Sebastian

P.S.

Irgendwie ist es nicht so einfach zu rechnen...
Bei einem Timerinterrupt von 10 mS mußt Du natürlich bis 300 rechnen um auf 3 Sekunden zu kommen ...

Blue72
20.07.2008, 17:36
Hallo Sebastian,

ja das Programm funktioniert soweit, einzigst mit dem LDR bin ich immer noch nicht so zufireden, er funktioniert zwar, aber nicht so wie ich möchte ;)
Das habe ich aber zum weitergrübeln hinten angestellt.

Eine Lösung mit dem Timer gefällt mir besser.
Ich habe jetzt festgestellt das A dann den Wert 1200 haben muss (ca., ein fach "mitgezählt" und die Printausgabe gelesen), das ist mir aber alles zu unsicher.

Wie kann ich denn den Timer0 mit dem Pind.7 Programmtechnisch verbinden ?

Jens

izaseba
20.07.2008, 18:09
Wie verbinden ?

So wie das oben steht, timer0 so konfigurieren, daß er alle 10 ms einen Überlauf macht.

In dem Overflow Interrupt, diese if else Sache rein fertig.

300 ist doof, das passt micht mehr in ein byte, da könnte man den Timer so einstellen, daß er alle 20 ms überläuft und bis 150 Zählen, klar ?

Gruß Sebastian

Blue72
20.07.2008, 19:32
Hmm ... ich konnte bis grade mit dem Begriff "Überlauf des Timers" nichts anfangen, jetzt bin ich schlauer :)

So, ich habe nur Timer0 oder Timer2 zur Verfügung, beide 8-bit.
Der Atmega8 läuft mit den internen 8MHz.
8MHz / 1024 (prescale) = 7812,5 Hz / Sekunde
Dann 7812,5Hz / 256 (8-bit) = 30,51

Heisst doch das der Timer0 dann 30,51 mal pro Sekunde überläuft oder ?

Um den Timer0 dann alle 20 überlaufen zu lassen müsste ich also
den Timer schon bei 2692,5 loslaufen lassen ?

Hab ich das so richtig verstanden ?

Gruß
Jens

guenter1604
20.07.2008, 20:42
Hallo Blue72,

der 8-Bit Timer kann nur von 0-255 zählen, dann löst er einen Interrupt (Überlauf) aus und fängt bei 0 wieder an.
Wenn du jetzt ausgerechnet hast, daß der Überlauf 30mal pro Sekunde auftritt und du ein Ereignis nach 3 Sekunden haben möchtest gilt:

1 Sekunde 30mal
3 Sekunden 90mal

also füge in die Interruptroutine eine Variable ein die auf 90 zählt, dann führst du deinen Code aus und setzt die Variable wieder auf 0.

Günter

Blue72
20.07.2008, 20:49
Hallo Günter,

stimmt das habe ich so ausgerechnet, wollte nur wissen ob das was ich rechne überhaupt richtig ist (zum verstehen).

Gruß
Jens