Multitasking mit dem Arduino Uno?

Hallo zusammen,
bin neu hier im Forum und lerne gerade fleißig mit dem Arduino Uno Dinge zu machen.
Jetzt möchte ich eine kleine Schutzschaltung bauen, aber benötige dafür doch noch eure Hilfe.

Zur Schaltung selber:
3 Ultraschallsensoren, um einen Abstand zu messen
1 Strommessgerät, um einen Strom zu messen (entweder 0A oder 4A, mehr nicht)

Wenn die 4A anliegen, müssen die drei Ultraschallsensoren nacheinander in regelmäßigen Zeitintervallen, jew. eine Veränderung des Abstandes messen.

Sobald die 4A anliegen, aber die Sensoren keine regelmäßige veränderung registrieren, muss zB. eine Led leuchten.

Wie programiere ich dieses "Multitasking" mit dem Strommessgerät und den Ultraschallsensoren?

Danke und mfG

Nudelkopf33

Nudelkopf33:
... Wie programiere ich dieses "Multitasking" ...

Meiner Meinung nach am besten mit einem „endlichen Automaten“.

Was mir dazu eingefallen ist steht hier.. Sehr gut finde ich die Nachtwächter-Erklärung.

Gruß

Gregor

Ablaufsteuerung
Meine Standardantwort zu Ablaufsteuerungen:

Eine Stichworte Sammlung für Google Suchen:
Endlicher Automat,
State Machine,
Multitasking,
Coroutinen,
Ablaufsteuerung,
Schrittkette,
BlinkWithoutDelay,

Blink Without Delay
Der Wachmann

Multitasking Macros
Intervall Macro

Echtes Multitasking gibt es auf dem Arduino nicht.
Du kannst aber die Aufgaben so schnell hintereinander ausführen lassen, dass es Dir wie gleichzeitig erscheint.
Alle Aufgaben werden dann nacheinander im Loop aufgerufen. Dabei darf keine Aufgabe den Loop lange blockieren, d.h. delay und alle Arten von Schleifen (for, while, do) sind tabu.

Schau Dir in der IDE das Beispiel BlinkWithoutDelay an und verstehe, wie es funktioniert. Evtl. hilft Dir beim Verständnis die Nachtwächtererklärung.

Gruß Tommy

Dabei darf keine Aufgabe den Loop lange blockieren, d.h. delay und alle Arten von Schleifen (for, while, do) sind tabu.

Zu absolut, aus meiner bescheidenen Sicht.

Wobei ich allerdings zugeben muss, dass ich selber mal diese Sicht vertreten habe.
Aber das Buch ist zu! (für mich)

Nachtrag, der Gegenbeweis für das Tabu:

  1. Drei Endlosschleifen
  2. Zwei fette Delay in loop()
  3. Von 1 und 2 völlig ungestörtes, kooperatives, Multitasking
#include <TaskMacro.h>
// siehe: https://forum.arduino.cc/index.php?topic=415229.0

unsigned long loopcount  = 0;
unsigned long yieldcount = 0;


void printCount()  // User Task
{
  taskBegin();
  while(1)
  {
    taskPause(1000); // jede Sekunde  
    Serial.print("Loop: ");    
    Serial.print(loopcount);    
    Serial.print("    Yield: ");    
    Serial.print(yieldcount);    
    Serial.println();
  }  
  taskEnd();
}

void printA() // User Task
{
  taskBegin();
  while(1)
  {
    taskPause(5000); // alle 5 Sekunden   
    Serial.println("A");
  }  
  taskEnd();
}



// hier alle Tasks, gefolgt von einem taskSwitch() eintragen
// alternativ, ein Array verwenden
void scheduler() //  Scheduler
{
  taskBegin();
  while(1)
  {
    printCount();
    taskSwitch();
    printA();
    taskSwitch();
  }  
  taskEnd();
}

