Forum: Mikrocontroller und Digitale Elektronik Attiny mit Timer und Taster


von Tommy T. (thomas_k86)


Lesenswert?

Hab da ne Frage!

Habe da einen Code wo man den Ausgang über den Timer0 mit einem Taster 
einschaltet.
Ich möchte aber in der Zeit wo der Timer abläuft,das Programm mit dem 
selben Taster auch beenden können.
Was fehlt da noch?
Danke schon mal.

von Manuel S. (steinerhippo)


Lesenswert?

Verstehe ich richtig, dass du auf Tastendruck einen Timer aktivierst?

Ohne etwas mehr Erklärung wird das wohl nichts werden. Wo fragst du den 
Taster ab? Der Timer läuft, wenn der Taster gedrückt ist, oder immer? 
Wird die Timer ISR dann periodisch aufgerufen, oder soll diese nur 
einmal ausgeführt werden?

Wenn die Tasterabfrage in der main Methode passiert, kannst du doch 
einfach den Timer wieder deaktivieren.

Du kannst auch alternativ den Taster als Interrupt Auslöser verwenden 
und in der main Methode die Arbeit erledigen und mittels Flag von der 
ISR in die main Methode signalisieren, was zu tun ist.

Eigentlich tappe ich aber im Dunklen, weil deine Angaben mehr als 
dürftig sind.

von Peter D. (peda)


Lesenswert?


von Tommy T. (thomas_k86)


Angehängte Dateien:

Lesenswert?

Ups!!Da hab ich doch glatt vergessen den Code anzuhängen.War schon a 
bisi müde! :)
1
$regfile = "attiny13.dat"                                   'verwendeter Prozessor
2
$crystal = 1200000                                          'Definition des Takt
3
$hwstack = 15
4
$swstack = 15
5
$framesize = 15
6
7
Config Timer0 = Timer , Prescale = 1024                     'hier wird der timer configuriert
8
Timer0 = 57722
9
10
On Timer0 Ontimer1                                          'bei einem timerüberlauf springt der controller zu ontimer0
11
12
13
14
Config Pinb.2 = Input
15
Config Portb.1 = Output
16
17
Dim Zeit As Byte
18
19
Taster1 Alias Pinb.2
20
21
22
Hauptprogramm:
23
Do
24
If Taster1 = 0 Then Gosub Relais1
25
26
Loop
27
28
29
Relais1:
30
   Enable Timer0                                            'der timer wird eingeschaltet
31
   Enable Interrupts                                        'die interrupts werden eingeschaltet (hier nur der timer interrupt ist nötig dass der avr interrupts zulässt)
32
   Portb.1 = 1
33
34
      Do
35
         If Zeit < 1 Then
36
                                            ' wen die zeit Über 1 sekunde ist werden der timer und die interrupts wieder deaktiviert
37
            Disable Timer0
38
            Disable Interrupts
39
            Portb.1 = 0                                     'das relai fällt ab
40
            Goto Hauptprogramm                              'der controller verlässt die do loop schleife und kommt weider zum hauptprogramm zurück
41
         End If
42
      Loop
43
Return
44
45
46
47
48
49
Ontimer1:                                                   ' hier der timer interrupt
50
   Zeit = Zeit + 1                                          ' zeit wird um eins erhöht
51
   Timer0 = 57722
52
Return                                                      ' der timer bekommt einen wert dass er nicht die vollen 65535 takte zählen muss das würde länger als eine sekunde dauern
53
                                           ' der controller kehrt zum programm zurück

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Tommy Tomatronic schrieb:
> Hauptprogramm:
..
> If Taster1 = 0 Then Gosub Relais1
..
> Relais1:
..
>             Goto Hauptprogramm
..
> Return

Ein C-Compiler würde Dich dafür ungespitzt in den Boden rammen (sprich 
einen fatalen Fehler melden).
In Bascom wird wohl nur Dein Stack überlaufen.

von Karl H. (kbuchegg)


Lesenswert?

Tommy Tomatronic schrieb:
> Ups!!Da hab ich doch glatt vergessen den Code anzuhängen.

Ist das der Code, der zu deiner Ausgangsfrage im Eröffnungsposting 
gehört.

Denn dann
> Was fehlt da noch?

Antwort:
Ziemlich viel. Der ganze Prgorammaufbau ist mies.
Schmeiss ihn weg, überleg dir was anderes und probier das aus.


Hinweis: Der Ansatz mit dem Timer ist grundsätzlich ok. Das geht schon 
mal in die richtige Richtung.

Hinweis 2:
Grundsätzlich gibt es 2 verschiedene Möglichkeiten für eine derartige 
'Uhrenverwendung'. Man kann die Zeit positiv abzählen. Im Sinne von: ich 
zähle einen Zähler raus und wenn der eine bestimmte Zahl erreicht hat, 
ist die zu wartende Zeit um.
Man kanns aber auch anders rum machen: Der Zähler zählt nicht hoch und 
es wird auf das Erreichen eines bestimmten Zählerstandes geprüft, 
sondern man dreht das Pferd um. Ein Countdown. Der Zähler startet bei 
einem bestimmten Zählerstand und wenn 0 erreicht wird, dann ist die Zeit 
um.

Die zweite Lösung hat den Vorteil, dass das Prüfen der Endbedingung 
immer auf 0 erfolgt, was den Code öfter etwas vereinfacht, weil man 
keine variable Endbedingung braucht (wenn die Zeit variabel sein soll). 
Soll meine Uhr unterschiedliche Zeiträume abmessen können, dann geht das 
ganz einfach, in dem ich ihr eben jene unterschiedlichen Zeitan als 
Startwert vorgebe.

Funktionieren tut beides und man muss dann im Einzelfall entscheiden, 
was einfacher ist.

Hinweis 3:
Auch wenn immer wieder gesagt wird, dass Interrupt Routinen kurz sein 
sollen (was ja grundsätzlich auch stimmt), so bedeutet das nicht, dass 
man in ihnen gar nichts tun darf.
Wenn du dort einen Zähler erhöhst, dann darf man da durchaus auch in der 
ISR Prüfen, ob dieser Zählwert eine bestimmte Bedingung erfüllt und dann 
zb davon abhängig einen Ausgang schalten. In Summe ist das immer noch 
einfacher und schneller abgearbeitet, als irgendwelche anderen 
Konstrukte. Denn in dem Fall bedeutet das dann ganz einfach, dass die 
Hauptschleife eben nicht auf das Ablaufen der Zeitdauer warten muss und 
in der Zwischenzeit was anderes tun kann. Zum Beispiel einen weiteren 
Tastendruck auswerten. Die Hauptschleife startet einfach nur den Timer 
(eventuell unter Vorgabe einer zu wartenden Zeit, wenn es sich um einen 
Countdown-Zähler handelt), setzt einen Ausgang und die Interrupt Routine 
schaltet dann den Ausgang nach Ablauf der Zeit selbsttätig wieder ab.

Als Skizze
1
countdown = 0
2
timer starten
3
interrupt enable
4
5
6
do
7
8
  if( Taste gedrückt ) then
9
    Ausgang ein schalten
10
    countdown = 5
11
  end if
12
13
loop
14
15
OnTimer
16
  if countdown > 0 then
17
    countdown = countdown - 1
18
    if countdown = 0 then
19
      Ausgang aus schalten
20
    endif
21
  endif
22
  return


da solltest du jetzt auch eine Möglichkeit finden, wie du ein 
vorzeitiges Ende mittels Tastendruck einbauen kannst. Hinweis: Du weißt 
das die Wartezeit noch nicht abgelaufen ist, wenn die Variable countdown 
einen Wert ungleich 0 besitzt.

D.h. du kannst hier
1
do
2
3
  if( Taste gedrückt ) then
4
5
    ****************
6
7
    Ausgang ein schalten
8
    countdown = 5
9
  end if
anhand des aktuellen Wertes in countdown unterscheiden, ob ein 
Tastendruck den Zähler ein oder ausschalten soll.
Beachte auch, dass ich durch die Systematik jetzt auch nicht mehr 
laufend den Timer starten/stoppen bzw. Interrupts ein ausschalten muss. 
Denn wenn Countdown bereits auf 0 steht, dann macht die Interrupt 
Routine einfach nichts mehr. Damit ist es aber egal, ob der Timer läuft 
oder nicht. Und im Zweifelsfall entscheide ich mich dann für die 
einfachere Variante, in der ich mich um den Timer selbst im weiteren 
Programmverlauf nicht mehr kümmern muss.


Hinweis 3:
Das hier
1
If Taster1 = 0 Then
ist auch in BASCONM keine vernünftige Methode um einen Tastendruck zu 
erkennen. BASCOM macht es dir insofern leicht, als es dafür den Befehl 
"DEBOUNCE" gibt. Man mag dazu stehen wie man will, aber das ist nun mal 
die BASCOM Methode um einen Tastendruck zu erkennen.

: Bearbeitet durch User
von Tommy T. (thomas_k86)


Lesenswert?

Himmel,Arsch und Zwirn!! :)

Das wird nix! Hat niemand eine fertige Lösung für mich?Ich bin schon am 
verzweifeln.Da kann doch nichts dabei sein,habe ich mir gedacht.Da ist 
doch nix dran.Aber es will einfach nicht sein.
Also ganz einfach!
Ich möchte:Wenn ich Portb.2 mit einem Taster 0,3sek lang auf Gnd 
ziehe,soll Portb.1 60 min auf High schalten.Wenn ich innerhalb der 60 
min wieder Portb.2 für 0,3 auf low ziehe,soll Portb.1 auch schon auf low 
schalten.
Das ganze mit einem ATtiny13 oder 45.
Danke für eure mühen!!

von Karl H. (kbuchegg)


Lesenswert?

Tommy Tomatronic schrieb:
> Himmel,Arsch und Zwirn!! :)
>
> Das wird nix!

Zeig doch mal.
Das Grundgerüst steht doch schon. In sauberes BASCOM überführen und den 
Teil, den ich zur Übung ausgelassen habe einsetzen und im Grunde wars 
das auch schon.


> Ich möchte:Wenn ich Portb.2 mit einem Taster 0,3sek

Sind die 0.3sek Bedingung?

: Bearbeitet durch User
von pff (Gast)


Angehängte Dateien:

Lesenswert?

das blitzen abschalten und die Zeit musste schon selbst anpassen...
;-)

von Tommy T. (thomas_k86)


Lesenswert?

Karl Heinz schrieb:
> Sind die 0.3sek Bedingung?

Nein nur ein Richtwert.Also ein normales bedienen eines Tasters.

von F. F. (foldi)


Lesenswert?

Tommy Tomatronic schrieb:
> Karl Heinz schrieb:
>> Sind die 0.3sek Bedingung?
>
> Nein nur ein Richtwert.Also ein normales bedienen eines Tasters.

Also eher 30ms statt 300ms. Soll sicher dem Entprellen dienen und dafür 
reichen 30ms.

: Bearbeitet durch User
von Tommy T. (thomas_k86)


Lesenswert?

pff schrieb:
> das blitzen abschalten und die Zeit musste schon selbst anpassen...
> ;-)

Danke lieber pff aber der Code funzt nicht. Portb.2 ist auf High sonst 
tut
sich da nix.

von Karl H. (kbuchegg)


Lesenswert?

Nochmal:
wo ist DEIN Code?

Den Code von pfff hab ich nicht näher studiert, der ist mir zu 
umfangreich für die Aufgabenstellung.
ABer ich weiß 100%-ig, dass das weiter oben skizzierte Framework die 
Aufgabe mit Leichtigkeit lösen kann. Also: wie hast du die Skizze 
umgesetzt?

von pff (Gast)


Lesenswert?

bei mir:
Config Portb.2 = Output : Led3_d3 Alias Portb.2             ' off Bord 
=D3

bei dir:
Config Pinb.2 = Input

ein bischen kopfschmerzen muss ich dir schon an tun...
:-)

von nana_jaja (Gast)


Lesenswert?


von Tommy T. (thomas_k86)


Lesenswert?

Karl Heinz schrieb:
> Also: wie hast du die Skizze
> umgesetzt?

Ich hab da ungefähr 20 - 30 mal rumgestrickt und wie man da immer sagt
"lösche das ganze und fange von vorne an" Das mache ich mittlerweile 
ständig.Ich bin einfach zu doof für so was vermutlich leichtes. :)

von Karl H. (kbuchegg)


Lesenswert?

Tommy Tomatronic schrieb:
> Karl Heinz schrieb:
>> Also: wie hast du die Skizze
>> umgesetzt?
>
> Ich hab da ungefähr 20 - 30 mal rumgestrickt

Zeigen

> Ich bin einfach zu doof für so was vermutlich leichtes. :)
Die Umstellung in der Denkweise ist das schwierige.
Der Rest ist reines Anwenden der BASCOM Syntax an den Stellen, die ich 
lapidar einfach in Deutsch formuliert habe bzw. Ergänzen von 
Standardsachen, wie Variablendefinition oder Konfiguration von I/O Pins.

: Bearbeitet durch User
von nana_jaja (Gast)


Lesenswert?


von Tommy T. (thomas_k86)


Lesenswert?

pff schrieb:
> bei mir:
> Config Portb.2 = Output : Led3_d3 Alias Portb.2             ' off Bord
> =D3
>
> bei dir:
> Config Pinb.2 = Input
>
> ein bischen kopfschmerzen muss ich dir schon an tun...
> :-)

Das weis ich schon.Das hab ich gleich bemerkt.
Also Portb.2 ist auf High,sonst passiert da nix.Da reagiert nix auf den 
Taster am Portb.1

von pff (Gast)


Lesenswert?

bei mir ist da ein externer widerstand als pullup dran.
also sieht er die taste garnicht.
also hinter
config pinb.1 = input    ' schalte port auf in
portb.1 = 1              ' schalte pullup für pin ein

aber du solltest mal bei halvar rein schauen!

von Tommy T. (thomas_k86)


Lesenswert?

pff schrieb:
> bei mir ist da ein externer widerstand als pullup dran.

