Forum: Mikrocontroller und Digitale Elektronik Die Tone Funktion in der ISR aufrufen.


von Sascha r. (Gast)


Lesenswert?

Hallo,
ich möchte gerne mit meinem Arduino UNO Board folgendes programmieren:

Wenn ich einen Taster betätige, soll der Interrupt 0 ausgelöst werden. 
In der ISR möchte ich mit Hilfe der tone Funktion eine Melodie 
abspielen. Da ich ja innerhalb der ISR die Delay Funktion nicht 
verwenden kann (benötige ich für die Notenlänge), habe ich die 
DelayMicroseconds() Funktion benutzt.

Leider funktioniert es so nicht, die tone Funktion benutzt den Timer 2, 
liegt es vielleicht daran?

Die tone Funktion läuft ausserhalb der ISR, ist also in Ordnung. Die 
Funktion DelayMicroseconds funktioniert in der ISR, also auch OK.

Würde mich über einen Tipp freuen....

gruß,

Sascha r.

von Autor (Gast)


Lesenswert?

Du kannst Alternativ in der ISR auch einfach nur eine Variable setzen. 
Diese frägst du dann in der main ab und reagierst dementsprechend.

von Ardu (Gast)


Lesenswert?

Innerhalb einer ISR keine Funktionen aufrufen nur Zustände ändern!

Welchen Grund hast du dieses zu tun? Das kann programmtechnisch einfach 
anders gelöst werden.

von Sascha r. (Gast)


Lesenswert?

Hallo,
der Grund...naja, ich steuer kontinuierlich eine 7 Segmentanzeige an die 
mir Temperaturen anzeigt, wenn jetzt der Taster betätigt wird, soll die 
Anzeige unterbrochen werden und primär diese eine Melodie abgespielt 
werden.

Gruß,
Sascha r.

von ladida (Gast)


Lesenswert?

7-Segment ansteuern macht man normalerweise im Hintergrund, ich vermute 
Multiplexing? Dann im Timer-Interrupt einfach die fertigen Daten 
rausschieben, die z.B. in nem Array bereit liegen, das in der main() 
gefüllt wird.
Tasten solltest du einfach per Polling abfragen, nicht per Interrupt, 
dabei Entprellung beachten.

Und schon hat dein µC genug Zeit, um das Display dauernd anzusteuern, 
deine Melodie abzuspielen und nebenbei noch Schach zu spielen ;)

von Karl H. (kbuchegg)


Lesenswert?

Tasten in einem Interrupt sind keine gute Idee.
Dafür würde das Multiplexing der 7-Segment in einen Timer Interrupt 
gehören.

Wurde aber auch von meinen Vorgängern schon angesprochen.

Wie man 'nebenher' eine Tonausgabe macht, das hatten wir vor kurzem 
schon mal:
Beitrag "Arduino tone() ohne delay"

von Sascha r. (Gast)


Lesenswert?

Hallo ladida,
dass hört sich gut. Ich weiß nicht ob Polling so gut ist, da noch 
ständig Temperatursensoren ausgelesen werden. Wenn ich jetzt den Taster 
drücke, während ich auf den DS18B20...naja, da ist wohl Interrupt 
besser. Ich werde es mal mit setzen einer Variablen ausprobieren, hört 
sich erstmal gut an.

Gruß

Sascha r.

von Sascha r. (Gast)


Lesenswert?

Hey Karl Heinz Buchegger,
ja dafür benutze ich auch den internen Interrupt mit mit Timer 1.

von Peter D. (peda)


Lesenswert?

Ich würde Töne einfach mit einem PWM-Ausgang erzeugen und die Dauer mit 
einem Timerinterrupt. Das kostet fast keine CPU-Last und blockiert auch 
nichts.

Falls man knapp an Timern ist, kann man auch für PWM und Dauer den 
gleichen Timer nehmen. Ergibt dann etwas höhere Interruptlast, da man 
die Perioden zählen muß.

von Sascha r. (Gast)


Lesenswert?

Hallo,
danke für die Antworten, ich habe es erstmal ohne den Aufruf der tone 
Funktion in der ISR gelöst (dank den Hinweisen). Aber mich würde es 
trotzdem interessieren, warum dies nicht funktioniert hat? Lag es 
wirklich an dieser Funktion, welche den Timer 2 benutzt?

von Wolfgang H. (frickelkram)


Lesenswert?

Sascha r. schrieb:
> Hallo,
> danke für die Antworten, ich habe es erstmal ohne den Aufruf der tone
> Funktion in der ISR gelöst (dank den Hinweisen). Aber mich würde es
> trotzdem interessieren, warum dies nicht funktioniert hat? Lag es
> wirklich an dieser Funktion, welche den Timer 2 benutzt?

Rechne doch mal das Timing durch. Mit welcher Rate hast Du den Timer 
aufgerufen? Wie lang war der Delay? Welche Tonfrequenzen hast Du 
erzeugen wollen?
Ich vermute einfach mal das die Interrupt-Frequenz höher war als Dein 
tiefster Ton. Dann möchte schon der nächste Interrupt feuern während 
Deine ISR noch im Delay hängt.
Die zwei Timer parallel zu betreiben ist ok, allerdings ist die Ton-ISR 
nicht nötig, wie oben schon erwähnt.
Wenn Du zwei ISR Routinen nutzt, die Ergebnisse gegenseitig nutzen musst 
Du die eventuell manuell synchronisieren, damit Du nicht in eine 
Race-Condition läufst. Dazu müsstest Du aber mal ein Listing des 
original-Codes einstellen, damit jemand drauf gucken und die gezielte 
Hinweise geben kann.

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.