Forum: Mikrocontroller und Digitale Elektronik Delay funktioniert nur in loop (Arduino)


von Johannes S. (jojo_hau)


Lesenswert?

Hallo zusammen.

Ich baue aktuell eine Steuerung für eine Fräse. In meinem Code verwenden 
ich delay() und micros(). Das funktioniert alles in der loop-Schleife, 
ich möchte den code aber gerne mehrmals verwenden und wollte dafür den 
code in eine Funktion packen. In der Funktion funktionieren delay() und 
micros() dann aber nicht mehr.

Als Beispiel:
digitalWrite(LED, HIGH);
delay(5000);
digitalWrite(LED, LOW);
delay(5000);

funktionier in der loop-Schleife perfekt und in einer Funktion leuchtet 
die LED kurz auf und geht wieder direkt aus.

Funktionieren diese Zeit-Sachen nur in der Loop-Schleife? Kann ich mir 
nicht wirklich vorstellen.

Grüße,
Johannes

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Johannes S. schrieb:
> In der Funktion funktionieren delay() und micros() dann aber nicht mehr.

Wie gelangst Du zu dieser Erkenntnis?

Wann wird die Funktion von wo aufgerufen?

Wo ist Dein Code (nein, das Fragment oben zählt nicht)?

von Wolfgang (Gast)


Lesenswert?

Johannes S. schrieb:
> In der Funktion funktionieren delay() und micros() dann aber nicht mehr.

Du musst die Funktion dann auch in loop() aufrufen.

von Johannes S. (jojo_hau)


Lesenswert?

Danke für die Antwort.
Die oben genannten "5000" sind aber ein fester Wert, oder?

Zusätzlich vielleicht noch wichtig das ich dass ganze von dem 
receive-Event des I2c-Bus ausführen möchte. Ist das relevant?

Grüße,
Johannes

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Johannes S. schrieb:
> Die oben genannten "5000" sind aber ein fester Wert, oder?

Die hast Du selbst genannt.

Magst Du mit Dir noch mal ins Reine kommen, wer hier jetzt welche Frage 
stellt?

von Johannes S. (jojo_hau)


Lesenswert?

>Magst Du mit Dir noch mal ins Reine kommen, wer hier jetzt welche Frage
stellt?

Gerade stand hier noch dass Delay einen festen Wert braucht, ist aber 
schon wider weg.

>Wie gelangst Du zu dieser Erkenntnis?

Von der loop ausgeführt leuchtet die LED ca. 5 Sekunden und von dem 
receive-Event ausgeführt ca. 0,5s.

>Wo ist Dein Code (nein, das Fragment oben zählt nicht)?

Dachte mit einem so einfachen code ist es leichter den Fehler zu finden. 
Werden an meinen Code Notizen machen und gleich posten.

Grüße,
Johannes

von Johannes S. (jojo_hau)


Lesenswert?

Hier mein Code, hoffe alles ist verständlich. Das ganze ist eine 
Schrittmotoren-Steuerung für 3 Schrittmotoren.
1
void receiveEvent(int HowMany)
2
{
3
4
  //Hier ist Code der Parameter für die for-Schleife festlegt 
5
6
  
7
  for(long a = 0;a < SchritteMax; a++)
8
  {
9
    Micros1 = micros(); //Zeit messen für die Verzögerung am Ende der Schleife
10
    TimerX++;       
11
    TimerY++;         //Wichtig für die bestimmung Welcher pin eine Puls bekommt. Nicht jeder Pin bekommt bei einem Schleifen-durchlauf einen Impuls. Denke dass das nicht so wichtig ist.
12
    TimerZ++;         
13
    if(digitalRead(PinEndschalterX) == LOW || digitalRead(PinEndschalterY) == LOW || digitalRead(PinEndschalterZ) == LOW)
14
    {
15
      break;           //if abfrage ob ein Endschalter betätigt wurde. Denke dass ist unwichtig.
16
    }
17
    if(TimerX >= Switches[0])
18
    {
19
      digitalWrite(PinStepX, LOW);
20
      delayMicroseconds(Impulslange);  //Zeit die der Pin LOW wird. sind 32 MicroSekunden.
21
      digitalWrite(PinStepX, HIGH);
22
      TimerX -= Schritt[0];            //Relevant für die Auswahl der Pins
23
      XCoordinate += WertProSchrittX;  //Koordinaten werden aktualisiert
24
    }
25
    if(TimerY >= Switches[1])
26
    {
27
      digitalWrite(PinStepY, LOW);
28
      delayMicroseconds(Impulslange);
29
      digitalWrite(PinStepY, HIGH);
30
      TimerY -= Schritt[1];
31
      YCoordinate += WertProSchrittY;
32
    }
33
    if(TimerZ >= Switches[2])
34
    {
35
      digitalWrite(PinStepZ, LOW);
36
      delayMicroseconds(Impulslange);
37
      digitalWrite(PinStepZ, HIGH);
38
      TimerZ -= Schritt[2];
39
      ZCoordinate += WertProSchrittZ;
40
    }
41
    
42
    if(a < SchrittMaxBeschleunigung)
43
    {
44
      Delay -= int(Beschleunigung);  //veränderung des Delays am ende. Beschleunigung bzw. Bremsen am anfang und ende.
45
    }
46
    
47
    if(a > SchrittMinBremsen)
48
    {
49
      Delay += int(Beschleunigung);
50
    }
51
    
52
    if(Delay < GeschwindigkeitAchse)
53
    {
54
      Delay = int(GeschwindigkeitAchse); // kontrollieren der Endgeschwindigkeit/ stimmt nie so ganz
55
    }
56
    
57
    for(long l=0;l<15000;l++)
58
    {
59
      Micros2 = micros();
60
      if (Micros2 - Micros1 > Delay)  //Verzögerung bis Der delay erreicht ist. Delay hat einen Wert zwischen 150 und 9999 MicroSekunden.
61
      {
62
        break;
63
      }
64
    }
65
66
  }
67
}

