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!"));
  }

  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);
  }

  // Webserver starten
  WiFiServer.begin();

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

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

  /*
    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!"));
  }

  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);
  }

  // Webserver starten
  WiFiServer.begin();

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

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

  /*
    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 "ESP8266WebServer.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"

// festeIP = true -> IP Gateway und Subnetz und DNS-Server festlegen
bool festeIP = false;

/*
  IP, Gateway, Subnetz und DNS-Server festlegen
  Liste frei verfügbarer DNS-Server:
  https://de.wizcase.com/blog/besten-kostenlosen-und-oeffentlichen-dns-server/
  hier: OpenDNS
*/
IPAddress ip(192, 168, 1, 200);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress dns1(208, 67, 222, 222);
IPAddress dns2(208, 67, 220, 220);

// 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);
  delay(1000);
  
   // Parameter für die zu ermittelnde Zeit
  configTime(Zeitzone, Zeitserver);

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

  // wenn eine statische IP verwendet werden soll
  if (festeIP) WiFi.config(ip, gateway, subnet, dns1, dns2);

  // 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 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 (festeIP) 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"

// festeIP = true -> IP Gateway und Subnetz und DNS-Server festlegen
bool festeIP = false;

/*
  IP, Gateway, Subnetz und DNS-Server festlegen
  Liste frei verfügbarer DNS-Server:
  https://de.wizcase.com/blog/besten-kostenlosen-und-oeffentlichen-dns-server/
  hier: OpenDNS
*/
IPAddress ip(192, 168, 1, 200);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress dns1(208, 67, 222, 222);
IPAddress dns2(208, 67, 220, 220);

// 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.begin(Router, Passwort);

  // wenn eine statische IP verwendet werden soll
  if (festeIP) WiFi.config(ip, gateway, subnet, dns1, dns2);

  // 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 (festeIP) 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: 30. Aug 2023 @ 20:20