Blin­ken­de LEDs mit Multithreading

Lese­zeit: 4 Minu­ten
Navi­ga­ti­on

Als Mul­ti­threa­ding wird die Mög­lich­keit bezeich­net, meh­re­re Threads (Pro­gramm­tei­le) qua­si gleich­zei­tig ablau­fen zu lassen.

Im Pro­gramm sol­len meh­re­re LEDs gleich­zei­tig und in unter­schied­li­chen Rhyth­men blin­ken. Das kann natür­lich mit delay nicht rea­li­siert wer­den, weil delay den Pro­gramm­ab­lauf für die im Para­me­ter bestimm­te Zeit anhält.

Benö­tig­te Bauteile:

  • 5 LEDs
  • 5 Wider­stän­de > 100 Ω
  • Lei­tungs­dräh­te

Baue die Schal­tung auf:
(Fah­re mit der Maus über das Bild, um die Bezeich­nun­gen der Bau­tei­le zu sehen)

Für jede der LEDs ist ein eige­ner Pro­gramm­teil (Thread) ver­ant­wort­lich, die Threads wer­den im loop-Teil nach­ein­an­der aufgerufen.

Mit enum wer­den die LEDs und ihre Ports defi­niert, mit Mini­mum und Maxi­mum wird der Bereich des Blink­in­ter­valls festgelegt:

enum LED
{
  // Startwert Pin 3
  LED_1 = 3,
  LED_2,
  LED_3,
  LED_4,
  LED_5
};

// Zufallsbereich des Blinkintervalls
# define Minimum 200
# define Maximum 2000

Der setup-Teil defi­niert die pin­Mo­des der LEDs und star­tet den Zufallsgenerator.

void setup()
{
  // pinMode festlegen: Startwert LED_1, Endwert  LED_5
  for (int i = LED_1; i <= LED_5; i++)
  {
    pinMode(i, OUTPUT);
  }

  // Zufallsgenerator starten
  randomSeed(analogRead(0));
}

Für jede LED ist ein eige­ner Pro­gramm­teil zuständig:

void LED_1_Blinken()
{
  /* 
    die Variablen sollen den letzten Wert des Aufrufs behalten 
    -> Definition als static
  */
  static bool Zustand = false;

  /* 
    der Rückgabewert von millis() ist unsigned long int
    -> WarteZeit muss ebenfalls den Typ unsigned long int haben
  */
  static unsigned long int WarteZeit = 0;

  // Blinkintervall zufällig ermitteln
  int BlinkIntervall =  random(Minimum, Maximum);

  // wenn Zustand false
  if (!Zustand)
  {
    /* 
     millis() ermittelt die seit Programmstart verstrichene Zeit
     prüfen, ob die Zeit schon abgelaufen ist
     millis() - WarteZeit muss größer als das BlinkIntervall sein
    */
    if (millis() - WarteZeit >= BlinkIntervall)
    {
      digitalWrite(LED_1, HIGH);
      
      // Wartezeit um Blinkintervall erhöhen
      WarteZeit += BlinkIntervall;
      Zustand = !Zustand;
    }
  }

  // wenn Zustand true
  if (Zustand)
  {
    if (millis() - WarteZeit >= BlinkIntervall)
    {
      digitalWrite(LED_1, LOW);
      WarteZeit += BlinkIntervall;

      // Zustand "umdrehen" true -> false, false -> true
      Zustand = !Zustand;
    }
  }
}

Der Pro­gramm­teil wie­der­holt sich für die ande­ren LEDs, es muss nur der Name der LED (LED_2, LED_3 …) aus­ge­tauscht werden.

Im loop-Teil wer­den nach­ein­an­der die Metho­den für die ver­schie­de­nen LEDs aufgerufen:

void loop()
{
  LED_1_Blinken();
  LED_2_Blinken();
  LED_3_Blinken();
  LED_4_Blinken();
  LED_5_Blinken();
}


Ver­wand­te Aufgaben:


Letzte Aktualisierung: 3. Sep 2020 @ 14:22