PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ein Taster für 2 Aufgaben?



Inkoknito
13.03.2009, 12:05
Hallo,

ich möchte einen Taster drücken z.B. 1 sek und es soll die Aufgabe X durchgeführt werden, allerdings wenn ich den Taser 2 sek lang drücke soll Aufgabe 2 ausgeführt werden aber nicht aufgabe 1. Das ganze in Bascom.

Hat vieleicht dafür jemand einen Codeschnipsel oder einen Lösungsansatz oder sagr einen Link?
Habe auch schon die Forensuche benutzt aber leider leider nichts gefunden. Selber habe ich auch keine Idee wie man das realiesieren könnte.

besten dank : )

vklaffehn
13.03.2009, 13:07
Moin!
Kann zwar kein Bascom, aber hätte einen Ansatz:
Warten, bis Knopf gedrückt, Timer starten (oder anders Zeit messen), warten, bis Knopf wieder losgelassen, Zeit auslesen, auswerten...
MfG
Volker

Inkoknito
13.03.2009, 13:28
hi,

vielen Dank. Ich werde es gleich einmal ausprobieren wenn ich wieder zuhause bin, klingt auch logisch irgendwie : ) Habe aber noch nie mit timern gearbeitet, aber ich werde es mal testen.

Wie ist das wenn ich einen Taster am µC anschließe und starte den Timer und halt ihn wieder an, ist der taster dann auch entprellt? Zur Zeit löse ich das mit debounce. Oder kann man beides kombinieren?

merci

Realisator
13.03.2009, 15:10
Hallo Inkognito,

der Vorschlag von Volker ist zwar sicher der beste, aber natürlich führen noch diverse andere Wege nach Rom.
Wenn man es gerne ohne Timer machen will, könnte man z.B.:

- Bei Tastendruck eine Schleife starten, in der eine Variable hochgezählt wird.
- Schleife verlassen beim Loslassen der Taste.
- Zählerstand der Variable ist dann das Schätzeisen dafür, wie lange die Taste gedrückt war.


If Zählvariable < Bestimmter_Wert then
Aufgabe1
else
Aufgabe2
end if

Variable und Schleifendurchlaufzeit sollten so gewählt sein, dass ein Überlauf ausgeschlossen werden kann.
Oder ein Überlauf dient als weitere Abbruchbedingung für die Schleife.

Aber Volkers Weg ist zu bevorzugen.


Gruß
Stefan

Inkoknito
14.03.2009, 19:04
hat jemand von euch einen Codeschnipsel dafür wie ich die Zeit messe wie lange der Taster gedrückt ist?

habe mal mit dem Timer etwas rum probiert und auf dem Display soll etwas angezeigt werden wenn PinD.3 auf Masse gezogen wird doch leider passiert das nicht.


$regfile = "attiny2313.dat"
$crystal = 1000000
$hwstack = 64
$swstack = 30
$framesize = 120


Config Lcd = 16 * 2

Config Lcdpin = Pin , Db4 = Portb.3 , Db5 = Portb.2 , Db6 = Portb.1 , Db7 = Portb.0 , E = Portb.5 , Rs = Portb.4
Config Lcdbus = 4



Config Int1 = Falling 'Configuriere Int0 auf Low Level
Enable Interrupts 'einschalten der Interrupts
Enable Int1 'einschalten von Interrupt Int0
On Hallo 'springe Zu Isr_von _int0

Portd.3 = 1

Cls
Do
Locate 2 , 1
Lcd "Arii"
Loop
End

Hallo: 'isr Von Int0
Locate 1 , 1
Lcd "hallo"
Wait 1
Return


danke

repi64
14.03.2009, 22:54
On Hallo ist sicher nicht richtig. Eher was mit " On Int1 Hallo"
Ist auch sinnvoll die Kommentare mit anzupassen (Int0).

Inkoknito
15.03.2009, 15:01
hi,

so das mit dem Interrupt funktioniert jetzt, es lag nur an ein paar Schreibfehlern im Code.

Aber wie messe ich nun die Zeit, wie lange PIND.3 auf Masse gezogen wird. Ich nehme mal stark an mit einem Timer aber wie?

vielen dank : )


$regfile = "attiny2313.dat"
$crystal = 1000000
$hwstack = 64
$swstack = 30
$framesize = 120
Config Pind.2 = Input
Config Portd.1 = Output
Config Lcd = 16 * 2

Config Lcdpin = Pin , Db4 = Portb.3 , Db5 = Portb.2 , Db6 = Portb.1 , Db7 = Portb.0 , E = Portb.5 , Rs = Portb.4
Config Lcdbus = 4



'springe Zu Isr_von _int0

Portd.3 = 1


Config Int1 = Falling 'fallende Flanke

'INT0 einschalten
Enable Int1

'Interrupts global einschalten. Das ist der Hauptschalter für alle Interrupts
Enable Interrupts

On Int1 On_int0
Cls

Do

Toggle Portd.1
Waitms 200
Locate 1 , 1
Lcd "Test"
Loop


On_int0:
Cls
Locate 1 , 1
Lcd "Hallo Ari"
Wait 1
Cls
Return

-tomas-
16.03.2009, 22:16
ich denke, dass Peter Dannegger hier die beste Tastenlösung entwickelt hat (gcc).

Ich habe die einfache Lösung mal in Bascom umgeschrieben:
Beispiel 2 in https://www.roboternetz.de/wissen/index.php/Bascom_Debounce_ISR_in_Assembler

es gibt dazu noch eine erweiterte Lösung mit Taste Lang/Kurz gedrückt...

Realisator
17.03.2009, 01:03
Hallo Inkognito,

hier ein Schnippsel aus einem Programm von mir für den ATMega88, wo ich per Interrupt Signale einer spezielln Fernbedienung (nicht RC5) auswerte. Dazu messe ich jeweils die Zeit zwischen den Interrupts.
"Zeit messen" ist dabei fast falsch formuliert, denn mich interessiert hier kein Wert in menschenlesbarer Form, wie tausendstel Sekunden oder sowas, sondern es gibt in meinem Programm nur wenige unterschiedliche Pulslängen. Mir reicht es, die klar zu unterscheiden.




Config Timer0 = Timer , Prescale = 1024

On Pcint0 Int0_int 'Pin-Change-Interrupt initialisieren.
Pcmsk0 = &B00000001 'Nur PortB.0 abfragen.
Enable pcInt0 'Den Interrupt aktivieren.


Const Timervorgabe = 0
Enable Timer0 'Hier werden die Timer aktiviert

'##########################################
Int0_int:
'Hinweis: Die im Quelltext angegebene "Wechselzeit" bezieht sich auf einen 16MHz-Quarz
'unter Verwendung eines 8-Bit Timers mit Prescaler 1024.
'"Wechselzeit" ist die Zeit zwischen den Flanken, also von PC-Interrupt zu PC-Interrupt.
'---------------------------------------------------------------------------------------------------

Incr Ir_bitcount
Wechselzeit=Timer0 '-Timervorgabe
Timer0 = Timervorgabe

if Wechselzeit<3 then
Goto Verwerfen 'Zeit zu kurz. Fehlempfang. Paket verwerfen und raus hier.
end if



if EinsGleichZwei=1 then 'Nur durch Goto erreichbare Routine.
verwerfen:
Ir_Bitcount=0
Bitnummer=0
IR_Adresse=0
IR_Daten=0
end if

Return

Beste Grüße
Stefan[/code]

thewulf00
17.03.2009, 11:17
Übrigens:
Man muss nicht warten, bis der Taster losgelassen wurde.

Man geht einfach folgendermaßen vor.
Bei Tastendruck startet man einen Timer mit Interrupt bei Überlauf/Ablauf.
Der Timer wird auf einen Wert gesetzt, dass er überläuft, wenn der Taster eine Mindestzeit gehalten wird.

Kommt der Interrupt, ist es ganz automatisch schon Fall 2 (Taster lang gedrückt halten), egal ob er bereits losgelassen wurde.
Kommt das Loslassen des Tasters vor dem Interrupt, wird der Timer abgeschaltet und es ist Fall 1 (Taster kurz drücken).
Auf diese Weise kann man das Programm oder deren Funktionen nicht länger als nötig blockieren.