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
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)?
Johannes S. schrieb: > In der Funktion funktionieren delay() und micros() dann aber nicht mehr. Du musst die Funktion dann auch in loop() aufrufen.
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
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?
>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
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 | }
|
Erstmal ist derCode unvollständig und so funktioniert delay nicht. Das muss so (Beispiel) aussehen "delay(500)".
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.
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.
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
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.
"Don't use the delay() function in an interrupt routine! It relies on interrupts itself."
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
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.
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
> 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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.