Tasks zyklisch aufrufen

Hallo

Ich bin daran eine aufgabe mit einem Arduino Uno zu lösen.
Ich habe eine CNC Maschine gekauft mit defekter Steuerung. Die Steuerung ist bereits entsorgt und nun muss Ersatz her. Die Maschine selbst wird über einen PC mit EMC2 gesteuert. Für die Steuerung von einigen Zusatzfunktionen möchte ich ein Arduino Uno hernehmen.
Da muss ich bspw einige Endschalter abfragen, ein paar Magnetventile und Spulen ansteuern und einen Asynchronmotor (400V Drehstrom ein und ausschalten)
Die Leistungstreiber sollen mit Triacs und Optomos bzw Fets und Freilaufdioden etc realisiert werden.
Soweit so gut.

Ich hab mit dem Uno schon ein paar Abende rumgespielt. das Funzt soweit schon einigermassen.
Für mein Projekt suche ich nun ein Konstrukt für mein neues Programm.
Ich habe mir vorgestellt dass ich einen Timer interrupt habe der Zyklisch einige Funktionen aufruft. So dass ich bswp alle 20ms (ist das realistisch?) jede Funktion aufrufe und diese wieder verlasse wenn sie abgearbeitet ist. delays etc möchte ich so realisieren dass wenn z.b eine funktion das 50te mal aufgerufen wurde, dann weiss ich jetzt ist eine sekunde um.

macht das sinn? wie stelle ich sowas an?

gruss
siegi

Schau dir mal das Blink Beispiel aus dem Tutorialbereich an welches man hier als Muster nehmen kann.

Die Variable interval definiert die Intervallzeit.

Code angepasst:

 http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
 */

// Variables will change:
// will store last time LED was updated
long previousMillis = 0;       
// will store last time LED was updated
long interval = 1000;

void setup() {
  // Eingänge und Ausgänge setzen
  // ...
}

void loop()
{
  // dieser Code wird bei jedem Loop ausgeführt
  // ...

  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;  
    
   // Anweisungen, welche jeweils pro Intervall ausgeführt werden
   // ....

  }
}

was passiert wenn meine maschine >9h eingeschaltet ist?
dann gibts durch den überlauf ein problem?

gruss
siegi

was meint ihr zu meinem aktuellen versuch?

#include <MsTimer2.h>

void task1() {
  static boolean output = HIGH; //Variables declared as static will only be created and initialized the first time a function is called. 

  digitalWrite(13, output);
  output = !output;
}

void task2() {
  static boolean output = HIGH; //Variables declared as static will only be created and initialized the first time a function is called. 
  
  digitalWrite(01, output);
  output = !output;
}

void task3() {
  static boolean output = HIGH; //Variables declared as static will only be created and initialized the first time a function is called. 
  
  digitalWrite(02, output);
  output = !output;
}

void task4() {
  static boolean output = HIGH; //Variables declared as static will only be created and initialized the first time a function is called. 
  
  digitalWrite(00, output);
  output = !output;
}

void setup() {
  pinMode(13, OUTPUT);
  pinMode(00, OUTPUT);
  pinMode(01, OUTPUT); 
  pinMode(02, OUTPUT);  
  MsTimer2::set(20, ms_task); // 20ms period
  MsTimer2::start();
}

void ms_task() {

  task1();
  task2(); 
  task3(); 
  task4();
}

void loop() {
}

ps: we kann ich hier vernünftig code posten?

Hallo trilobyte,

über diese Timerfunktion handhabe ich solche Sachen auch, aber ich möchte es, wenn ich mal Zeit habe, nicht mit einen internen Timer, sondern ein RTC-Modul realisieren, da diese Methode viel genauer ist.
Falls du unterschiedlichen Timerfunktionen haben willst, könntest du dies mit Laufvariablen handhaben, die hochzählen, per if-Anweisung abfragen und dann wieder zurücksetzen.

Codeabschnitte kannst du über das Icon: # umsetzen.

@trilobyte
Dein Lösungsansatz ist in diesem Fall definitiv sicherer. Die Problematik eines Überlaufs ist bei einer Maschinensteuerung nicht wirklich optimal.

Ein weiterer Lösungsansatz wäre ein externer Timer, welcher jeweils einen externen Interrupt auslöst. Dieser Interrupt wird über die Anweisung attachInterrupt() abgefragt. Bei Empfang eines Interrupt wird dann die Ausführung deiner verschiedenen Tasks angestossen.

http://www.arduino.cc/en/Reference/AttachInterrupt

Nachteil dieser Lösung ist die Tatsache, dass noch eine externe Timerelektronik nötig ist. :frowning:

Das kann Dir nicht helfen:
http://www.arduino.cc/playground/Code/Metro

Ansonsten wie bereits gesagt externer Taktgenerator auf Interrupt oder durch internen Interrupt via Timer

Den Asynchronmotor würde ich mit einem Schütz schalten.

Grüße Uwe