Delay funktioniert nur in loop (Arduino)

OP #4360086
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
OP #4360149
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
OP #4360176
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
}
OP #4360200
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.
OP #4360213
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
Angehängte Dateien:
OP #4360265
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
Gast #4360276
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren