Laby­rinth-Spiel TFT Fernbedienung

#include "IRremote.hpp"
int EmpfaengerPin = 11;

#include "Adafruit_GFX.h"
#include "Adafruit_ST7735.h"

/*
  Arduino
  SCK  13
  RST   9
  DC    8
  CS   10
  COPI 11
*/
#define TFT_CS        10
#define TFT_RST        9
#define TFT_DC         8

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

/*
  Farben als hexadezimal definiert
  alternativ:
  int SCHWARZ = 0;
  int FARBE = 15;
  . . .
*/
// Farben
#define SCHWARZ 0x0000     // dezimal 0
#define BLAU 0x000F        // dezimal 15
#define ROT 0xF800         // dezimal 63488
#define GRUEN 0x0E81       // dezimal 3713
#define CYAN 0x07FF        // dezimal 2047
#define MAGENTA 0xF81F     // dezimal 63519
#define GELB 0xAFE5        // dezimal 65504
#define WEISS 0xFFFF       // dezimal 65535
#define BRAUN 0xFC00       // dezimal 64512
#define GRAU 0xF7F0        // dezimal 63472
#define GRUENGELB 0xAFE5   // dezimal 45029
#define DUNKELCYAN 0x03EF  // dezimal 1007
#define ORANGE 0xFD20      // dezimal 64800
#define PINK 0xFC18        // dezimal 64536

// Farbe der Blöcke
#define FARBE GRUEN

// Farbe des Kreises
#define KREISFARBE ROT

// Farbe der Schrift
#define SCHRIFTFARBE WEISS

// Spiel starten wenn * gedrückt wurde
bool SpielStart = false;

const int Radius = 10;
const int Abstand = Radius * 2;

// je höher, dest langsamer
const int Geschwindigkeit = 100;

// Bewegung des Kreises in Pixeln
const int Bewegung = 5;

// Startposition des Kreises
int CursorX = Radius;
int CursorY = tft.height() / 2 - Abstand;

// Variable für die Zeitmessung
long Start;

void setup() 
{
  // Startbildschirm
  // schwarzes Farbschema horizontale Ausrichtung
  // Cursor setzen, Schriftgröße und -farbe definieren
  tft.initR(INITR_BLACKTAB);
  tft.setRotation(0);
  tft.fillScreen(SCHWARZ);
  tft.setTextSize(2);
  tft.setCursor(1, 10);
  tft.setTextColor(SCHRIFTFARBE);

  tft.println("Start:");
  tft.print("-> *");
  Serial.begin(9600);
  IrReceiver.begin(EmpfaengerPin);
}

void loop() 
{
  // nur ausführen, wenn SpielStart true
  if (IrReceiver.decode() && !SpielStart) 
  {
    delay(200);

    // nächsten Wert lesen
    IrReceiver.resume();

    // Start mit *
    if (IrReceiver.decodedIRData.command == 66) 
    {
      // Spiel wird gestartet
      SpielStart = true;

      // Parcours bauen
      ParcoursBauen();

      // Zeitmessung starten
      Start = millis();
    }
  }

  // wenn die Taste * gedrückt wurde
  if (SpielStart) 
  {
    if (IrReceiver.decode()) 
    {
      // nächsten Wert lesen
      IrReceiver.resume();

      // OK -> Bewegung anhalten
      if (IrReceiver.decodedIRData.command == 64) 
      {
        // Kreis an der aktuellen Position anhalten
        tft.fillCircle(CursorX, CursorY, Radius, KREISFARBE);
      }

      // nach oben
      if (IrReceiver.decodedIRData.command == 0x46) 
      {
        // Kreis an der aktuellen Position "löschen"
        tft.fillCircle(CursorX, CursorY, Radius, SCHWARZ);

        // wenn der Bildschirmrand noch nicht erreicht wurde
        // rückwärts (Richtung x = 1) bewegen
        if (CursorY > Radius) CursorY -= Bewegung;
        tft.fillCircle(CursorX, CursorY, Radius, KREISFARBE);
        delay(Geschwindigkeit);
      }

      // nach unten
      if (IrReceiver.decodedIRData.command == 21) 
      {
        tft.fillCircle(CursorX, CursorY, Radius, SCHWARZ);
        if (CursorY < tft.height() - Radius) CursorY += Bewegung;
        tft.fillCircle(CursorX, CursorY, Radius, KREISFARBE);
        delay(Geschwindigkeit);
      }

      // nach links
      if (IrReceiver.decodedIRData.command == 68) 
      {
        tft.fillCircle(CursorX, CursorY, Radius, SCHWARZ);
        if (CursorX > Radius) CursorX -= Bewegung;
        tft.fillCircle(CursorX, CursorY, Radius, KREISFARBE);
        delay(Geschwindigkeit);
      }

      // nach rechts
      if (IrReceiver.decodedIRData.command == 67) 
      {
        tft.fillCircle(CursorX, CursorY, Radius, SCHWARZ);
        CursorX += Bewegung;
        tft.fillCircle(CursorX, CursorY, Radius, KREISFARBE);
        delay(Geschwindigkeit);
      }
    }

    // rechter Bildschirmrand erreicht -> Spielende
    if (CursorX > tft.height() - Radius * 2) 
    {
      ErgebnisZeigen();
    }
  }
}

void ErgebnisZeigen() {
  // Zeit berechnen
  int Sekunden;
  long VerstricheneZeit = millis() - Start;
  Sekunden = int(VerstricheneZeit / 1000);

  // Zeit anzeigen
  tft.fillScreen(SCHWARZ);
  tft.setTextSize(2);
  tft.setCursor(1, 10);
  tft.println("Zeit:");
  tft.println(String(Sekunden) + " s");

  tft.setCursor(1, 40);
  tft.setTextColor(ROT);
  tft.println();
  tft.println("Neustart:");
  tft.println("-> *");
  SpielStart = false;
}

void ParcoursBauen() 
{
  CursorX = Radius;
  CursorY = tft.height() / 2 - Abstand;
  tft.fillScreen(SCHWARZ);

  // Kreis anzeigen
  tft.fillCircle(CursorX, CursorY, Radius, KREISFARBE);

  // Parcours "bauen"
  tft.fillRect(65, 35, 5, 45, FARBE);
  tft.fillRect(1, 1, 35, 35, FARBE);
  tft.fillRect(1, 80, 70, 80, FARBE);
  tft.fillRect(110, 1, 70, 95, FARBE);
  tft.fillRect(110, 130, 140, 160, FARBE);
}

Letzte Aktualisierung:

Lot­to­zah­len mit WiFi

UNO R4 WiFi

#include "WiFiS3.h"
#include "NTP.h"

// Minimum/Maximum der Zufallszahlen
const byte Minimum = 1;
const byte Maximum = 49;

// Anzahl der zu ziehenden Zahlen
const byte Anzahl = 6;

// Array für die gezogenen Zahlen
int LottoZahl[Anzahl];

// Array für die angekreuzten Zahlen
int SpielZahl[Anzahl];

// SSID und Passwort des Routers
char Router[] = "Router_SSID";
char Passwort[] = "xxxxxxxx";

int Status = WL_IDLE_STATUS;
WiFiServer WiFiServer(80);
WiFiClient WiFiClient;

WiFiUDP wifiUdp;
NTP ntp(wifiUdp);

void setup() 
{
  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial) { ; }

  // Verbindung aufbauen
  if (WiFi.status() == WL_NO_MODULE) 
  {
    Serial.println(F("Verbindungsaufbau gescheitert!"));
  }

  while (Status != WL_CONNECTED) 
  {
    Status = WiFi.begin(Router, Passwort);

    // Zeit für den Verbindungsaufbau
    // wenn die Verbindung nicht zustandekommt -> Zeit vergrößern
    delay(500);
  }

  // Webserver starten
  WiFiServer.begin();

  /*
    Zeitzone
    CEST: Central European Summertime
    Beginn europäische Sommerzeit letzter Sonntag im März 2 Uhr GMT + 2 Stunden
  */
  ntp.ruleDST("CEST", Last, Sun, Mar, 2, 120);

  // CET: Central European Time
  // Beginn Normalzeit letzter Sonntag im Oktober 3 Uhr GMT + 1 Stunde
  ntp.ruleSTD("CET", Last, Sun, Oct, 3, 60);

  // ntp starten
  ntp.begin();

  // Zeit holen
  ntp.update();

  // Zeit mit formatedTime() anzeigen: 
  // %d = Tag, %m = Monat, %Y = Jahr, %T = Zeit in Stunden, Minuten, Sekunden
  Serial.println(ntp.formattedTime("%d.%m.%Y Uhrzeit: %T"));

  // Zufallsgenerator mit dem Signal an A0 starten
  randomSeed(analogRead(A0));
}

void loop() 
{
  // Variable "leeren"/auf 0 setzen
  String AnzahlTreffer = "";
  String GespielteZahlen = "";
  String GezogeneZahlen = "";
  byte Treffer = 0;

  // auf WiFiClienten warten ...
  WiFiClient = WiFiServer.available();
  if (WiFiClient) 
  {
    // Seite aufbauen wenn SeiteAufbauen true ist
    boolean SeiteAufbauen = true;

    // solange der WiFiClient verbunden ist ...
    while (WiFiClient.connected()) 
    {
      if (WiFiClient.available()) 
      {
        // Anforderung vom WiFiClienten lesen ...
        char Zeichen = WiFiClient.read();

        // wenn als Zeichen neue Zeile (\n) übergeben wird
        // SeiteAufbauen true ist -> Seite anzeigen
        if (Zeichen == '\n' && SeiteAufbauen) 
        {
          ntp.update();

          /*
              HTML-Seite aufbauen
              die folgenden Anweisungen müssen
              mit print oder println gesendet werden
              println "verschönert" den Quelltext
              (erzeugt einen Zeilenumbruch im Quelltext)
              " müssen mit \ maskiert werden " -> \"
          */
          WiFiClient.println("HTTP/1.1 200 OK");
          WiFiClient.println("Content-type:text/html");

          // Leerzeile zwingend erforderlich
          WiFiClient.println();
          WiFiClient.println("<!doctype html>");
          WiFiClient.println("<html>");
          WiFiClient.println("<body>");
          WiFiClient.println("<h2>Lottozahlen mit WiFi ziehen (6 aus " + String(Maximum) + ")");
          WiFiClient.print("</h2>");
          WiFiClient.println("<hr />");
          WiFiClient.println("<b>");

          // formatedTime() zeigt Wochentage in englischer Sprache
          // -> müssen einzeln abgefragt werden
          switch (ntp.weekDay()) 
          {
            case 0:
              WiFiClient.print("Sonntag");
              break;
            case 1:
              WiFiClient.print("Montag");
              break;
            case 2:
              WiFiClient.print("Dienstag");
              break;
            case 3:
              WiFiClient.print("Mittwoch");
              break;
            case 4:
              WiFiClient.print("Donnerstag");
              break;
            case 5:
              WiFiClient.print("Freitag");
              break;
            case 6:
              WiFiClient.print("Samstag");
              break;
          }
          WiFiClient.print(", ");
          WiFiClient.print(ntp.formattedTime("%d.%m.%Y Uhrzeit: %T</b>"));

          WiFiClient.println("<hr />");

          WiFiClient.println("<table><tr>");

          // Button neue Ziehung
          WiFiClient.print("<td><input style='font-size:14pt;");
          WiFiClient.print("font-weight:bold;");
          WiFiClient.print(" background-color:#7eff78;");
          WiFiClient.print(" width:200px; cursor:pointer;");
          WiFiClient.print(" border-radius:5px;border: 2px solid black;'");
          WiFiClient.print(" type='button'");
          WiFiClient.println(" onClick =\"location.href='WiFi.localIP()'\"");
          WiFiClient.println(" value='neue Ziehung'>");
          WiFiClient.println("</td></tr></table>");
          WiFiClient.println("<hr />");

          // Ziehung der "angekreuzten" Zahlen
          Ziehung();
          ZahlenSortieren(LottoZahl, 6);

          // String GespielteZahlen aus den Elementen des Arrays LottoZahl
          // zusammensetzen
          for (int i = 0; i < Anzahl; i++) 
          {
            GespielteZahlen = GespielteZahlen + LottoZahl[i] + " ";
            SpielZahl[i] = LottoZahl[i];
          }

          // Ziehung der Lottozahlen
          Ziehung();

          // Zahlen sortieren
          ZahlenSortieren(LottoZahl, 6);

          // Vergleichen der Elemente der Arrays SpielZahl und LottoZahl
          for (int i = 0; i < Anzahl; i++)
          {
            for (int ii = 0; ii < Anzahl; ii++) 
            {
              // Übereinstimmung gefunden -> Treffer um 1 erhöhen
              // AnzahlTreffer: String für übereinstimmende Zahlen erzeugen
              if (SpielZahl[i] == LottoZahl[ii]) 
              {
                AnzahlTreffer = AnzahlTreffer + SpielZahl[i] + " ";
                Treffer++;
              }
            }
          }

          // String GezogeneZahlen aus den Elementen des Arrays LottoZahl
          // zusammensetzen
          for (int i = 0; i < Anzahl; i++) 
          {
            GezogeneZahlen = GezogeneZahlen + LottoZahl[i] + " ";
          }
          WiFiClient.println("<h3 style='background-color:lightyellow'>");
          WiFiClient.println("Gespielte Zahlen: ");
          WiFiClient.println(GespielteZahlen);
          WiFiClient.println("</h3>");

          WiFiClient.println("<h3 style='background-color:lightcyan'>");

          WiFiClient.println("Gezogene Zahlen: ");
          WiFiClient.println(GezogeneZahlen);
          WiFiClient.println("</h3>");

          if (Treffer == 0) WiFiClient.println("<br><b>keine Treffer!</b>");

          // getroffene Zahlen anzeigen
          else 
          {
            WiFiClient.print("<br><b>" + String(Treffer));
            WiFiClient.print(" Treffer: </b>");
            WiFiClient.print(AnzahlTreffer);
          }

          WiFiClient.println("<hr>");

          // IPs anzeigen
          WiFiClient.print("<b>Eigene IP: ");
          WiFiClient.print(WiFiClient.remoteIP());
          WiFiClient.print("</b>");
          WiFiClient.print("<br><b>IP Adresse Arduino: ");
          WiFiClient.print(WiFi.localIP());
          WiFiClient.print("</b>");
          WiFiClient.println("</body>");
          WiFiClient.println("</html>");

          // HTTP-Antwort endet mit neuer Zeile
          WiFiClient.println();

          // Seite vollständig geladen -> loop verlassen
          break;
        }
        // neue Zeile -> SeiteAufbauen auf true setzen
        if (Zeichen == '\n') SeiteAufbauen = true;

        // die aktuelle Zeile enthält ein Zeichen
        else if (Zeichen != '\r') SeiteAufbauen = false;
      }
    }
    delay(1);

    WiFiClient.stop();
  }
}

int Ziehung() 
{
  for (int i = 0; i < Anzahl; i++) 
  {
    /*
      die Lottozahl gilt solange als bereits gezogen
      bis in der for-Schleife nachgewiesen wird, dass sie neu ist
      und BereitsGezogen den Wert false hat
    */
    bool BereitsGezogen = true;
    while (BereitsGezogen) 
    {
      // Zahl ziehen
      LottoZahl[i] = random(Minimum, Maximum);
      BereitsGezogen = false;
      /*
        Zufallszahl mit den bereits gezogenen Zahlen vergleichen
        i wird in der ersten for-Schleife hochgezählt
        alle bisherigen Zahlen (ii) werden mit den bisher gezogenen
        (außer der gerade gezogenen) verglichen (ii < i)
        ist sie identisch, erhält BereitsGezogen den Wert true
        es wird erneut eine Zufallszahl bestimmt
        wenn die Zahl neu ist, (BereitsGezogen hat noch den Wert false)
        wird die while-Schleife verlassen und die nächste Zahl gezogen
      */
      for (int ii = 0; ii < i; ii++) 
      {
        if (LottoZahl[i] == LottoZahl[ii]) BereitsGezogen = true;
      }
    }
  }
  /*
    das Array mit den Zahlen wird an das Hauptprogramm zurückgegeben
    beim ersten Aufruf sind es die gespielten Zahlen
    beim zweiten Aufruf die gezogenen Lottozahlen
  */
  return LottoZahl[Anzahl];
}

void ZahlenSortieren(int Zahlen[], int Groesse) 
{
  // unsortierten Bereich des Arrays durchlaufen
  for (int i = 0; i < (Groesse - 1); i++) 
  {
    // bei jedem Durchlauf wird das jeweils letzte Element weggelassen
    for (int ii = 0; ii < (Groesse - (i + 1)); ii++) 
    {
      /*
        wenn die aktuelle Zahl größer als die nachfolgende Zahl ist
        -> aktuelle Zahl temporär speichern
        -> Zahlen vertauschen
        -> temporäre Zahl der nachfolgenden Zahl zuweisen
      */
      if (Zahlen[ii] > Zahlen[ii + 1]) 
      {
        int zwischengespeicherteZahl = Zahlen[ii];
        Zahlen[ii] = Zahlen[ii + 1];
        Zahlen[ii + 1] = zwischengespeicherteZahl;
      }
    }
  }
}

UNO WiFi Rev2, MKR 1010, Nano 33 IoT

#include "WiFiNINA.h"
#include "NTP.h"

// Minimum/Maximum der Zufallszahlen
const byte Minimum = 1;
const byte Maximum = 49;

// Anzahl der zu ziehenden Zahlen
const byte Anzahl = 6;

// Array für die gezogenen Zahlen
int LottoZahl[Anzahl];

// Array für die angekreuzten Zahlen
int SpielZahl[Anzahl];

// SSID und Passwort des Routers
char Router[] = "Router_SSID";
char Passwort[] = "xxxxxxxx";

int Status = WL_IDLE_STATUS;
WiFiServer WiFiServer(80);
WiFiClient WiFiClient;

WiFiUDP wifiUdp;
NTP ntp(wifiUdp);

void setup() 
{
  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial) { ; }

  // Verbindung aufbauen
  if (WiFi.status() == WL_NO_MODULE) 
  {
    Serial.println(F("Verbindungsaufbau gescheitert!"));
  }

  while (Status != WL_CONNECTED) 
  {
    Status = WiFi.begin(Router, Passwort);

    // Zeit für den Verbindungsaufbau
    // wenn die Verbindung nicht zustandekommt -> Zeit vergrößern
    delay(500);
  }

  // Webserver starten
  WiFiServer.begin();

  /*
    Zeitzone
    CEST: Central European Summertime
    Beginn europäische Sommerzeit letzter Sonntag im März 2 Uhr GMT + 2 Stunden
  */
  ntp.ruleDST("CEST", Last, Sun, Mar, 2, 120);

  // CET: Central European Time
  // Beginn Normalzeit letzter Sonntag im Oktober 3 Uhr GMT + 1 Stunde
  ntp.ruleSTD("CET", Last, Sun, Oct, 3, 60);

  // ntp starten
  ntp.begin();

  // Zeit holen
  ntp.update();

  // Zeit mit formatedTime() anzeigen: 
  // %d = Tag, %m = Monat, %Y = Jahr, %T = Zeit in Stunden, Minuten, Sekunden
  Serial.println(ntp.formattedTime("%d.%m.%Y Uhrzeit: %T"));

  // Zufallsgenerator mit dem Signal an A0 starten
  randomSeed(analogRead(A0));
}

void loop() 
{
  // Variable "leeren"/auf 0 setzen
  String AnzahlTreffer = "";
  String GespielteZahlen = "";
  String GezogeneZahlen = "";
  byte Treffer = 0;

  // auf WiFiClienten warten ...
  WiFiClient = WiFiServer.available();
  if (WiFiClient) 
  {
    // Seite aufbauen wenn SeiteAufbauen true ist
    boolean SeiteAufbauen = true;

    // solange der WiFiClient verbunden ist ...
    while (WiFiClient.connected()) 
    {
      if (WiFiClient.available()) 
      {
        // Anforderung vom WiFiClienten lesen ...
        char Zeichen = WiFiClient.read();

        // wenn als Zeichen neue Zeile (\n) übergeben wird
        // SeiteAufbauen true ist -> Seite anzeigen
        if (Zeichen == '\n' && SeiteAufbauen) 
        {
          ntp.update();

          /*
              HTML-Seite aufbauen
              die folgenden Anweisungen müssen
              mit print oder println gesendet werden
              println "verschönert" den Quelltext
              (erzeugt einen Zeilenumbruch im Quelltext)
              " müssen mit \ maskiert werden " -> \"
          */
          WiFiClient.println("HTTP/1.1 200 OK");
          WiFiClient.println("Content-type:text/html");

          // Leerzeile zwingend erforderlich
          WiFiClient.println();
          WiFiClient.println("<!doctype html>");
          WiFiClient.println("<html>");
          WiFiClient.println("<body>");
          WiFiClient.println("<h2>Lottozahlen mit WiFi ziehen (6 aus " + String(Maximum) + ")");
          WiFiClient.print("</h2>");
          WiFiClient.println("<hr />");
          WiFiClient.println("<b>");

          // formatedTime() zeigt Wochentage in englischer Sprache
          // -> müssen einzeln abgefragt werden
          switch (ntp.weekDay()) 
          {
            case 0:
              WiFiClient.print("Sonntag");
              break;
            case 1:
              WiFiClient.print("Montag");
              break;
            case 2:
              WiFiClient.print("Dienstag");
              break;
            case 3:
              WiFiClient.print("Mittwoch");
              break;
            case 4:
              WiFiClient.print("Donnerstag");
              break;
            case 5:
              WiFiClient.print("Freitag");
              break;
            case 6:
              WiFiClient.print("Samstag");
              break;
          }
          WiFiClient.print(", ");
          WiFiClient.print(ntp.formattedTime("%d.%m.%Y Uhrzeit: %T</b>"));

          WiFiClient.println("<hr />");

          WiFiClient.println("<table><tr>");

          // Button neue Ziehung
          WiFiClient.print("<td><input style='font-size:14pt;");
          WiFiClient.print("font-weight:bold;");
          WiFiClient.print(" background-color:#7eff78;");
          WiFiClient.print(" width:200px; cursor:pointer;");
          WiFiClient.print(" border-radius:5px;border: 2px solid black;'");
          WiFiClient.print(" type='button'");
          WiFiClient.println(" onClick =\"location.href='WiFi.localIP()'\"");
          WiFiClient.println(" value='neue Ziehung'>");
          WiFiClient.println("</td></tr></table>");
          WiFiClient.println("<hr />");

          // Ziehung der "angekreuzten" Zahlen
          Ziehung();
          ZahlenSortieren(LottoZahl, 6);

          // String GespielteZahlen aus den Elementen des Arrays LottoZahl
          // zusammensetzen
          for (int i = 0; i < Anzahl; i++) 
          {
            GespielteZahlen = GespielteZahlen + LottoZahl[i] + " ";
            SpielZahl[i] = LottoZahl[i];
          }

          // Ziehung der Lottozahlen
          Ziehung();

          // Zahlen sortieren
          ZahlenSortieren(LottoZahl, 6);

          // Vergleichen der Elemente der Arrays SpielZahl und LottoZahl
          for (int i = 0; i < Anzahl; i++)
          {
            for (int ii = 0; ii < Anzahl; ii++) 
            {
              // Übereinstimmung gefunden -> Treffer um 1 erhöhen
              // AnzahlTreffer: String für übereinstimmende Zahlen erzeugen
              if (SpielZahl[i] == LottoZahl[ii]) 
              {
                AnzahlTreffer = AnzahlTreffer + SpielZahl[i] + " ";
                Treffer++;
              }
            }
          }

          // String GezogeneZahlen aus den Elementen des Arrays LottoZahl
          // zusammensetzen
          for (int i = 0; i < Anzahl; i++) 
          {
            GezogeneZahlen = GezogeneZahlen + LottoZahl[i] + " ";
          }
          WiFiClient.println("<h3 style='background-color:lightyellow'>");
          WiFiClient.println("Gespielte Zahlen: ");
          WiFiClient.println(GespielteZahlen);
          WiFiClient.println("</h3>");

          WiFiClient.println("<h3 style='background-color:lightcyan'>");

          WiFiClient.println("Gezogene Zahlen: ");
          WiFiClient.println(GezogeneZahlen);
          WiFiClient.println("</h3>");

          if (Treffer == 0) WiFiClient.println("<br><b>keine Treffer!</b>");

          // getroffene Zahlen anzeigen
          else 
          {
            WiFiClient.print("<br><b>" + String(Treffer));
            WiFiClient.print(" Treffer: </b>");
            WiFiClient.print(AnzahlTreffer);
          }

          WiFiClient.println("<hr>");

          // IPs anzeigen
          WiFiClient.print("<b>Eigene IP: ");
          WiFiClient.print(WiFiClient.remoteIP());
          WiFiClient.print("</b>");
          WiFiClient.print("<br><b>IP Adresse Arduino: ");
          WiFiClient.print(WiFi.localIP());
          WiFiClient.print("</b>");
          WiFiClient.println("</body>");
          WiFiClient.println("</html>");

          // HTTP-Antwort endet mit neuer Zeile
          WiFiClient.println();

          // Seite vollständig geladen -> loop verlassen
          break;
        }
        // neue Zeile -> SeiteAufbauen auf true setzen
        if (Zeichen == '\n') SeiteAufbauen = true;

        // die aktuelle Zeile enthält ein Zeichen
        else if (Zeichen != '\r') SeiteAufbauen = false;
      }
    }
    delay(1);

    WiFiClient.stop();
  }
}

int Ziehung() 
{
  for (int i = 0; i < Anzahl; i++) 
  {
    /*
      die Lottozahl gilt solange als bereits gezogen
      bis in der for-Schleife nachgewiesen wird, dass sie neu ist
      und BereitsGezogen den Wert false hat
    */
    bool BereitsGezogen = true;
    while (BereitsGezogen) 
    {
      // Zahl ziehen
      LottoZahl[i] = random(Minimum, Maximum);
      BereitsGezogen = false;
      /*
        Zufallszahl mit den bereits gezogenen Zahlen vergleichen
        i wird in der ersten for-Schleife hochgezählt
        alle bisherigen Zahlen (ii) werden mit den bisher gezogenen
        (außer der gerade gezogenen) verglichen (ii < i)
        ist sie identisch, erhält BereitsGezogen den Wert true
        es wird erneut eine Zufallszahl bestimmt
        wenn die Zahl neu ist, (BereitsGezogen hat noch den Wert false)
        wird die while-Schleife verlassen und die nächste Zahl gezogen
      */
      for (int ii = 0; ii < i; ii++) 
      {
        if (LottoZahl[i] == LottoZahl[ii]) BereitsGezogen = true;
      }
    }
  }
  /*
    das Array mit den Zahlen wird an das Hauptprogramm zurückgegeben
    beim ersten Aufruf sind es die gespielten Zahlen
    beim zweiten Aufruf die gezogenen Lottozahlen
  */
  return LottoZahl[Anzahl];
}

void ZahlenSortieren(int Zahlen[], int Groesse) 
{
  // unsortierten Bereich des Arrays durchlaufen
  for (int i = 0; i < (Groesse - 1); i++) 
  {
    // bei jedem Durchlauf wird das jeweils letzte Element weggelassen
    for (int ii = 0; ii < (Groesse - (i + 1)); ii++) 
    {
      /*
        wenn die aktuelle Zahl größer als die nachfolgende Zahl ist
        -> aktuelle Zahl temporär speichern
        -> Zahlen vertauschen
        -> temporäre Zahl der nachfolgenden Zahl zuweisen
      */
      if (Zahlen[ii] > Zahlen[ii + 1]) 
      {
        int zwischengespeicherteZahl = Zahlen[ii];
        Zahlen[ii] = Zahlen[ii + 1];
        Zahlen[ii + 1] = zwischengespeicherteZahl;
      }
    }
  }
}

ESP8266 (NodeM­CU)

#include "ESP8266WiFi.h"
#include "time.h"

// SSID und Passwort des Routers
char Router[] = "RouterSSOD";
char Passwort[] = "xxxxxxxx";

// Minimum/Maximum der Zufallszahlen
const byte Minimum = 1;
const byte Maximum = 49;

// Anzahl der zu ziehenden Zahlen
const byte Anzahl = 6;

// Array für die gezogenen Zahlen
int LottoZahl[Anzahl];

// Array für die angekreuzten Zahlen
int SpielZahl[Anzahl];

// Variablen für die Anzahl der Ziehungen
int Durchlauf = 0;

// Anzahl der Treffer
byte EinTreffer = 0;
byte ZweiTreffer = 0;
byte DreiTreffer = 0;
byte VierTreffer = 0;
byte FuenfTreffer = 0;
byte SechsTreffer = 0;

/*
  NTP-Server aus Pool 
  #define Zeitserver "de.pool.ntp.org"
  https://www.pool.ntp.org/zone/de
  oder z.B. Zeitserver der Physikalisch-technische Bundesanstalt
  #define Zeitserver "ptbtime1.ptb.de"
  wenn eine statische IP-Adresse verwendet kann der Eintrag auch direkt erfolgen
  NTP-Server als IP-Adresse angeben
  192.53.103.108 -> Physikalisch-technische Bundesanstalt
*/
#define Zeitserver "de.pool.ntp.org"

/*
  Liste der Zeitzonen
  https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
  Zeitzone CET = Central European Time -1 -> 1 Stunde zurück
  CEST = Central European Summer Time von
  M3 = März, 5.0 = Sonntag 5. Woche, 02 = 2 Uhr
  bis M10 = Oktober, 5.0 = Sonntag 5. Woche 03 = 3 Uhr
*/
#define Zeitzone "CET-1CEST,M3.5.0/02,M10.5.0/03"

// statischeIP = false -> IP-Adresse über DHCP vergeben
// statischeIP = true -> statische IP festlegen
// ip und gateway müssen an das lokale Netz angepasst werden
bool statischeIP = true;
IPAddress ip(192, 168, 1, 200);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

/*
  öffentliche DNS-Server
  -----------------------------------------------
  OpenDNS 208, 67, 222, 222 (USA)
  Google 8, 8, 8, 8 (USA)
  Cloudfare 1, 1, 1, 1 (USA)
  DNSWWatch 84, 200, 69, 80 (Deutschland)
  Quad9 9, 9, 9, 9 (Schweiz)
  Neustar UltraDNS 56, 154, 70, 3 (USA, gefiltert)
  Deutsche Telekom 217, 5,100,185
  ------------------------------------------------
  oder die im Router eingetragene IP
  im Beispiel: 192, 168, 1, 20
*/
IPAddress primaryDNS(192, 168, 1, 20);
IPAddress seconfaryDNS(9, 9, 9, 9);

// time_t enthält die Anzahl der Sekunden seit dem 1.1.1970 0 Uhr
time_t aktuelleZeit;

/* 
  Struktur tm wandelt die ermittelte Zeit in ein "lesbares" Format um:
  tm_hour -> Stunde: 0 bis 23
  tm_min -> Minuten: 0 bis 59
  tm_sec -> Sekunden 0 bis 59
  tm_mday -> Tag 1 bis 31
  tm_mon -> Monat: 0 (Januar) bis 11 (Dezember)
  tm_year -> Jahre seit 1900
  tm_yday -> vergangene Tage seit 1. Januar des Jahres
  tm_isdst -> Wert > 0 = Sommerzeit (dst = daylight saving time)
*/
tm Zeit;

WiFiServer Server(80);
WiFiClient Client;

void setup() 
{
  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial);

  // ESP8286
  configTime(Zeitzone, Zeitserver);

  // WiFi starten
  WiFi.mode(WIFI_STA);
  WiFi.begin(Router, Passwort);

  // wenn eine statische IP verwendet werden soll
  if (statischeIP) WiFi.config(ip, gateway, subnet, primaryDNS, seconfaryDNS);

  // Verbindung herstellen
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(200);
    Serial.print(".");
  }

  Server.begin();

  // SSID des Routers anzeigen
  Serial.println();
  Serial.print("Verbunden mit ");
  Serial.println(WiFi.SSID());

  // IP des D! anzeigen
  Serial.println(WiFi.localIP());

  // Zufallsgenerator mit dem Signal an A0 starten
  randomSeed(analogRead(A0));
}

void loop() 
{
  // Variable zurücksetzen
  String AnzahlTreffer = "";
  String GespielteZahlen = "";
  String GezogeneZahlen = "";
  int Treffer = 0;
  
  // aktuelle Zeit lesen
  time(&aktuelleZeit);

  // localtime_r -> ermittelte Zeit in die lokale Zeitzone setzen
  localtime_r(&aktuelleZeit, &Zeit);

  Client = Server.available();
  if (Client) 
  {
    // Seite aufbauen wenn SeiteAufbauen true ist
    boolean SeiteAufbauen = true;

    // solange der Client verbunden ist ...
    while (Client.connected()) 
    {
      if (Client.available()) 
      {
        // Anforderung vom Clienten lesen ...
        char Zeichen = Client.read();
        // return (\n) gesendet
        if (Zeichen == '\n') 
        {
          // wenn SeiteAufbauen den Wert true hat
          if (SeiteAufbauen) 
          {
            /*
              HTML-Seite aufbauen
              die folgenden Anweisungen müssen
              mit print oder println gesendet werden
              println "verschönert" den Quelltext
              (erzeugt einen Zeilenumbruch im Quelltext)
              " müssen mit \ maskiert werden " -> \"
            */

            // HTML-Seite aufbauen
            Client.println("HTTP/1.1 200 OK");
            Client.println("Content-type:text/html");

            // Leerzeile zwingend erforderlich
            Client.println();
            Client.println("<!doctype html>");
            Client.println("<html>");
            Client.println("<h2>Lottozahlen mit WiFi ziehen (6 aus " + String(Maximum) + ")</h2>");
            Client.println("<hr />");

             // tm_mday -> Wochentag anzeigen
            switch (Zeit.tm_wday) 
            {
              case 0:
                Client.print("Sonntag");
                break;
              case 1:
                Client.print("Montag");
                break;
              case 2:
                Client.print("Dienstag");
                break;
              case 3:
                Client.print("Mittwoch");
                break;
              case 4:
                Client.print("Donnerstag");
                break;
              case 5:
                Client.print("Freitag");
                break;
              case 6:
                Client.print("Samstag");
                break;
            }
            Client.print(", ");

            // Tag: führende 0 ergänzen
            if (Zeit.tm_mday < 10) Client.print("0");
            Client.print(Zeit.tm_mday);
            Client.print(".");

            // Monat: führende 0 ergänzen
            if (Zeit.tm_mon < 10) Client.print("0");
            Client.print(Zeit.tm_mon + 1);
            Client.print(".");

            // tm_year + 1900
            Client.print(Zeit.tm_year + 1900);

            // Uhrzeit
            Client.print(" Uhrzeit: ");

            // Stunden
            if (Zeit.tm_hour < 10) Client.print("0");
            Client.print(Zeit.tm_hour);
            Client.print(":");

            // Minuten
            if (Zeit.tm_min < 10) Client.print("0");
            Client.print(Zeit.tm_min);
            Client.print(":");

            // Sekunden
            if (Zeit.tm_sec < 10) Client.print("0");
            Client.print(Zeit.tm_sec);
            Client.println("<hr />");

            Client.println("<table><tr>");

            // Button neue Ziehung
            Client.print("<td><input style='font-size:14pt;");
            Client.print("font-weight:bold;");
            Client.print(" background-color:#7eff78;");
            Client.print(" width:200px; cursor:pointer;");
            Client.print(" border-radius:5px;border: 2px solid black;'");
  
            Client.print(" type='button'");
            Client.println(" onClick =\"location.href='WiFi.localIP()'\"");
            Client.println(" value='neue Ziehung'>");
            Client.println("</td></tr></table>");

            // Ziehung der "angekreuzten" Zahlen
            Ziehung();
            ZahlenSortieren(LottoZahl, 6);

            // String GespielteZahlen aus den Elementen des Arrays LottoZahl
            // zusammensetzen
            for (int i = 0; i < Anzahl; i++) 
            {
              GespielteZahlen = GespielteZahlen + LottoZahl[i] + " ";
              SpielZahl[i] = LottoZahl[i];
            }

            // Ziehung der Lottozahlen
            Ziehung();

            // Zahlen sortieren
            ZahlenSortieren(LottoZahl, 6);

            // Vergleichen der Elemente der Arrays SpielZahl und LottoZahl
            for (int i = 0; i < Anzahl; i++) 
            {
              for (int ii = 0; ii < Anzahl; ii++) 
              {
                // Übereinstimmung gefunden -> Treffer um 1 erhöhen
                // AnzahlTreffer: String für übereinstimmende Zahlen erzeugen
                if (SpielZahl[i] == LottoZahl[ii]) 
                {
                  AnzahlTreffer = AnzahlTreffer + SpielZahl[i] + " ";
                  Treffer++;
                }
              }
            }

            // String GezogeneZahlen aus den Elementen des Arrays LottoZahl
            // zusammensetzen
            for (int i = 0; i < Anzahl; i++) 
            {
              GezogeneZahlen = GezogeneZahlen + LottoZahl[i] + " ";
            }

            Client.println("<hr />");
           
            Client.println("<br>---------------------------------------------------------");
            Client.println("<br><b>Gespielte Zahlen: </b>");
            Client.println(GespielteZahlen);
            Client.println("<br>---------------------------------------------------------");
            Client.println("<br><b>Gezogene Zahlen: </b>");
            Client.println(GezogeneZahlen);
            Client.println("<br>---------------------------------------------------------");

            if (Treffer == 0) Client.println("<br><b>keine Treffer!</b>");

            // getroffene Zahlen anzeigen
            else 
            {
              Client.print("<br><b>" + String(Treffer));
              Client.print(" Treffer: </b>");
              Client.print(AnzahlTreffer);
            }
 
            Client.print("<hr>");

            // IPs anzeigen
            Client.print("<b>Eigene IP (Server): ");
            Client.print(Client.remoteIP());
            Client.print("</b>");

            if (statischeIP) Client.print("<br><b>statische IP Klient: ");
            else Client.print("<br><b>IP Adresse Klient DHCP ");
            Client.print(WiFi.localIP());
            Client.print("</b>");
            Client.println("</body>");
            Client.println("</html>");

            // HTTP-Antwort endet mit neuer Zeile
            Client.println();

            // Seite vollständig geladen -> loop verlassen
            break;
          }

          // wenn new line (\n) gesendet wurde -> Seite aufbauen
          if (Zeichen == '\n') SeiteAufbauen = true;

          else if (Zeichen != '\r') SeiteAufbauen = false;
          delay(1);
          Client.stop();
        }
      }
    }
  }
}

int Ziehung() 
{
  for (int i = 0; i < Anzahl; i++) 
  {
    /*
      die Lottozahl gilt solange als bereits gezogen
      bis in der for-Schleife nachgewiesen wird, dass sie neu ist
      und BereitsGezogen den Wert false hat
    */
    bool BereitsGezogen = true;
    while (BereitsGezogen) 
    {
      // Zahl ziehen
      LottoZahl[i] = random(Minimum, Maximum);
      BereitsGezogen = false;
      /*
        Zufallszahl mit den bereits gezogenen Zahlen vergleichen
        i wird in der ersten for-Schleife hochgezählt
        alle bisherigen Zahlen (ii) werden mit den bisher gezogenen
        (außer der gerade gezogenen) verglichen (ii < i)
        ist sie identisch, erhält BereitsGezogen den Wert true
        es wird erneut eine Zufallszahl bestimmt
        wenn die Zahl neu ist, (BereitsGezogen hat noch den Wert false)
        wird die while-Schleife verlassen und die nächste Zahl gezogen
      */
      for (int ii = 0; ii < i; ii++) 
      {
        if (LottoZahl[i] == LottoZahl[ii]) BereitsGezogen = true;
      }
    }
  }
  /*
    das Array mit den Zahlen wird an das Hauptprogramm zurückgegeben
    beim ersten Aufruf sind es die gespielten Zahlen
    beim zweiten Aufruf die gezogenen Lottozahlen
  */
  return LottoZahl[Anzahl];
}

void ZahlenSortieren(int Zahlen[], int Groesse) 
{
  // unsortierten Bereich des Arrays durchlaufen
  for (int i = 0; i < (Groesse - 1); i++) 
  {
    // bei jedem Durchlauf wird das jeweils letzte Element weggelassen
    for (int ii = 0; ii < (Groesse - (i + 1)); ii++) 
    {
      /*
        wenn die aktuelle Zahl größer als die nachfolgende Zahl ist
        -> aktuelle Zahl temporär speichern
        -> Zahlen vertauschen
        -> temporäre Zahl der nachfolgenden Zahl zuweisen
      */
      if (Zahlen[ii] > Zahlen[ii + 1]) 
      {
        int zwischengespeicherteZahl = Zahlen[ii];
        Zahlen[ii] = Zahlen[ii + 1];
        Zahlen[ii + 1] = zwischengespeicherteZahl;
      }
    }
  }
}

ESP32-WROOM, Nano ESP32

#include "WiFi.h"
#include "time.h"

// SSID und Passwort des Routers
char Router[] = "Router_SSID";
char Passwort[] = "xxxxxxxx";

// Minimum/Maximum der Zufallszahlen
const byte Minimum = 1;
const byte Maximum = 49;

// Anzahl der zu ziehenden Zahlen
const byte Anzahl = 6;

// Array für die gezogenen Zahlen
int LottoZahl[Anzahl];

// Array für die angekreuzten Zahlen
int SpielZahl[Anzahl];

// Variablen für die Anzahl der Ziehungen
int Durchlauf = 0;

// Anzahl der Treffer
byte EinTreffer = 0;
byte ZweiTreffer = 0;
byte DreiTreffer = 0;
byte VierTreffer = 0;
byte FuenfTreffer = 0;
byte SechsTreffer = 0;

/*
  NTP-Server aus Pool 
  #define Zeitserver "de.pool.ntp.org"
  https://www.pool.ntp.org/zone/de
  oder z.B. Zeitserver der Physikalisch-technische Bundesanstalt
  #define Zeitserver "ptbtime1.ptb.de"
  wenn eine statische IP-Adresse verwendet kann der Eintrag auch direkt erfolgen
  NTP-Server als IP-Adresse angeben
  192.53.103.108 -> Physikalisch-technische Bundesanstalt
*/
#define Zeitserver "de.pool.ntp.org"

/*
  Liste der Zeitzonen
  https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
  Zeitzone CET = Central European Time -1 -> 1 Stunde zurück
  CEST = Central European Summer Time von
  M3 = März, 5.0 = Sonntag 5. Woche, 02 = 2 Uhr
  bis M10 = Oktober, 5.0 = Sonntag 5. Woche 03 = 3 Uhr
*/
#define Zeitzone "CET-1CEST,M3.5.0/02,M10.5.0/03"

// statischeIP = false -> IP-Adresse über DHCP vergeben
// statischeIP = true -> statische IP festlegen
// ip und gateway müssen an das lokale Netz angepasst werden
bool statischeIP = true;
IPAddress ip(192, 168, 1, 200);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

/*
  öffentliche DNS-Server
  -----------------------------------------------
  OpenDNS 208, 67, 222, 222 (USA)
  Google 8, 8, 8, 8 (USA)
  Cloudfare 1, 1, 1, 1 (USA)
  DNSWWatch 84, 200, 69, 80 (Deutschland)
  Quad9 9, 9, 9, 9 (Schweiz)
  Neustar UltraDNS 56, 154, 70, 3 (USA, gefiltert)
  Deutsche Telekom 217, 5,100,185
  ------------------------------------------------
  oder die im Router eingetragene IP
  im Beispiel: 192, 168, 1, 20
*/
IPAddress primaryDNS(192, 168, 1, 20);
IPAddress seconfaryDNS(9, 9, 9, 9);

// time_t enthält die Anzahl der Sekunden seit dem 1.1.1970 0 Uhr
time_t aktuelleZeit;

/* 
  Struktur tm wandelt die ermittelte Zeit in ein "lesbares" Format um:
  tm_hour -> Stunde: 0 bis 23
  tm_min -> Minuten: 0 bis 59
  tm_sec -> Sekunden 0 bis 59
  tm_mday -> Tag 1 bis 31
  tm_mon -> Monat: 0 (Januar) bis 11 (Dezember)
  tm_year -> Jahre seit 1900
  tm_yday -> vergangene Tage seit 1. Januar des Jahres
  tm_isdst -> Wert > 0 = Sommerzeit (dst = daylight saving time)
*/
tm Zeit;

WiFiServer Server(80);
WiFiClient Client;

void setup() 
{
  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial);

   // Parameter für die zu ermittelnde Zeit
  // ESP32
  configTzTime(Zeitzone, Zeitserver);

  // ESP8286
  // configTime(Zeitzone, Zeitserver);

  // WiFi starten
  WiFi.mode(WIFI_STA);
  WiFi.begin(Router, Passwort);

  // wenn eine statische IP verwendet werden soll
  if (statischeIP) WiFi.config(ip, gateway, subnet, primaryDNS, seconfaryDNS);

  // Verbindung herstellen
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(200);
    Serial.print(".");
  }

  Server.begin();

  // SSID des Routers anzeigen
  Serial.println();
  Serial.print("Verbunden mit ");
  Serial.println(WiFi.SSID());

  // IP des D! anzeigen
  Serial.println(WiFi.localIP());

  // Zufallsgenerator mit dem Signal an A0 starten
  randomSeed(analogRead(A0));
}

void loop() 
{
  // Variable zurücksetzen
  String AnzahlTreffer = "";
  String GespielteZahlen = "";
  String GezogeneZahlen = "";
  int Treffer = 0;
  
  // aktuelle Zeit lesen
  time(&aktuelleZeit);

  // localtime_r -> ermittelte Zeit in die lokale Zeitzone setzen
  localtime_r(&aktuelleZeit, &Zeit);

  Client = Server.available();
  if (Client) 
  {
    // Seite aufbauen wenn SeiteAufbauen true ist
    boolean SeiteAufbauen = true;

    // solange der Client verbunden ist ...
    while (Client.connected()) 
    {
      if (Client.available()) 
      {
        // Anforderung vom Clienten lesen ...
        char Zeichen = Client.read();
        // return (\n) gesendet
        if (Zeichen == '\n') 
        {
          // wenn SeiteAufbauen den Wert true hat
          if (SeiteAufbauen) 
          {
            /*
              HTML-Seite aufbauen
              die folgenden Anweisungen müssen
              mit print oder println gesendet werden
              println "verschönert" den Quelltext
              (erzeugt einen Zeilenumbruch im Quelltext)
              " müssen mit \ maskiert werden " -> \"
            */

            // HTML-Seite aufbauen
            Client.println("HTTP/1.1 200 OK");
            Client.println("Content-type:text/html");

            // Leerzeile zwingend erforderlich
            Client.println();
            Client.println("<!doctype html>");
            Client.println("<html>");
            Client.println("<h2>Lottozahlen mit WiFi ziehen (6 aus " + String(Maximum) + ")</h2>");
            Client.println("<hr />");

             // tm_mday -> Wochentag anzeigen
            switch (Zeit.tm_wday) 
            {
              case 0:
                Client.print("Sonntag");
                break;
              case 1:
                Client.print("Montag");
                break;
              case 2:
                Client.print("Dienstag");
                break;
              case 3:
                Client.print("Mittwoch");
                break;
              case 4:
                Client.print("Donnerstag");
                break;
              case 5:
                Client.print("Freitag");
                break;
              case 6:
                Client.print("Samstag");
                break;
            }
            Client.print(", ");

            // Tag: führende 0 ergänzen
            if (Zeit.tm_mday < 10) Client.print("0");
            Client.print(Zeit.tm_mday);
            Client.print(".");

            // Monat: führende 0 ergänzen
            if (Zeit.tm_mon < 10) Client.print("0");
            Client.print(Zeit.tm_mon + 1);
            Client.print(".");

            // tm_year + 1900
            Client.print(Zeit.tm_year + 1900);

            // Uhrzeit
            Client.print(" Uhrzeit: ");

            // Stunden
            if (Zeit.tm_hour < 10) Client.print("0");
            Client.print(Zeit.tm_hour);
            Client.print(":");

            // Minuten
            if (Zeit.tm_min < 10) Client.print("0");
            Client.print(Zeit.tm_min);
            Client.print(":");

            // Sekunden
            if (Zeit.tm_sec < 10) Client.print("0");
            Client.print(Zeit.tm_sec);
            Client.println("<hr />");

            Client.println("<table><tr>");

            // Button neue Ziehung
            Client.print("<td><input style='font-size:14pt;");
            Client.print("font-weight:bold;");
            Client.print(" background-color:#7eff78;");
            Client.print(" width:200px; cursor:pointer;");
            Client.print(" border-radius:5px;border: 2px solid black;'");
  
            Client.print(" type='button'");
            Client.println(" onClick =\"location.href='WiFi.localIP()'\"");
            Client.println(" value='neue Ziehung'>");
            Client.println("</td></tr></table>");

            // Ziehung der "angekreuzten" Zahlen
            Ziehung();
            ZahlenSortieren(LottoZahl, 6);

            // String GespielteZahlen aus den Elementen des Arrays LottoZahl
            // zusammensetzen
            for (int i = 0; i < Anzahl; i++) 
            {
              GespielteZahlen = GespielteZahlen + LottoZahl[i] + " ";
              SpielZahl[i] = LottoZahl[i];
            }

            // Ziehung der Lottozahlen
            Ziehung();

            // Zahlen sortieren
            ZahlenSortieren(LottoZahl, 6);

            // Vergleichen der Elemente der Arrays SpielZahl und LottoZahl
            for (int i = 0; i < Anzahl; i++) 
            {
              for (int ii = 0; ii < Anzahl; ii++) 
              {
                // Übereinstimmung gefunden -> Treffer um 1 erhöhen
                // AnzahlTreffer: String für übereinstimmende Zahlen erzeugen
                if (SpielZahl[i] == LottoZahl[ii]) 
                {
                  AnzahlTreffer = AnzahlTreffer + SpielZahl[i] + " ";
                  Treffer++;
                }
              }
            }

            // String GezogeneZahlen aus den Elementen des Arrays LottoZahl
            // zusammensetzen
            for (int i = 0; i < Anzahl; i++) 
            {
              GezogeneZahlen = GezogeneZahlen + LottoZahl[i] + " ";
            }

            Client.println("<hr />");
           
            Client.println("<br>---------------------------------------------------------");
            Client.println("<br><b>Gespielte Zahlen: </b>");
            Client.println(GespielteZahlen);
            Client.println("<br>---------------------------------------------------------");
            Client.println("<br><b>Gezogene Zahlen: </b>");
            Client.println(GezogeneZahlen);
            Client.println("<br>---------------------------------------------------------");

            if (Treffer == 0) Client.println("<br><b>keine Treffer!</b>");

            // getroffene Zahlen anzeigen
            else 
            {
              Client.print("<br><b>" + String(Treffer));
              Client.print(" Treffer: </b>");
              Client.print(AnzahlTreffer);
            }
 
            Client.print("<hr>");

            // IPs anzeigen
            Client.print("<b>Eigene IP (Server): ");
            Client.print(Client.remoteIP());
            Client.print("</b>");

            if (statischeIP) Client.print("<br><b>statische IP Klient: ");
            else Client.print("<br><b>IP Adresse Klient DHCP ");
            Client.print(WiFi.localIP());
            Client.print("</b>");
            Client.println("</body>");
            Client.println("</html>");

            // HTTP-Antwort endet mit neuer Zeile
            Client.println();

            // Seite vollständig geladen -> loop verlassen
            break;
          }

          // wenn new line (\n) gesendet wurde -> Seite aufbauen
          if (Zeichen == '\n') SeiteAufbauen = true;

          else if (Zeichen != '\r') SeiteAufbauen = false;
          delay(1);
          Client.stop();
        }
      }
    }
  }
}

int Ziehung() 
{
  for (int i = 0; i < Anzahl; i++) 
  {
    /*
      die Lottozahl gilt solange als bereits gezogen
      bis in der for-Schleife nachgewiesen wird, dass sie neu ist
      und BereitsGezogen den Wert false hat
    */
    bool BereitsGezogen = true;
    while (BereitsGezogen) 
    {
      // Zahl ziehen
      LottoZahl[i] = random(Minimum, Maximum);
      BereitsGezogen = false;
      /*
        Zufallszahl mit den bereits gezogenen Zahlen vergleichen
        i wird in der ersten for-Schleife hochgezählt
        alle bisherigen Zahlen (ii) werden mit den bisher gezogenen
        (außer der gerade gezogenen) verglichen (ii < i)
        ist sie identisch, erhält BereitsGezogen den Wert true
        es wird erneut eine Zufallszahl bestimmt
        wenn die Zahl neu ist, (BereitsGezogen hat noch den Wert false)
        wird die while-Schleife verlassen und die nächste Zahl gezogen
      */
      for (int ii = 0; ii < i; ii++) 
      {
        if (LottoZahl[i] == LottoZahl[ii]) BereitsGezogen = true;
      }
    }
  }
  /*
    das Array mit den Zahlen wird an das Hauptprogramm zurückgegeben
    beim ersten Aufruf sind es die gespielten Zahlen
    beim zweiten Aufruf die gezogenen Lottozahlen
  */
  return LottoZahl[Anzahl];
}

void ZahlenSortieren(int Zahlen[], int Groesse) 
{
  // unsortierten Bereich des Arrays durchlaufen
  for (int i = 0; i < (Groesse - 1); i++) 
  {
    // bei jedem Durchlauf wird das jeweils letzte Element weggelassen
    for (int ii = 0; ii < (Groesse - (i + 1)); ii++) 
    {
      /*
        wenn die aktuelle Zahl größer als die nachfolgende Zahl ist
        -> aktuelle Zahl temporär speichern
        -> Zahlen vertauschen
        -> temporäre Zahl der nachfolgenden Zahl zuweisen
      */
      if (Zahlen[ii] > Zahlen[ii + 1]) 
      {
        int zwischengespeicherteZahl = Zahlen[ii];
        Zahlen[ii] = Zahlen[ii + 1];
        Zahlen[ii + 1] = zwischengespeicherteZahl;
      }
    }
  }
}

Letzte Aktualisierung:

Far­ben­spie­le RGB-Matrix

#include "Adafruit_NeoMatrix.h"

#define RGBMatrixPin 7

// Anzahl der leuchtenden LEDs
// da die Position zufällig bestimmt wird, können sie sich auch überlagern
#define AnzahlLED 64

// RGBMatrix -> Name der RGB-Matrix
/*
  die wichtigsten Parameter:
  Parameter 1 = Breite der Matrix (8)
  Parameter 2 = Höhe der Matrix (8)
  Parameter 3 = Name des Daten-Pins (RGBMatrixPin)
*/
Adafruit_NeoMatrix RGBMatrix = Adafruit_NeoMatrix(8, 8, RGBMatrixPin,
                               NEO_MATRIX_TOP + NEO_MATRIX_RIGHT +
                               NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE,
                               NEO_GRB + NEO_KHZ800);

#define Zufallsfarbe RGBMatrix.Color(random(1, 255), random(1, 255), random(1, 255))

void setup()
{
  RGBMatrix.setBrightness(10);

  // NeoPixel Bibliothek initialisieren
  RGBMatrix.begin();
  
  // Zufallsgenerator starten
  randomSeed(analogRead(A0));
}

void loop()
{
  RGBMatrix.clear();

  int Minimum = 0;
  int Maximum = 8;

  for (int i = 0; i < AnzahlLED; i++)
  {
    // Zufallsposition der Pixel
    int Spalte =  random(Minimum, Maximum);
    int Zeile =  random(Minimum, Maximum);

    RGBMatrix.drawPixel(Spalte, Zeile, Zufallsfarbe);
  }
  RGBMatrix.show();
  delay(1000);
  RGBMatrix.clear();
}

Letzte Aktualisierung:

Ampel Ardui­no WiFi mit Blue­tooth schalten

#include "ArduinoBLE.h"

/* 
  eindeutige  UUID bestimmen: 
  https://www.guidgenerator.com/online-guid-generator.aspx
  https://www.uuidgenerator.net/
  BLERead | BLEWrite | BLENotify
  -> schreiben, lesen, Info
*/
// Name BLE-Service
BLEService LEDSchalten("19b10000-e8f2-537e-4f6c-d104768a1214");

BLEUnsignedCharCharacteristic Auswahl("19b10000-e8f2-537e-4f6c-d104768a1214", BLERead | BLEWrite | BLENotify);

enum Ampel
{
  ROT = 5,
  GELB,
  GRUEN
};

void setup()
{
  Serial.begin(9600);

  // pinMode festlegen
  for (int i = ROT; i <= GRUEN; i++)
  {
    pinMode(i, OUTPUT);
  }

  // BLE starten
  if (!BLE.begin()) Serial.println("Bluetooth-Modul konnte nicht gestartet werden!");
  else Serial.println("Bluetooth-Modul erfolgreich gestartet!");

  // Name festlegen (wird in der App angezeigt) und den Service (LEDSchalten) zuweisen
  BLE.setLocalName("LEDs schalten");
  BLE.setAdvertisedService(LEDSchalten);

  // Auswahl als Platzhalter für den in der App gewählten Wert
  LEDSchalten.addCharacteristic(Auswahl);

  // Service LEDSchalten hinzufügen
  BLE.addService(LEDSchalten);

  // Startwert für die Kommunikation schreiben
  Auswahl.writeValue(0);

  // Zuweisung starten
  BLE.advertise();
}

void loop()
{
  // auf die Verbindung zu Geräten warten
  BLEDevice Verbindung = BLE.central();

  // wenn der Arduino mit einem Gerät verbunden ist ...
  if (Verbindung)
  {
    Serial.println("Verbunden ... ");

    // solange der Arduino mit einem Gerät verbunden ist ...
    while (Verbindung.connected())
    {
      /*
        Dezimal -> Hex-Umrechnung
        10 -> A
        11 -> B
        12 -> C
        20 -> 14
        21 -> 15
        22 -> 16
        30 -> 1E
      */
      if (Auswahl.written())
      {
        if (Auswahl.value() == 10)
        {
          Serial.print(Auswahl.value());
          Serial.println(" -> rot ein");
          digitalWrite(ROT, HIGH);
        }

        if (Auswahl.value() == 11)
        {
          Serial.print(Auswahl.value());
          Serial.println(F(" -> gelb ein"));
          digitalWrite(GELB, HIGH);
        }

        if (Auswahl.value() == 12)
        {
          Serial.print(Auswahl.value());
          Serial.println(F(" -> gr\u00fcn ein"));
          digitalWrite(GRUEN, HIGH);
        }

        if (Auswahl.value() == 20)
        {
          Serial.print(Auswahl.value());
          Serial.println(F(" -> rot aus"));
          digitalWrite(ROT, LOW);
        }

        if (Auswahl.value() == 21)
        {
          Serial.print(Auswahl.value());
          Serial.println(F(" -> gelb aus"));
          digitalWrite(GELB, LOW);
        }

        if (Auswahl.value() == 22)
        {
          Serial.print(Auswahl.value());
          Serial.println(F(" -> gr\u00fcn aus"));
          digitalWrite(GRUEN, LOW);
        }

        // Ampel schalten
        if (Auswahl.value() == 30)
        {
          Serial.print(Auswahl.value());
          Serial.println(F(" -> Ampel schalten"));
          digitalWrite(ROT, HIGH);
          delay(5000);
          digitalWrite(GELB, HIGH);
          delay(1000);
          digitalWrite(ROT, LOW);
          digitalWrite(GELB, LOW);
          digitalWrite(GRUEN, HIGH);
          delay(3000);
          digitalWrite(GRUEN, LOW);
          digitalWrite(GELB, HIGH);
          delay(1000);
          digitalWrite(GELB, LOW);
          digitalWrite(ROT, HIGH);
        }
      }
    }
  }
}

Letzte Aktualisierung:

LEDs UDP mit WLAN schalten

// UNO R4 WiFi
// #include "WiFiS3.h"

// MKR WiFi 1010 Nano 33 IOT
#include "WiFiNINA.h"
#include "WiFiUdp.h"

// Status bestimmt, ob die jeweilige LED an oder aus ist
// alle LEDS beim Start aus
bool Status[5] = { 0, 0, 0, 0, 0 };

// die LEDs Startwert gelbe LED an Pin 6
enum Farben 
{
  GELB = 6,
  BLAU,
  ROT,
  WEISS,
  GRUEN
};

// festeIP = false -> IP-Adresse über DHCP vergeben
// festeIP = true -> IP festlegen
bool festeIP = false;

// feste IP
IPAddress ip(192, 168, 1, 200);

// Netzwerkstatus
int status = WL_IDLE_STATUS;

// Router: Name des Routers
// Passwort: WLAN-Passwort
char Router[] = "FRITZ!Box 7590 LB";
char Passwort[] = "anea1246";

// lokaler Port
#define Port 9000

// char-Array für die empfangenen Paket
char Pakete[255];

// Variable für den Befehl des Schaltvorgangs
byte Schalten;

WiFiUDP Udp;

void setup()
{
  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial);

  if (festeIP) WiFi.config(ip);

  // Verbindung aufbauen
  if (WiFi.status() == WL_NO_MODULE) 
  {
    Serial.println(F("Verbindungsaufbau gescheitert!"));
  }

  Serial.print("Verbindung aufbauen mit ");
  Serial.println(Router);

  while (status != WL_CONNECTED) 
  {
    status = WiFi.begin(Router, Passwort);

    // Zeit für den Verbindungsaufbau
    // wenn die Verbindung nicht zustandekommt -> Zeit vergrößern
    delay(500);
  }

  // pinMode: Startwert ⇒ GELB, Endwert ⇒ GRUEN
  for (int i = GELB; i <= GRUEN; i++)
  {
    pinMode(i, OUTPUT);
  }

  // IP des Servers/des verbunden Computers anzeigen
  Serial.print("Server: ");
  Serial.println(WiFi.SSID());

  // IP des Arduinos anzeigen
  if (festeIP) Serial.print("Statische IP Adresse Arduino: ");
  else Serial.print("IP Adresse Arduino DHCP: ");
  Serial.println(WiFi.localIP());

  Udp.begin(Port);
}

void loop()
{
  // gesendete Pakete abfragen
  UDPAbfragen();

  // Schalten enthält die Anweisung welche LEDs geschaltet werden sollen
  switch (Schalten)
  {
    // Lauflicht
    case 10:
      Serial.print("gesendeter Befehl: ");
      Serial.print(Schalten);
      Serial.println(" -> Lauflicht");
      Lauflicht();
      break;

    case 11:
      // gelbe LED
      Status[0] = !Status[0];
      Serial.print("gesendeter Befehl: ");
      Serial.print(Schalten);
      if (!Status[0])
      {
        Serial.println(" -> gr\u00fcne LED ausschalten");
      }
      else Serial.println(" -> gr\u00fcne LED einschalten");
      digitalWrite(GRUEN, Status[0]);
      break;

    case 12:
      // blaue LED
      Status[1] = !Status[1];
      Serial.print("gesendeter Befehl: ");
      Serial.print(Schalten);

      if (!Status[1])
      {
        Serial.println(" -> wei\u00dfe LED ausschalten");
      }
      else Serial.println(" -> wei\u00dfe LED einschalten");
      digitalWrite(WEISS, Status[1]);
      break;

    case 13:
      // rote LED
      Status[2] = !Status[2];
      Serial.print("gesendeter Befehl: ");
      Serial.print(Schalten);
      if (!Status[2])
      {
        Serial.println(" -> rote LED ausschalten");
      }
      else Serial.println(" -> rote LED einschalten");
      digitalWrite(ROT, Status[2]);
      break;

    case 14:
      // weiße LED
      Status[3] = !Status[3];
      Serial.print("gesendeter Befehl: ");
      Serial.print(Schalten);
      if (!Status[3])
      {
        Serial.println(" -> blaue LED ausschalten");
      }
      else Serial.println(" -> blaue LED einschalten");
      digitalWrite(BLAU, Status[3]);
      break;

    case 15:
      // grüne LED
      Status[4] = !Status[4];
      Serial.print("gesendeter Befehl: ");
      Serial.print(Schalten);
      if (!Status[4])
      {
        Serial.println(" -> gelbe LED ausschalten");
      }
      else Serial.println(" -> gelbe LED einschalten");
      digitalWrite(GELB, Status[4]);
      break;

    case 16:
      // alle einschalten
      Serial.print("gesendeter Befehl: ");
      Serial.print(Schalten);
      Serial.println(" -> alle einschalten");
      AlleAn();
      break;

    // alle ausschalten
    case 17:
      Serial.print("gesendeter Befehl: ");
      Serial.print(Schalten);
      Serial.println("-> alle ausschalten");
      AlleAus();
      break;

    default:
      break;
  }

  // Schaltbefehl löschen
  Schalten = 0;
}

void UDPAbfragen()
{
  // Daten abfragen
  int PaketGroesse = Udp.parsePacket();

  // wenn Daten empfangen wurden ...
  if (PaketGroesse) {
    // Daten lesen
    Udp.read(Pakete, 255);
    Serial.println("-----------------------");

    /*
      gesendetes Paket zu int umwandeln
      char-Array in String umwandeln
      zu int umwandeln
      alternativ mit atoi:
      Schalten = atoi(Pakete);
    */
    String SchaltWert = String(Pakete);
    Schalten = SchaltWert.toInt();

    // alternativ: Schalten = atoi(Pakete);
    // IP des Senders/Port anzeigen
    Serial.print("Sender: ");
    Serial.println(Udp.remoteIP());

    // IP und Port des
    Serial.print("Adressat: ");
    Serial.print(WiFi.localIP());
    Serial.println(" Port: " + String(Port));

    // Paket senden
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write("OK");
    Udp.endPacket();
  }
  delay(10);
}
void Lauflicht()
{
  AlleAus();
  for (int i = GELB; i <= GRUEN; i++)
  {
    // aktuelle LED i einschalten
    digitalWrite(i, HIGH);
    delay(200);

    // aktuelle LED i ausschalten
    digitalWrite(i, LOW);
  }
  for (int i = GRUEN; i >= GELB; i--)
  {
    // aktuelle LED i einschalten
    digitalWrite(i, HIGH);
    delay(200);

    // aktuelle LED i ausschalten
    digitalWrite(i, LOW);
  }
}

void AlleAn()
{
  for (int i = GELB; i <= GRUEN; i++)
  {
    // aktuelle LED i ausschalten
    digitalWrite(i, HIGH);
  }

  // Status für alle LEDs auf 1 setzen
  for (int i = 0; i < sizeof(Status); i++)
  {
    Status[i] = 1;
  }
}

void AlleAus()
{
  for (int i = GRUEN; i <= GELB; i++)
  {
    // aktuelle LED i ausschalten
    digitalWrite(i, LOW);
  }

  // Status für alle LEDs auf 0 setzen
  for (int i = 0; i < sizeof(Status); i++)
  {
    Status[i] = 0;
  }
}

Letzte Aktualisierung:

Alarm­an­la­ge Hall-Sensor

int LED = 7;
int MAGNETSENSOR = 6;
int LAUTSPRECHER = 8;
 
void setup() 
{
  pinMode(LED, OUTPUT);
  pinMode(MAGNETSENSOR, INPUT);
}

void loop() 
{
  digitalWrite(LED, LOW);
  int SensorLesen = digitalRead(MAGNETSENSOR);
  if (SensorLesen == LOW) 
  {
    digitalWrite(LED, HIGH);
    tone(LAUTSPRECHER, 1000);
  }
  else 
  {
    digitalWrite(LED, LOW);
    noTone(LAUTSPRECHER);
  }
}

Letzte Aktualisierung:

Alarm­an­la­ge Lichtschranke

int LICHTSCHRANKE = 5;
int LED = 8;
int LAUTSPRECHER = 7;
int SensorWert;

void setup() 
{
  pinMode(LED, OUTPUT);
  pinMode(LAUTSPRECHER, OUTPUT);
  pinMode(LICHTSCHRANKE, INPUT);
}

void loop()
{
  SensorWert = digitalRead(LICHTSCHRANKE);
  if (SensorWert == HIGH)
  {
    // LED einschalten, Ton abspielen  
    digitalWrite(LED, HIGH);  
    tone(LAUTSPRECHER, 1000);   
  } 

  else   
  {   
    // LED und Lautsprecher ausschalten
    digitalWrite(LED, LOW);
    noTone(LAUTSPRECHER);   
  }
}

Letzte Aktualisierung:

Alarm­an­la­ge Bewegungsmelder

Ardui­no UNO

int BEWEGUNGSMELDER = 7; 
int LAUTSPRECHER = 8;  
int LED = 9; 

void setup()
{
  pinMode(BEWEGUNGSMELDER, INPUT); 
  pinMode(LED, OUTPUT );  
  pinMode(LAUTSPRECHER, OUTPUT);  
}

void loop() 
{
  int SensorWert = digitalRead(BEWEGUNGSMELDER);
  if (SensorWert == HIGH)   
  {
    // LED einschalten, Ton abspielen  
    digitalWrite(LED, HIGH);  
    tone(LAUTSPRECHER, 1000);   
  } 
  else   
  {   
    // LED und Lautsprecher ausschalten
    digitalWrite(LED, LOW);
    noTone(LAUTSPRECHER);   
  }
}

ESP32-Wroom

int BEWEGUNGSMELDER = 22; 
int LED = 23; 
int LAUTSPRECHER = 27;  

void setup()
{
  pinMode(BEWEGUNGSMELDER, INPUT_PULLDOWN); 
  pinMode(LED, OUTPUT );  
  pinMode(LAUTSPRECHER, OUTPUT);  
}

void loop() 
{
  int SensorWert = digitalRead(BEWEGUNGSMELDER);

  if (SensorWert == HIGH)   
  {
    // LED einschalten, Ton abspielen  
    digitalWrite(LED, HIGH);  
    tone(LAUTSPRECHER, 1000);   
  } 
  else   
  {   
    // LED und Lautsprecher ausschalten
    digitalWrite(LED, LOW);
    noTone(LAUTSPRECHER);   
  }
}

Wemos D1 Mini

int BEWEGUNGSMELDER = D1; 
int LED = D2; 
int LAUTSPRECHER = D3;  

void setup()
{
  pinMode(BEWEGUNGSMELDER, INPUT); 
  pinMode(LED, OUTPUT);  
  pinMode(LAUTSPRECHER, OUTPUT);  
}

void loop() 
{
  int SensorWert = digitalRead(BEWEGUNGSMELDER);

  if (SensorWert == HIGH)   
  {
    // LED einschalten, Ton abspielen  
    digitalWrite(LED, HIGH);  
    tone(LAUTSPRECHER, 1000);   
  } 
  else   
  {   
    // LED und Lautsprecher ausschalten
    digitalWrite(LED, LOW);
    noTone(LAUTSPRECHER);   
  }
}

NodeM­CU

int BEWEGUNGSMELDER = D1; 
int LED = D0; 
int LAUTSPRECHER = D2;  
int SensorWert; 

void setup()
{
  pinMode(BEWEGUNGSMELDER, INPUT); 
  pinMode(LED, OUTPUT );  
  pinMode(LAUTSPRECHER, OUTPUT);  
  Serial.begin(9600);
}

void loop() 
{
  SensorWert = digitalRead(BEWEGUNGSMELDER);

  if (SensorWert == HIGH)   
  {
    // LED einschalten, Ton abspielen  
    digitalWrite(LED, HIGH);  
    tone(LAUTSPRECHER, 1000);   
  } 
  else   
  {   
    // LED und Lautsprecher ausschalten
    digitalWrite(LED, LOW);
    noTone(LAUTSPRECHER);   
  }
}

Letzte Aktualisierung:

Alarm­an­la­ge Fotowiderstand

int Fotowiderstand = A0; 
int LED = 7; 
int Lautsprecher = 5;

// der Wert für SchwelleDunkelheit 
// kann an die gewünschte "Dunkelheit" 
// (den Zeitpunkt, an dem die LED leuchten soll)
// angepasst werden
int SchwelleDunkelheit = 400;

void setup()  
{ 
  pinMode(LED, OUTPUT); 
  Serial.begin(9600); 
}

void loop()   
{ 
  // digitaler Wert der gelesenen Spannung am Pin A0
  int SensorWert = analogRead(Fotowiderstand); 
  
  // Kommentarzeichen in den Zeilen 26 und 27 entfernen 
  // um den Wert für SchwelleDunkeheit anzuzeigen
  // und evtl. anzu passen
  // Serial.print("Ausgelesener Wert: ");       
  // Serial.println(SensorWert); 

  if (SensorWert < SchwelleDunkelheit)  
  {
    // LED einschalten, Ton abspielen  
    digitalWrite(LED, HIGH);  
    tone(Lautsprecher, 1000);   
  } 
  else   
  {   
    // LED und Lautsprecher ausschalten
    digitalWrite(LED, LOW);
    noTone(Lautsprecher);   
  }
}

Letzte Aktualisierung: