Forum: Mikrocontroller und Digitale Elektronik Delay während noInterrutps()


von Wer B. (Gast)


Lesenswert?

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.

von R. F. (rfr)


Lesenswert?

Wovon schreibst du?
Meintest du, dass in einem Interrupt kein Delay auftreten darf?

oder was?

Robert

von Wer B. (Gast)


Lesenswert?

R. F. schrieb:
> Wovon schreibst du?
> Meintest du, dass in einem Interrupt kein Delay auftreten darf?

Ja, so gelesen

von Vincent H. (vinci)


Lesenswert?

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.

von Student (Gast)


Lesenswert?

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?

von Jim M. (turboj)


Lesenswert?

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.

von Wer B. (Gast)


Lesenswert?

Nein, der Uno soll 2 Sekundenlang von nichts gestört werden

von Wer B. (Gast)


Lesenswert?

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.

von Wer B. (Gast)


Lesenswert?

Die Serielle Verbindung wird nicht benötigt (in dieser Zeit).

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

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.

von W.A. (Gast)


Lesenswert?

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.

von Wer B. (Gast)


Lesenswert?

Wie soll ich das nun in der Arduino IDE schreiben ?

Schon mal danke für die vielen Antworten

von Lötpunkt (Gast)


Lesenswert?

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?

von Carl D. (jcw2)


Lesenswert?

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.

von Wer B. (Gast)


Lesenswert?

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?

von Wolfgang (Gast)


Lesenswert?

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?

von The D. (thedaz)


Lesenswert?

Man kann delays auch ohne Interrupts realisieren indem man einen Timer 
benutzt und dessen count Register in einer while loop gegen einen 
Zielwert vergleicht.

von Wer B. (Gast)


Lesenswert?

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)

von Wer B. (Gast)


Lesenswert?

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

von The D. (thedaz)


Lesenswert?

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.

von Michael U. (amiga)


Lesenswert?

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

von Wolfgang (Gast)


Lesenswert?

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.

von Wer B. (Gast)


Lesenswert?

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

von Michael R. (mr-action)


Lesenswert?

Warum ignorierst du die empfangenen Wiederholungen nicht einfach? Is 
doch wesentlich besser wie evtl. etwas wichtiges zu verpassen, weil man 
grade ganz Taub ist...

von Amateur (Gast)


Lesenswert?

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.

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.