von Dieter S. (Gast)


Lesenswert?

Erstmal ist derCode unvollständig und so funktioniert delay nicht.

Das muss so (Beispiel) aussehen "delay(500)".

von Johannes S. (jojo_hau)


Lesenswert?

Danke für die Antwort

Dieter S. schrieb:
> Erstmal ist derCode unvollständig und so funktioniert delay nicht.

Was fehlt die den? soll ich nochmal eine Version des Codes posten ohne 
alle unwichtigen Sachen?

Dieter S. schrieb:
> Das muss so (Beispiel) aussehen "delay(500)".

Danke für die info, mit einer Variable hat es bis jetzt bei mir noch nie 
Probleme gegeben. Hab das Ganze mit dem Wert 32 anstatt Impulslange 
probiert funktioniert aber trotzdem nicht.

von Dieter S. (Gast)


Lesenswert?

Im Code fehlt die komplette Deklaration und das Setup sowie die Loop. 
Wir wissen nicht was da losgeht.

Und die Variable musst du in die Klammer setzen.

von Johannes S. (jojo_hau)


Angehängte Dateien:

Lesenswert?

Ich hab die Datei mal Angehängt, da das Programm aber kompliziert ist 
und es keine Kommentare gibt werde ich hier die wichtigsten Sachen 
auflisten:

In dieser Version funktioniert der gesamte Code. Hier befindet sich der 
Primäre teil noch in der loop. In der nächsten Verion befinden sich 
vieles in einer libary.

Der Teil der in der loop steht soll in eine Funktion.

Der Arduino empfängt Daten über die I2c-Schnittstelle und setzt die 
Variabel Motorfahren auf true, wodurch die "Funktion" in der loop 
ausgeführt wird.

primär geht es darum das eine Funktion mit delay() oder micros() die vom 
receive-Event ausgeführt wird nicht korrekt funktioniert.

sorry hab den Code 2mal angehängt

: Bearbeitet durch User
von Ulrich F. (Gast)


Lesenswert?

Johannes S. schrieb:
> primär geht es darum das eine Funktion mit delay() oder micros() die vom
> receive-Event ausgeführt wird nicht korrekt funktioniert.

Das liegt daran, dass die Interrupts in einer Interruptroutine gesperrt 
sind.

von Albert M. (Firma: Bastler aus Mönchengladbach) (albertm) Benutzerseite


Lesenswert?

"Don't use the delay() function in an interrupt routine!
It relies on interrupts itself."

von Johannes S. (jojo_hau)


Lesenswert?

Danke für die Antworten

Albert M. schrieb:
> "Don't use the delay() function in an interrupt routine!
> It relies on interrupts itself."

was könnte ich als alternative nehmen? Die micros() Funktion scheint 
auch nicht zu funktionieren.

Grüße,
Johannes

von Ulrich F. (Gast)


Lesenswert?

Johannes S. schrieb:
> was könnte ich als alternative nehmen?

Du hast die Interruptroutine gnadenlos überladen.
Ändere das.
Schleifen, Delay() und seine Brüder haben da nichts drin verloren.
ISRs haben schlank zu sein.

von Johannes S. (jojo_hau)


Lesenswert?

Ulrich F. schrieb:
> Du hast die Interruptroutine gnadenlos überladen.
> Ändere das.
> Schleifen, Delay() und seine Brüder haben da nichts drin verloren.
> ISRs haben schlank zu sein.


Was meinst du damit konkret?
Ich denke das die Auswertung der Daten des I2c-Busses nicht so ein 
Problem ist, dass ist zwar viel code, es wird davon aber nur ein kleiner 
teil aufgerufen.

Soll ich die Funktion mit for-schleife und delays in die loop packen?

Grüße,
Johannes

von Ulrich F. (Gast)


Lesenswert?

> Was meinst du damit konkret?

Du beschwerst dich über das nicht funktionieren von delay() in einer 
ISR.
Ich sage: Dann ändere dein Programm so, dass das delay() nicht nötig 
ist.
Mehr nicht....
Der Ball liegt bei dir, spiele ihn.

von Johannes S. (jojo_hau)


Lesenswert?

Ich hatte nicht verstanden dass das Event eine ISR ist. Jetzt ist mir 
das Klar.
Hab auch schon eine Idee, werde das Morgen testen.

Danke für die Erklärungen.

Grüße,
Johannes

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.