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.
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.
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.
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 ;)
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"
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.
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ß.
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?
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.