void yield() // wird im Delay aufgerufen
{
    static bool reentranceFlag = true;
    yieldcount++;
    if(reentranceFlag)  
    {
      reentranceFlag = false; // zirkulaere Aufrufe unterdruecken
      scheduler();    
      reentranceFlag = true;
    }
}

void setup() 
{
  Serial.begin(9600);
  Serial.println();
  Serial.println("Start");
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() 
{
  loopcount++;
  digitalWrite(LED_BUILTIN, HIGH);   
  delay(1000);                      
  digitalWrite(LED_BUILTIN, LOW);   
  delay(1000);                       
}

Deine Taskmakros "schummeln" sich ja an diesen Regeln vorbei, indem sie diese Sachen aufbrechen.
Ob das dem TO beim Verständnis hilft?

Gruß Tommy

diese Sachen

Delay wird nicht aufgebrochen.
Das wird so von Arduino mitgeliefert.

Die aufgebrochenen Schleifen, lassen sich auch bequem durch (computed) Gotos ersetzen.
(wirds aber nicht schöner durch)

Übrigens:
Ein preemtives Multitaskíng würde die Schleifen ebenfalls aufbrechen, nur auf andere Art.
Endlosschleifen sind ein quasi ein MUSS.
Weder ein normales Arduinoprogramm kommt ohne aus (eine muss wohl sein), noch ein preemtives Multitaskíng System (für jede Task eine).

Ob das dem TO beim Verständnis hilft?

Ob es wohl irgendwem hilft ein Tabu Dogma aufzustellen, welches so leicht widerlegt werden kann?
:grin: :grin: :grin:

Ich finde der geneigte Leser darf das mitnehmen, was er möchte, und gerne den Rest ausblenden.

Es stellt keiner Tabus auf, auch wenn Du das gern so darstellst.

Fakt ist nunmal, dass delay und schleiben ohne besondere Maßnahmen sich im loop nicht gerade förderlich auf die guasiparallele Verarbeitung auswirken.

Wir können natürlich festlegen, dass den Anfängern nur noch Dein Taskmodell angeboten wird und wir die von Dir kritisierten "Tabus" weglassen.

Das dürfte die Anzahl der Postings und Poster dann stark vermindern.

Gruß Tommy

Es stellt keiner Tabus auf,

alle Arten von Schleifen (for, while, do) sind tabu.

Dann hast du das nicht aufgestellt, sondern das ist einfach eins, so ganz ohne Aufstellung.
:sunglasses: So ein prinzipielles... :sunglasses:
Ein unabwendbares...

Genau so wenig, wie du zu bestimmen hast, ob jemand Schleifen und Delay verwendet, möchte ich meine TaskMacros durch drücken.
:smiling_imp: Klaro? :smiling_imp:

Du kannst von mir aus auf deinen Dogmen beharren...
Aber wenn du glaubst, das es die einzige Wahrheit ist, dann bist du schief gewickelt.
Sorry, dass ich dir das so sage....

Ok, ok .... (aktiver Rückzug)
Vielleicht springe ich auf "Tabus" etwas scharf an.
Vielleicht hast du den Begriff "Tabu" etwas leichtfertig verwendet.

Ok, Tabu war evtl. zu hart formuliert.

Deine Task-Makros finde ich persönlich sehr gut aber nicht unbedingt für Anfänger geeignet. Da dürfte dann eher ein Copy & paste, anstelle von Verständnis entstehen.

Ich denke, wir haben beide etwas überreagiert.

Gruß Tommy

Da dürfte dann eher ein Copy & paste, anstelle von Verständnis entstehen.

Mag sein, bei dem einen, oder anderen....

Aber genauso gut, mag bei dem einen, oder anderen, ein tiefes Verständnis von/über Nebenläufigkeiten entstehen.

Ich traue mich das nicht im Vorfeld zu beurteilen.

Schon gar nicht, weil evtl. hunderte diesen Thread lesen.
Und ich eigentlich keinen davon kenne.

Ein Multitasking führt Code ein, der den Arduino beschäftigt (Overlay).

Ein Sketch der so geschrieben ist, daß die verschiedenen Abläufe genügend flüssig nacheinander abarbeiten, ist meiner Ansicht nach schlanker.

Ich sehe für viele Sketche die einige Sachen "gleichzeitig" machen nicht die Notwendigkeit ein Multitasking aufzusetzen.

Grüße Uwe

Ich sehe für viele Sketche die einige Sachen "gleichzeitig" machen nicht die Notwendigkeit ein Multitasking aufzusetzen.

Ich dagegen, glaube, dass jede Art von Nebenläufigkeit ein verkapptes "Multitasking" ist.
Wie man es genau ausformuliert, oder welche Helferlein man sich dazu holt ist da eher zweitrangig.

Genau so ist jedes (funktionierende) Arduino Programm im Endeffekt (mindestens) ein endlicher Automat.
Egal ob man ein bewährtes Design Pattern verwendet, oder da einen verworrenen ausschauenden Code hinschreibt.
Ausnahmen sind sicher selten.

Die Frage ist also nicht so sehr, ob man Multitasking einsetzt, sondern ob man es dann auch so nennt.
Oder auch, ob es in dem Code übersichtlich zu geht.
Da hilft einem(mir) die Sicht auf die Task. Die zwingt mich das zusammen zu halten, was zusammen gehört.
Klare Schnittstellen zu schaffen.
Leichte Wiederverwendbarkeit.

Hi,

danke für Eure schnellen Antworten. Bis ich das alles Verstanden habe dauerts kurz bei mir :o

Tommy56:
Alle Aufgaben werden dann nacheinander im Loop aufgerufen. Dabei darf keine Aufgabe den Loop lange blockieren, d.h. delay und alle Arten von Schleifen (for, while, do) sind tabu.

Das stimmt nicht ganz. Die übliche Auswertung der Ultraschallsensoren basiert auf blockierendem Code. Dieser hällt alllerdings nur für wenige Millisekunden den Arduino an. Auch muss man Pausen zwischen den US-Sensoren machen, damit sie sich nicht gegenseitig stören. Es kann sonst der eine Echos des anderen auffangen.

Ich würde auf dieses Multitasking verzichten und alles in eine Loop-Schreiben. Im Zweifelsfall stört es die Auswertung der Ultraschallsensoren, wenn im flaschen Moment der Task ausgelöst wird.

Im Zweifelsfall stört es die Auswertung der Ultraschallsensoren, wenn im falschen Moment der Task ausgelöst wird.

Und in einem anderen Zweifel stört es die restlichen Abläufe, wenn die eine Sensorabhandlung blockiert.
Naja...
So ist das dann...

Spannend wird es immer bei mehreren zeitkritischen Abläufen, welche quasi parallel ablaufen sollen.

und alles in eine Loop-Schreiben.

Kann man machen, aber übersichtlich muss das Ergebnis dann nicht sein.

Nudelkopf33:
Bis ich das alles Verstanden habe dauerts kurz bei mir :o

Wir haben das ja schon von langer Hand vorbereitet und nur darauf gewartet einen passenden Tread zu finden um es loszuwerden. :wink: :wink: :wink: :wink: :smiley: :smiley:
Da sind wir klar im Vorteil :wink: :wink:
Grüße Uwe

combie:
Delay wird nicht aufgebrochen.
Das wird so von Arduino mitgeliefert

Solange yield nicht dokumentiert ist und z.B. hier nicht erwähnt wird, würde ich nicht von "mitgeliefert" sprechen. Und Neulingen zuerst BlinkWithoutDelay ans Herz legen. Wenn man dann deine TaskMakros versteht und sieht, wie diese die Aufgabe "preemptives Multitasking" lösen, kann man sie immer noch ganz toll finden.

Mehrere Ultraschallsensoren lassen sich schon aus akustischen Gründen in der Regel nicht wirklich "unsynchronisiert gleichzeitig" verwenden. Ist aber auch normalerweise (insbesondere hier) nicht nötig.

Und dass man delay(1000) durch andere Konstruktionen ersetzen sollte, wenn man einen "echtzeitfähigen Sketch" braucht, halte ich immer noch für den richtigen Tip für Neulinge.

Mehrere Ultraschallsensoren lassen sich schon aus akustischen Gründen in der Regel nicht wirklich “unsynchronisiert gleichzeitig” verwenden. Ist aber auch normalerweise (insbesondere hier) nicht nötig.

Man muss aber auch nicht den Rest des Programms deswegen blockieren!

Solange yield nicht dokumentiert ist und z.B. hier nicht erwähnt wird, würde ich nicht von “mitgeliefert” sprechen.

Das AGR Ventil deines Autos ist auch nicht in der Bedienungsanleitung erwähnt!
Aber doch gehört es zur Lieferung, wenn dir der Hersteller/Händler das Auto vor die Tür stellt.
Yield() gehört zum Lieferumfang, ob dir das passt oder nicht.
Es ist mir egal, ob dir das passt, und den ganzen Arduinos auch.

Natürlich kann man alles ausblenden, was nicht in der fürchterlich schwachen Arduino Doku steht.
Nur wird dann dein Programm genauso schwach.
Behauptung: Nur ein Dummkopf lasst sich von einer unvollständigen Doku ausbremsen.
Denn: Mit Aufmerksamkeit und Intelligenz lassen sich viele dieser Hürden umschiffen, Lücken füllen.
Klar ist es ein langer Weg, bis dahin…
Aber das kann doch kein Grund sein diese Features vor den Anfängern zu verbergen, oder?
Gibt es irgendeinen Grund, zu versuchen, Anfänger dumm zu halten?
Ist es nicht das genaue Gegenteil, des Sinn und Zweck, dieses Forums?

Nehmen wir mal deine heiß geliebten Ultraschallsensoren.
Quasi überall findet man pulseIn(). In nahezu jeder Lib.
Ist es dann nicht logisch, dass z.B. ein Balancer Robot, stumpf auf die Fresse fällt, oder zumindest derbe wackelt, wenn man auf den eingetretenen Pfaden bleibt?

Und Neulingen zuerst BlinkWithoutDelay ans Herz legen.

Diese Kritik kann ich nicht annehmen!
Du kritisierst Dinge, welche du dir selber ausgedacht hast.
Siehe Posting #2
BlinkWithoutDelay steht in meiner kleinen Linkliste ganz weit vorn.
Warum wohl?
Manno!

Wenn man dann deine TaskMakros versteht und sieht, wie diese die Aufgabe “preemptives Multitasking” lösen, kann man sie immer noch ganz toll finden.

Ist mir egal, wie das einer findet.
Wenns ihm gefällt, dann los, wenn nicht, dann nicht…

Den Code habe ich nur gepostet, weil Tommy56 da ein unsinniges, zumindest in der Absolutheit unsinniges, Dogma aufgestellt hat. Vor Schleifen und Delays zu warnen, finde ich völlig ok. Ist auch mein täglich Geschäft.
Aber da ein Tabu draus zu formen geht (mir) zu weit.
Tommy56 hats begriffen.
Bei dir dauert es noch…

So…
Die Eingangsfrage lautet:

Topic: Multitasking mit dem Arduino Uno?

Und du möchtest jetzt ernsthaft behaupten, dass meine TaskMacros in diesem Thread falsch untergebracht sind, habe ich dich da richtig verstanden?

Und dass man delay(1000) durch andere Konstruktionen ersetzen sollte, wenn man einen “echtzeitfähigen Sketch” braucht, halte ich immer noch für den richtigen Tip für Neulinge.

Der Tipp, ist auch völlig in Ordnung.
Aber es ist nicht die einzige Lösung.