Der externe ist bei mir auch drauf und mit dem internen hab ichs auch 
schon versucht,also mit Portb.1 = 1.

Ich hab schon einiges gebaut mit Mc aber so ne scheisse wie eben hatte 
ich doch noch nie!

Da kann auch der harvar nix für.der Code geht trotzdem nicht. :)

von Tommy T. (thomas_k86)


Lesenswert?

So jetzt hats gereicht!! :)
Jetzt hab ich da ein Uhrenprogramm hergenommen und das umgstrickt,dass 
es mit dem ATtiny45 läuft es funktioniert sogar. :)
Etwas schöner muss ich das noch schreiben aber es funzt! :) :) :)


$regfile = "attiny45.dat"                                   'verwendeter 
Prozessor
$crystal = 8000000                                          'Definition 
des Takt
$hwstack = 15 
'Reservierung im SRAM
$swstack = 15
$framesize = 15

'*** Ports 
konfigurieren********************************************************

Ddrb = &B00001100
Portb = &B00000011

On Timer1 Ontimer1
Config Timer1 = Timer , Prescale = 1024
Enable Timer1

Enable Interrupts

Dim Wert As Byte
Dim Multiplex As Byte
Dim Hsek_einer As Byte
Dim Hsek_zehner As Byte
Dim Sek_einer As Byte
Dim Sek_zehner As Byte
Dim Min_einer As Byte
Dim Min_zehner As Byte
Dim Std_einer As Byte
Dim Std_zehner As Byte

Declare Sub Minute
Declare Sub Stunde

Multiplex = 1
Timer1 = 51803

Stop Timer1

Do
   Debounce Pinb.0 , 0 , Minute , Sub
   Debounce Pinb.1 , 0 , Stunde , Sub
Loop

'*** Sub-Routinen 
**************************************************************
Sub Minute

    Start Timer1
    Portb.3 = 1
End Sub

Sub Stunde

    Stop Timer1
Hsek_einer = 0
Hsek_zehner = 0
Sek_einer = 0
Sek_zehner = 0
Portb.3 = 0
Portb.2 = 0

End Sub

'*** Interrupt-Routinen 
********************************************************
Ontimer1:                                                   'Aufruf im 
Sekundentakt
   Timer1 = 51803 
'65536-15625=49911 =1Hz

   Incr Hsek_einer

     If Hsek_einer >= 7 Then
      Hsek_einer = 0

      Incr Hsek_zehner
   End If

     If Hsek_zehner >= 7 Then
      Hsek_zehner = 0

      Incr Sek_einer
      Toggle Portb.2
   End If

   If Sek_einer = 40 Then

      Portb.3 = 0
      Return


   End If

   Return
   End

: Bearbeitet durch User
von Tommy T. (thomas_k86)


Angehängte Dateien:

Lesenswert?

Das ganze etwas schöner .Die zeit muss noch angepasst werden,den so 
schauts vielleicht doch a bisi komisch aus! :)

von Karl H. (kbuchegg)


Lesenswert?

manchmal ist es echt frustrierend hier den Leuten helfen zu wollen, ohne 
ihnen eine Lösung auf dem Silbertablett zu präsentieren.

von Tommy T. (thomas_k86)


Lesenswert?

Karl Heinz schrieb:
> manchmal ist es echt frustrierend hier den Leuten helfen zu wollen, ohne
> ihnen eine Lösung auf dem Silbertablett zu präsentieren.

Es muss doch nicht frustrierend sein!
Es ist oft besser so.Nur so lernt mans.Obs dann eine schöne Lösung 
ist,die dabei rauskommt,ist wieder was anderes. Hauptsache es Futzt. :)

von Hannes L. (hannes)


Lesenswert?

Tommy Tomatronic schrieb:
> Hauptsache es Futzt.
                  ^

Du hast wohl "t" und "r" verwechselt? ;-)

...

: Bearbeitet durch User
von Tommy T. (thomas_k86)


Lesenswert?

Hannes Lux schrieb:
> Tommy Tomatronic schrieb:
>> Hauptsache es Futzt.
>                   ^
>
> Du hast wohl "t" und "r" verwechselt? ;-)
>
> ...

Nein hab ich nicht. :) :)
Es läuft schon einige Tage und geht immer noch.

von Slang (Gast)


Lesenswert?

"funzt", von "funktioniert"; Bastler-Slang.

von Hannes L. (hannes)


Lesenswert?

Slang schrieb:
> "funzt", von "funktioniert"; Bastler-Slang.

Hmmm, "funzt" stand aber nicht da... ;-)
         ^

...

von Tommy T. (thomas_k86)


Lesenswert?

Hannes Lux schrieb:
> Hmmm, "funzt" stand aber nicht da... ;-)
>          ^

JaJa ich weiss schon! :) :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.