Zwei loops

Hallo alle zusammen,

ich arbeite erst seit kurzem mit dem Arduino und versuche gerade folgendes zu bewerkstelligen: Ich möchte auf dem Arduino UNO Daten speichern (auf SD) und zu einem späteren Zeitpunkt davon abspielen. Beide Sketche habe ich zu einem guten Stück fertig. Über zwei unterschiedliche Buttons möchte ich die zwei Modi aufrufen, quasi REC und PLAY; beide Sketche sind etwas umfangreicher. Im REC Modus kann/soll der PLAY Modus völlig ausgeschaltet sein und viceversa, man soll nicht im laufenden Prozess umschalten können. Ich versuche es gerade mit interrupts, aber ich stelle mir eher zwei loops vor, zwischen denen ich einfach per Schalter am Anfang auswählen kann und dann läuft einer bis man ausschaltet... wenn ich es richtig verstehe, wird ja "loop" durch interrupts lediglich unterbrochen?

Ich habe gesehen, das der DUE mehrere loops parallel aufrufen kann http://arduino.cc/en/Tutorial/MultipleBlinks? Hat jemand Erfahrung damit? Oder vielleicht eine andere Idee, die nicht tief in C reingeht? Wie gesagt, ich kenne eine ganze Menge Befehle noch gar nicht....

Ich arbeite mit einem arduino Uno/R3 und Software 1.0.6 an einem Mac.

1000 Dank für Ideen, links oder Stichwörter!!!
Viele Grüße

Die denkst viel zu kompliziert. Einfach zwei verschiedene Funktion aufrufen, je nachdem in welchem Modus man ist.

loop()
{
  if(digitalRead(playtaste)) mode = 1;
  if(digitalRead(rectaste)) mode = 2;
  if(mode == 1)
    {
    playsketch
    }
  if(mode == 2)
    {
    recsketch
    }
}

Grüße Uwe

Ich habe gesehen, das der DUE mehrere loops parallel aufrufen kann

Das tut aber gar nicht das, was du willst.
Es lässt 3 Tasks parallel laufen, quasi gleichzeitig.

wenn ich es richtig verstehe, wird ja “loop” durch interrupts lediglich unterbrochen?

Dem ist wohl so!

Es hat Nachteile, wenn man in Loop() eigene lang laufende Schleifen unterbringt. z.B. tuts das Serial Dingen dann nicht mehr so schön, denn Arduino erledigt in der Systemecke noch was…

Hallo zusammen,

vielen Dank für Eure guten Kommentare und Danke Uwe für diese gute Basis! Und ja, ich sehe, ich habe etwas zu kompliziert gedacht... ::slight_smile:

Das tut aber gar nicht das, was du willst.
Es lässt 3 Tasks parallel laufen, quasi gleichzeitig.

...ich dachte, vielleicht kann man einfach einen loop aufrufen und die anderen anhalten... daher der Gedanke. Von den interrupts bin ich weg, da ich gerade auf RX/TX angewiesen bin.

Ich poste mal beispielhaft den reduzierten Sketch (LED´s blinken). Über die while Schleifen bleibe ich im Modus den ich am Anfang auswähle, das ist super, denn ich möchte nicht aus versehen in einen anderen Modus.
"mode = 3" soll ausschließlich laufen, wenn "RECmodus", also "mode=2" läuft und an/ausschaltbar sein... da stecke ich im Moment fest.... habe es mit if/else versucht, aber noch nichts herausgefunden. 1000 Dank für einen kleinen Hinweis!
Viele Grüße
Jan

const int LEDgruen = 9;
const int LEDgelb = 10;
const int LEDrot = 11;

const int PLAYmodus = 2;
const int RECmodus = 3;
const int RECaktiv = 4;

int mode;

void setup(){
  
  pinMode(9, OUTPUT);   // LED gruen
  pinMode(10, OUTPUT);  // LED gelb
  pinMode(11, OUTPUT);  // LED rot
  
  pinMode(2, INPUT);    // Schalter für LED gruen
  pinMode(3, INPUT);    // Schalter für LED gelb
  pinMode(4, INPUT);    // Schalter für LED rot
  
}

