2 unabhängige loops erzeugen

Hi zusammen,

für eine Weihnachtsbeleuchtung möchte ich einen Kerzen-Flacker-Algorithmus(verwendet delays) UND zusätzlich einige PWM-Ports ansteuern (auch mit delays).

Wenn alles zusammen in der Loop steht, flackert gar nichts mehr. Die Ports werden zwar ein und ausgeschaltet, aber es liegt an den delays.

Gibt es eine Möglichkeit 2 unabhängige Loops parallel laufen zu lassen, die sich nicht beeinflussen?

int ledPin[] = {
  5, 6, 9, 10, 11};              // pwm pins only
int ledState[5];                 // last state of each led
long randNumber;
int led_lichtsensor = A5;
int lichtstaerke;

int button1State, button2State;  // variables to hold the pushbutton states
int lichtshow_start ;
int led_gr_1 = 22;
int led_gr_2 = 23;
int led_gr_3 = 24;


void setup() 
{  
  pinMode(led_gr_1, OUTPUT);  
  pinMode(led_gr_2, OUTPUT); 
  pinMode(led_gr_3, OUTPUT); 
  pinMode(led_gr_3, OUTPUT); 
   pinMode(A0, OUTPUT); 
  pinMode(led_lichtsensor, INPUT);  
  
  for (int i=0; i<=4; i++){      // set each led pin as an output
    pinMode(ledPin[i], OUTPUT);       
  }
  randomSeed(analogRead(0));     // seed the rnd generator with noise from unused pin

  for (int i=0; i<=4; i++){      // init each led with a random value
    ledState[i] = random(20, 201);
  }
  Serial.begin(9600);
  
  
}

void loop()
{
flackern();
lichtshow();
  
} // of loop





void lichtshow()

{
digitalWrite(led_gr_1,HIGH);
 delay(2000);
digitalWrite(led_gr_2,HIGH);
 delay(2000);
digitalWrite(led_gr_3,HIGH);
delay(10000);
digitalWrite(led_gr_1,LOW);
 delay(2000);
digitalWrite(led_gr_2,LOW);
 delay(2000);
digitalWrite(led_gr_3,LOW);
delay(10000);
}

void flackern()
{
  {     //flackeralgorythmus und lichtsensor
//-----------------------------------------------------------------------------------------------------------------------------------
lichtstaerke=(analogRead(led_lichtsensor));
Serial.println(lichtstaerke);
Serial.println(" ");
if(lichtstaerke >600)
{
for (int i=0; i<=4; i++){                  // for each led:
    analogWrite(ledPin[i], ledState[i]);     // set the pwm value of that pin determined previously
    randNumber = random(-40, 41);            // generate new random number and add that to the current value
    ledState[i] += randNumber;               // that range can be tweaked to change the intensity of the flickering
    if (ledState[i] > 200) {                 // clamp the limits of the pwm values so it remains within
      ledState[i] = 200;                     // a pleasing range as well as the pwm range
    }
    if (ledState[i] < 10) {
      ledState[i] = 10;
    }
  }
  delay(100); }   // the delay between changes
  else 
  {
     for (int i=0; i<=4; i++)
         {      // set each led pin as an output
          digitalWrite(ledPin[i], LOW);       
         } 
  } // of else
  }
}

Gibt es eine Möglichkeit 2 unabhängige Loops parallel laufen zu lassen, die sich nicht beeinflussen?

NEIN gibt es keine. 1 Controller mit 1 CPU und 1 Sketch. Der eine Programmteil nimmt unweigerlich Zeit dem anderen Weg und mit delay() ist es besonders schlimm.

Es gibt einen Ausweg. millis()

Du schaust wieviel Zeit vergangen ist und wenn es soweit ist dann macht Du die Aktion. So kannst Du gleiczeitig blinken und die PWM verändern.

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

Grüße Uwe

Ja, die Delays müssen weg.

Ich verwende manchmal die Protothreads. Vielleicht liegen sie dir ja.....

hi,

etwas wie zwei unabhängige loops. wie Du es meinst, ist kein problem, aber...

ABWECHSELND, das heißt, nicht so, wie Du meinst, also unabhängig.

das wichtige ist, wie gesagt, keine delays, schau Dir das beispiel blinkwithoutdelays in der IDe an, ohne das verstehen dieser sache geht es nicht, mehrere dinge "gleichzeitig" abzuarbeiten. nicht pausensteuern, sondern zeitsteuern!

gruß stefan

Hallo,

mein Grundgerüst, was Du verwenden könntest. Ob es noch einfacher geht weis ich nicht. Damit lasse abwechselnd verschiedene Informationen auf dem Display ausgeben. In dem Fall eine Anzeige für 2sec. und die andere für 8sec.

unsigned long _lastShow_LcdPage_1 = 0;
unsigned long _lastShow_LcdPage_2 = 0;
boolean _status_LcdPage_1 = true;
boolean _status_LcdPage_2 = false;

	
	// Wechsel der LCD Anzeige - Seite 1
    if ( (millis() - _lastShow_LcdPage_1 < 2000) && (_status_LcdPage_1 == true) )  // Seite 1 auf Display für 2sec.
      {
	   sinnvolle Dinge tun ...
       _lastShow_LcdPage_2 = millis();        // setzen der nächsten Eintrittsbedingung
       _status_LcdPage_2 = false;
      }
      else  {    
         _status_LcdPage_2 = true;
        }

    // Wechsel der LCD Anzeige - Seite 2
    if ( (millis() - _lastShow_LcdPage_2 < 8000) && (_status_LcdPage_2 == true) )  // Seite 2 auf Display für 8sec.
      {
       sinnvolle Dinge tun ...
       _lastShow_LcdPage_1 = millis();        // setzen der nächsten Eintrittsbedingung 
       _status_LcdPage_1 = false;
      }
      else  {    
         _status_LcdPage_1 = true;
        }

Wie wäre es mit Interrupts:

https://www.youtube.com/watch?v=TpiDYoif0HY&list=UUOdPZ2MheUfLxJ7zuZWaEuQ&index=34 und http://arduino.cc/en/pmwiki.php?n=Reference/Delay

ist glaube ich das, was du benötigst

Ich glaube, Interrupts sind nicht die Lösung, da in einer Interrupt-Routine auf keinen Fall die bisherige delay-basierte Lösung funktioniert.

Ohne delays geht es natürlich auch ohne Interrupt ;)

Interrupts die Timergesteuert sind funktionieren sicher aber das ist overkill. millis() macht das am einfachsten. Grüße Uwe