Liebe Community,
ich komme zurzeit nicht so ganz weiter, da ich das mit den delays bei
ausgestellten Interrupts nicht verstehe.
Ich würde gerne den Uno ca. 2 Sec warten lassen, und er darf dabei auf
keinen Fall unterbrochen werden, danach ist das ok.
Mit:
noInterrupts();
delay(2000);
Interrupts();
soll es ja angeblich nicht gehen...
Alternativen... ?
Viele Dank schon mal im Vorraus
Simon Sp.
Simon S. schrieb:> Liebe Community,>> ich komme zurzeit nicht so ganz weiter, da ich das mit den delays bei> ausgestellten Interrupts nicht verstehe.>> Ich würde gerne den Uno ca. 2 Sec warten lassen, und er darf dabei auf> keinen Fall unterbrochen werden, danach ist das ok.> Mit:> noInterrupts();> delay(2000);> Interrupts();> soll es ja angeblich nicht gehen...>> Alternativen... ?>> Viele Dank schon mal im Vorraus>> Simon Sp.
Bei so langen Delays lässt man das Gerät im Normalfall in einen
Sleep-Modus gehen und nutzt diverse "Wake-On-Interrupt" Features. Wie
genau das beim Uno geht kann ich aber leider nicht sagen.
Es geht ziemlich sicher nicht. Ein Delay funktioniert so:
Es wird ein Timer gesetzt, z.B. auf eine ms, dann wird eben so lange
gewartet bis 2000 Interrupts reinkamen.
Du kannst mit Interruptmasken ggf. bestimmen, welche Interrupts
durchkommen oder z.B. alle interrupts erlauben aber als handler nichts
tun. Das wird dann allerdings ungenauer ein wenig.
btw:
> Meintest du, dass in einem Interrupt kein Delay auftreten darf?
Du meinst doch eher dass im Delay kein Interrupt auftreten darf, so dass
der Delay exakt ist?
Simon S. schrieb:> oInterrupts();> delay(2000);> Interrupts();> soll es ja angeblich nicht gehen...
Kommt etwas darauf an wie Dein delay() implementiert wurde,
bei einfecher Schleife mit NOPs würde es tun.
Probleme macht das aber falls da noch ander Peripherie aktiv ist, in den
2 Sekunden könnten Dir z.B. hunderte Zeichen auf dem UART verloren
gehen.
Jim M. schrieb:> Simon S. schrieb:>> oInterrupts();>> delay(2000);>> Interrupts();>> soll es ja angeblich nicht gehen...>> Kommt etwas darauf an wie Dein delay() implementiert wurde,> bei einfecher Schleife mit NOPs würde es tun.>> Probleme macht das aber falls da noch ander Peripherie aktiv ist, in den> 2 Sekunden könnten Dir z.B. hunderte Zeichen auf dem UART verloren> gehen.
UART?
Der Arduino soll 2 Sekunden in einer Switch case abfrage nicht gestört
werden.
Wenn es hilft kann ich gerne den Code posten.
Simon S. schrieb:> Mit:> noInterrupts();> delay(2000);> Interrupts();> soll es ja angeblich nicht gehen...
In AVR-GCC (und der liegt auch unter dem Arduino Krams drunter)
funktioniert das hier sicher:
1
cli();
2
_delay_ms(2000);
3
sei();
Ob dein Code auch spielt, kann ich nicht sagen, denn ein
'noInterrupts()' und 'Interrupts() sind mir unbekannt. Evtl. ist das
Arduino-Sketch-Dialekt.
Matthias S. schrieb:> Ob dein Code auch spielt, kann ich nicht sagen, denn ein> 'noInterrupts()' und 'Interrupts() sind mir unbekannt. Evtl. ist das> Arduino-Sketch-Dialekt.
Das wird nicht irgendein Dialekt sein, sondern das sind - wie in C
üblich - Funktionsaufrufe.
Simon S. schrieb:>>> oInterrupts();>>> delay(2000);>>> Interrupts();>>> soll es ja angeblich nicht gehen...> Der Arduino soll 2 Sekunden in einer Switch case abfrage nicht gestört> werden.> Wenn es hilft kann ich gerne den Code posten.
Hallo Simon,
das passt irgend wie nicht zusammen. Was soll denn nun wirklich
geschehen. Soll die switch/case Abfrage laufen oder soll der Arduino 2
Sekunden warten?
Interrupts, die nach dem cli() auftreten, sind aber nicht weg.
Wenn "nicht gestört" also bedeuten soll "Interrupts aus dieser Zeit
ignorieren", dann muß man deutlich mehr tun.
Der Arduino soll ein Switch-Case machen.
In der Anfrage, wenn x = y ist, soll er (bsp.) die Led anmachen und
danach 2 Sekunden warten, ohne von einem externen Interrupt gestört zu
werden.
Mit noInterrupts() und interrupts() hat es bis jetzt auch immer
funktioniert, Intterupts zu unterbinden, jedoch habe ich nie ein Delay
benutzt.
Ich könnte den Intterupt Pin als Ausgang setzen und danach wieder als
Interrupt, aber da muss es doch was einfacheres geben oder?
Simon S. schrieb:> In der Anfrage, wenn x = y ist, soll er (bsp.) die Led anmachen und> danach 2 Sekunden warten, ohne von einem externen Interrupt gestört zu> werden.
Wenn du mit möglichen Interrupts rechnest und die für 2 Sekunden
unterbinden willst, hört sich das nach ziemlichem Murks an. Warum darf
da kein Interrupt zwischen kommen? Was ist dein eigentliches Problem
und Anlass für diesen "ungewöhnlichen" Lösungsweg?
Man kann delays auch ohne Interrupts realisieren indem man einen Timer
benutzt und dessen count Register in einer while loop gegen einen
Zielwert vergleicht.
Ich habe einen 433Mhz Sender, der jedes Signal mehr als einmal sendet,
damit es wahrscheinlicher ist das es ankommt.
Der Empfänger soll das Signal aber nur einmal aufzeichnen und nicht
mehrmals.
Deswegen soll er nach dem ersten Empfang(Interrupt) nichts mehr
empfangen.
(und daher alle anderen Interrupts der nächsten 2 Sekunden ignorieren)
The D. schrieb:> Man kann delays auch ohne Interrupts realisieren indem man einen Timer> benutzt und dessen count Register in einer while loop gegen einen> Zielwert vergleicht.
Könntest du ein bsp für ca 2 sec geben
Simon S. schrieb:> The D. schrieb:>> Man kann delays auch ohne Interrupts realisieren indem man einen Timer>> benutzt und dessen count Register in einer while loop gegen einen>> Zielwert vergleicht.>> Könntest du ein bsp für ca 2 sec geben
Ja, für nen ARM Prozessor, für einen Arduino habe ich kein Beispiel
parat. Das ist auch vom verwendeten Arduino abhängig. Ich empfehle die
Lektüre des zugehörigen Datenblatts, Kapitel Timer.
Hallo
Simon S. schrieb:> Wie soll ich das nun in der Arduino IDE schreiben ?
1
cli();
2
_delay_ms(2000);
3
sei();
schreib es eben so in Deinen Sketch, die Arduino-IDE ist manchmal besser
als ihr Ruf.
Ob es macht, was Du erreichen willst, mußt Du selber testen.
Wenn Dein Interrupt mit attachInterrupt() eingehängt ist, kannst Du ihn
auch einfach mit detachInterrupt() solange aushängen.
Gruß aus Berlin
Michael
Simon S. schrieb:> Könntest du ein bsp für ca 2 sec geben
Der Timer läuft auf deinem Uno bereits und stellt dir die aktuelle Zeit
über die Funktion millis() zur Verfügung. Wenn man also nach Empfang der
ersten Message sich die Zeit holt, 2 Sekunden dazuaddiert und sich das
in einer Variablen merkt, kann man jederzeit durch Vergleich
feststellen, ab wann ggf reinkommende Messages wieder berücksichtigt
werden soll.
Um einen Interrupt zu unterbinden, löscht man üblicherweise das
betreffende Interrupt-Enable-Bit und dann ist gut.
Michael U. schrieb:> Wenn Dein Interrupt mit attachInterrupt() eingehängt ist, kannst Du ihn> auch einfach mit detachInterrupt() solange aushängen.
Danke, das ist die Lösung
Warum ignorierst du die empfangenen Wiederholungen nicht einfach? Is
doch wesentlich besser wie evtl. etwas wichtiges zu verpassen, weil man
grade ganz Taub ist...
delay wird meist als, an die Taktfrequenz angepasste, Endlosschleife
implementiert.
Wenn ich aber davon ausgehe, dass für die meisten Verzögerungen keine
exakte Teilung möglich ist, halte ich die Unterdrückung, von
Unterbrechungen, nicht gerade für die Beste aller Lösungen.
Die Verzögerung wird dabei zwar konstanter, aber nicht genauer.