Blin­ken­de LEDs mit Multithreading

Lese­zeit: 4 Minu­ten

Lösung
Seite als PDF

Als Mul­ti­th­re­a­ding wird die Mög­lich­keit bezeich­net, meh­re­re Threads (Pro­gramm­tei­le) schein­bar 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
  • 3 Wider­stän­de 220 Ω (gel­be, rote und grü­ne LED)
  • 2 Wider­stän­de 100 Ω (blaue und wei­ße LED)
  • Lei­tungs­dräh­te

Beach­te die ➨Vor­wi­der­stän­de ver­schie­de­ner LEDs

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 set­up-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(A0));
}

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 Funk­ti­on (LED_2_Blinken, LED_3_Blinken ...) und die Bezeich­nung der LED (LED_2, LED_3 …) aus­ge­tauscht werden.

Im loop-Teil wer­den nach­ein­an­der die Funk­tio­nen 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();
}

Startseite
Aufgaben A-Z
Suchen
Downloads
Fehlermeldungen
Seite als PDF

Ver­wand­te Aufgaben:


Letzte Aktualisierung: 18. Apr 2024 @ 9:17