void loop()
{
  if(digitalRead(PLAYmodus)) mode = 1;
  if(digitalRead(RECmodus)) mode = 2;
  if(digitalRead(RECaktiv)) mode = 3;
  
  
  while(mode == 1)                       // PLAY modus
  {   
      digitalWrite(LEDgruen, HIGH);
      delay(100);
      digitalWrite(LEDgruen, LOW);
      delay(100);  
  }
   
 
    
  while(mode == 2)                        // REC modus
  { 
      digitalWrite(LEDgelb, HIGH);
      delay(200);
      digitalWrite(LEDgelb, LOW);
      delay(200);    
  }
 

                         
   while(mode == 3)                      // REC aktiv
    {
      digitalWrite(LEDrot, HIGH);
      delay(300);
      digitalWrite(LEDrot, LOW);
      delay(300);
    } 
}

So?

Keine Schleifen, kein Delay.
Aber ob schön, das dürfen gerne andere beurteilen ....

struct Blink
{
    bool state;
    byte pin;
    unsigned long lastHit;
    unsigned long interval;
    bool running;
  
  Blink(byte ledpin,  unsigned long blinkinterval)
  {
    pin     = ledpin;
    lastHit = millis();
    state   = false;
    interval = blinkinterval;
    pinMode(pin,OUTPUT); 
  }
  
   void handle()
  {
    if(running)
    {
      if(millis() - lastHit > interval)
      {
        state = ! state;
        digitalWrite(pin,state);
        lastHit = millis();
      }
    }else
    {
        digitalWrite(pin,LOW);
    }
  }

};





const int PLAYmodus = 2;
const int RECmodus = 3;
const int RECaktiv = 4;

Blink LEDgruen(9,100);
Blink LEDgelb(10,200);
Blink LEDrot(11,300);

void setup()
{
  pinMode(2, INPUT);    // Schalter für LED gruen
  pinMode(3, INPUT);    // Schalter für LED gelb
  pinMode(4, INPUT);    // Schalter für LED rot
}

void loop()
{
   LEDgruen.handle();
   LEDgelb.handle();
   LEDrot.handle();

// Taster/Schalter entprellung fehlt noch 
   LEDgruen.running = digitalRead(PLAYmodus) && !LEDgelb.running;
   LEDgelb.running  = digitalRead(RECmodus)  && !LEDgruen.running;
   LEDrot.running   = digitalRead(RECaktiv)  &&  LEDgelb.running;
}

nicht wirklich getestet
Aber so, oder so ähnlich könnte es gehen.

Wenn grün blinkt kann gelb nicht aktiviert werden.
Wenn gelb blinkt kann grün nicht aktiviert werden.
Wenn gelb blinkt kann rot aktiviert werden.

Wow, vielen Dank für das feedback combie! Ich versuche mich mal daran. Taster entprellen habe ich hardware mäßig geplant. Nur zum Verständnis, "delay" ist ja auch eine Art interrupt? Sind Sketches mit Delays und Schleifen (z.B. über while) innerhalb des Mainloops in puncto langes fehlerfreies Laufen "störungsanfälliger"? Ich versuche die Sache nicht unbedingt elegant zu lösen, aber solide laufen sollte es schon, REC vielleicht ein paar Tage durch und Play einen Tag. Vielen Dank und Grüße!
Jan

Nur zum Verständnis, "delay" ist ja auch eine Art interrupt?

Der Vergleich ist so dermaßen falsch, dass noch nicht mal das Gegenteil richtig ist!
:smiley: :smiley:
Interrupt == Unterbrechung
Delay == Blockade
(wobei ein Interrupt durchaus ein delay() unterbrechen kann, aber das delay() macht nach der Unterbrechung unverdrossen weiter seinen Job)

Sind Sketches mit Delays und Schleifen (z.B. über while) innerhalb des Mainloops in puncto langes fehlerfreies Laufen "störungsanfälliger"?

Da Arduino noch Gedöns in der Systemecke erledigt, und du mit eigenen (langlaufenden) Schleifen in Loop() das Gedöns verhinderst, kannst du dir Probleme einhandeln.
Also Ja!
Du kaufst dir ein Problem ein.

Trage Sorge, dass nichts blockiert.
Also, dass die loop() Funktion möglichst schnell/häufig durchlaufen wird.

Schleifen und (micro)Dalays sind manchmal unumgänglich.
Beschränke diese auf genau diese seltenen Fälle.
Alles andere bringt dich in des Teufels Küche.

