Ausführen von Funktionen alle x ms

Gast #4156259
Lesenswert?
• ▲
▼
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?
Gast #4156263
Lesenswert?
• ▲
▼
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
Gast #4156265
Lesenswert?
• ▲
▼
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.
Gast #4156266
Lesenswert?
• ▲
▼
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.
Gast #4156283
Lesenswert?
• ▲
▼
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
}
#4156341
Lesenswert?
• ▲
▼
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

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.