Hi, folgendes Problem: Ich möchte, dass bestimmte Funktionen alle x ms ausgeführt werden. Beispiel: Zeitstempel seit Start|Funktion 0 | A 150 | B 300 | A 450 | B 600 | A 750 | B 900 | A 1150 | C 1300 | B 1450 | A usw. Also jeweils 150ms Abstand zwischen den Funktionen. C aber zB nur bei jedem 8ten Durchlauf. Das Ganze möchte ich ohne delays bauen. Jemand eine Idee, wie man das machen kann?
Du setzt einen Timer auf der alle 50ms eine Interruptfunktion mit einer Statemachine oder internen Zaehlen aufruft. Dort schaust du dann welche Funktion gestartet werden soll. Entweder ist die Funktionalitaet sehr banal, z.B einen Port setzen, dann fuehrst du sie direkt aus. Oder sie ist komplexer, dann setzt du ein Startflag welches in deinem Hauptprogramm beachtung findet. Olaf
Guten Morgen, ja wurde "2003" von Peter Dannegger erfunden: Beitrag "Wartezeiten effektiv (Scheduler)" Damit lassen sich ohne Vorkenntnisse zeitabhängige Prozesse erstellen. Wenn man das Prinzip mal erkannt und verstanden hat, geht es auch mit eigenem Code.
Ich verstehe das Problem nicht. Das ist doch ein klassischer Timer-Interrupt. Alle 150ms löst der Timer-Interrupt aus. In der Interrupt-Routine wird halt ein Counter gezählt und bei erreichen von 8 die gewünschte Funktion ausgeführt und Timer wieder zurückgesetzt.
Unter der Vorraussetzung, dass die Funktionen nicht länger als 150 ms brauchen, kannst du einfach alls 150ms einen Timer-Interrupt auslösen. Der setzt ein Flag, auf das eine Warteschleife in der Hauptroutine wartet. Daraufhin wird eine der Funktionen in Abhängigkeit zu einer Zählvariablen gestartet. Danach wird die Zählvariable um 1 inkrementiert. Wenn sich die Geschichte bei jedem 8. Durchlauf wiederholt, kann man die Zählvariable auch auf den Bereich 0-7 reduzieren, indem man sie bei 8 auf 0 zurücksetzt.
Tom Thomsen schrieb: > Wie soll man damit auf 1150ms kommen? Indem man 900 + 150 korrekt mit 1050 berechnet (und nicht mit 1150) :-) Gesucht waren 150er Schritte ...
Tom Thomsen schrieb: > Wie soll man damit auf 1150ms kommen? Da ich auch den gleichen "Mist" geschrieben habe: Einfach die Zeitbasis passend verringern und die Vergleichswerte der Zählvariable entsprechend anpassen. (50ms wurden ja schon vorgeschlagen).
Habs jetzt so gelöst: Das results array beinhaltet alle Funktionen, die im 150ms Takt aufgerufen werden könnten. #x gibt funktionen an, die nur bei jedem x-ten Durchlaufen kommen. Aufruflogik fehlt noch
1 | #include <Metro.h> |
2 | Metro ledMetro = Metro(250); |
3 | |
4 | #define ARRAYSIZE 10 |
5 | char * results[]={ |
6 | "A", |
7 | "B", |
8 | "#8-C" |
9 | }; |
10 | int lastValuePointer = 0; |
11 | int loopCount = 0; |
12 | |
13 | void setup() |
14 | { |
15 | Serial.begin(19200); |
16 | delay(100); |
17 | } |
18 | |
19 | void increaseLoopCounter() { |
20 | lastValuePointer++; |
21 | |
22 | int arraySize = sizeof(results)/sizeof(char *); |
23 | |
24 | if(lastValuePointer == arraySize) lastValuePointer = 0; |
25 | |
26 | loopCount++; |
27 | if(loopCount > 8) loopCount = 0; |
28 | } |
29 | |
30 | void loop() |
31 | { |
32 | String valueToCheck; |
33 | if (ledMetro.check() == 1) { |
34 | |
35 | while(true) { |
36 | valueToCheck = results[lastValuePointer]; |
37 | |
38 | if(valueToCheck.indexOf("#") != -1) { |
39 | String repeatIndex = valueToCheck.substring(1, valueToCheck.indexOf("-")); |
40 | String delayedValue = valueToCheck.substring(valueToCheck.indexOf("-") + 1, valueToCheck.length()); |
41 | |
42 | if(loopCount == repeatIndex.toInt()) { |
43 | valueToCheck = delayedValue; |
44 | break; |
45 | } |
46 | |
47 | increaseLoopCounter(); |
48 | continue; |
49 | } |
50 | break; |
51 | } |
52 | |
53 | Serial.println(valueToCheck); |
54 | increaseLoopCounter(); |
55 | } |
56 | |
57 | delay(13); |
58 | } |
Hallo, das sieht alles recht kompliziert und schlecht erweiterbar aus, und dann noch die vielen Stringfunktionen. Mach doch folgendes (hab ich schon für Animationen auf einem Display so ähnlich umgesetzt) lege ein Struct an das folgende Informationen aufnimmt: aktueller Zähler (AZ), Zählerreset (ZR), PTR auf Funktionsaufruf In ein Array legst du nun die Structs die im Programm gerade gebraucht werden. Ausgelöst vom Timer gehst du nun das Array durch und erhöhst (AZ),wenn (AZ) >= (ZR) dann setzt du (AZ) auf null und führst die Funktion aus. Um einen Zeitlichen versatz zu erreichen Initialisierst du halt (AZ) nicht mit null. Würde bei Dir in etwa folgendermaßen aussehen: struct a; 1, 2, *A struct b; 0, 2, *B struct c; 0, 8, *C Was aus deiner Aufgabenstellung nicht klar hervorgeht ist, ob bei Ausführung von C die Bearbeitung von A/B ausgesetzt wird. Sieht in der Tabelle so aus klingt aber im Text nicht so. Dafür könnte man im Struct natürlich noch einen Zähler unterbringen der alle x-Schritte ein Aussetzten der normalen Zählung von (AZ) bewirkt. Die Möglichkeiten sind unbegrenzt. Sascha
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.