Aber mit "störungsanfälliger" hat auch das nichts zu tun.

Nachtrag zu "störungsanfälliger":

"Störung" == Dehnbarer Begriff

Brownout ist meist sowieso schon aktiviert.

Alle AVR Arduinos haben Watchdog Timer.
Wenn man vor Ausfällen Angst hat kann man den aktivieren.
Ein übliches Vorgehen ist: Den Watchdog auf die maximal zu erwartende loop() Laufzeit einzustellen (nagut, etwas mehr).
Und in in jedem loop() anzustoßen.
Wobei es dann klug wäre, die maximal zu erwartende loop() Laufzeit, möglichst klein zu halten. z.B. wenige Millisekunden.

Und wenn sichs um einen geordneten Wiederanlauf nach einer Störung/Stromausfall dreht, dann haben eigentlich alle RTCs ein kleines NVRam, in dem man den aktuellen Zustand halten kann.

Also:
Welche "Störungen" erwartest du?
:smiley: sind delays() und while(1); auch Störungen? :smiley:

Danke combie für Deinen Sketch, er funktioniert super! Will nur schauen, dass Playmodus(LEDgrün) bzw. RECmodus(LEDgelb) einmal ausgewählt, nicht mehr abschaltbar sind und der ausgewählte Modus dann läuft, bis man das Gerät ausschaltet. RECschalter(LEDrot) soll an und ausschaltbar sein, so wie es bei Dir ist. Wie gesagt, die LEDs sind nur Platzhalter in meinem Sketch für längere Sachen, zum einen auf SD-Karte speichern(RECmodus) um dann im PLAYmodus die Daten von SD über einen digital Pin auszugeben.

Mit Störung meine ich, bis zu welchem Maße sich das Risiko beim Daten speichern auf SD oder Daten lesen von SD für ein mögliches "Aufhängen/Ausfall" minimieren lässt und ob eine while(){}, für die es keine Anweisung gibt, wieder in den loop() zurückzukehren für Störungen quasi prädestiniert ist ...verstehe schon, dass es natürlich auch von den Funktionen abhängt. Ich verwende im allgemeinen in den Funktionen sehr kurze delay(), wie delay(2)...

const int LEDgruen = 9;
const int LEDgelb = 10;
const int LEDrot = 11;

const int PLAYmodus = 2;
const int RECmodus = 3;
const int RECaktiv = 4;

int mode;
int SchalterREC;

void setup(){
  
  pinMode(9, OUTPUT);   // LED gruen
  pinMode(10, OUTPUT);  // LED gelb
  pinMode(11, OUTPUT);  // LED rot
  
  pinMode(2, INPUT);    // Schalter für LED gruen
  pinMode(3, INPUT);    // Schalter für LED gelb
  pinMode(4, INPUT);    // Schalter für LED rot
  
}

void loop()
{
  if(digitalRead(PLAYmodus)) mode = 1;
  if(digitalRead(RECmodus)) mode = 2;
  
  
  
  while(mode == 1)                       // PLAY modus
  {   
      digitalWrite(LEDgruen, HIGH);
      delay(200);
      digitalWrite(LEDgruen, LOW);
      delay(200);  
  }
   
 
    
  while(mode == 2)                        // REC modus
  { 
      digitalWrite(LEDgelb, HIGH);
      delay(50);
      digitalWrite(LEDgelb, LOW);
      delay(50); 
        if(digitalRead(RECmodus == HIGH))         // SchalterREC
        {
          SchalterREC = digitalRead(RECaktiv);
          if (SchalterREC == HIGH) 
          {     
            digitalWrite(LEDrot, HIGH);  
          } 
          else 
          {
            digitalWrite(LEDrot, LOW); 
          }
        }
  }
 

   
}

Das Sketch funktioniert so mit den LEDs prima und macht genau das, was ich brauche, habe aber noch nicht die eigentlichen Funktionen darin getestet, und nach Deinen Anregungen könnten mir ja die 2 while() Schleifen Probleme bereiten... Für mich ist es leicht, dort die eigentlichen 2 Funktionen einfach einzusetzen... aber ich forsche mal weiter und schaue mir Deinen Sketch genauer an...der sieht für mich deutlich eleganter aus :wink: