Probleme mit random() am ARDUINO

In der EDV gibt es keinen echten Zufallsgenerator, der Werte tatsächlich zufällig erzeugt, so auch beim Arduino. Das sollten Sie wissen in Projekten mit Zufallswerten.

Juli 17, 2023 - Lesezeit: 3 Minuten
  • randomSeed()
  • analogRead()
  • Arduinos Empfehlung
  • Nutzt Ihr Projekt (ARDUINO Nano) die Erzeugung zufälliger Werte, dann stoßen Sie früher oder später auf den Befehl random() in der Arduino-Bibliothek. Dieser Befehl sorgt dafür, das ein zufälliger Wert (zwischen min und max) erzeugt wird. Die folgende Codezeile erzeugt einen zufälligen Wert der zwischen 1 und 100 liegt - nehmen wir mal 77 an.

    Serial.println(random(1, 100));

    Schalten Sie den Arduino aus und erneut ein, erzeugt der Generator allerdings wiederum die zufällige 77 - Sie bemerken bereits jetzt, das mit diesem Befehl etwas nicht stimmt - es ist immer die gleiche Zufallszahl. Bedingt ist dieser Effekt durch die implementierte Hardware die keinen echten Zufallsgenerator besitzt, denn Zufallsgeneratoren werden beispielsweise im Computerbereich mit Echtzeituhren oder Umdrehungswerten des Lüfters gekoppelt, um zufällige Werte generieren zu können - all dies hat der ARDUINO Nano nicht. Die Folge, es entsteht immer der selbe Wert der zwar zufällig irgendwo zwischen 1-100 liegt aber fortan unverändert bleibt.

    randomSeed()

    Es gäbe allerdings Alternativen, zunächst den Befehl randomSeed() der in der Lage ist zufällige Werte auszugeben, jedoch sind dies keine echten Zufallswerte. Der Befehl randomSeed() bedient sich einer fertigen Liste die zufällig angeordnete feste Zahlen beinhaltet und liest diese Schritt für Schritt aus, so entsteht der Eindruck zufälliger Werte. Dieser Befehl lieftert also ebenfalls keine echten Zufallszahlen.

    analogRead()

    Eine weitere Alternative wäre analogRead() der den analogen, freien Eingang (z.B.) A0 liest und den Wert zwischen 0...1024 ausgibt. Und tatsächlich erzeugt analogRead() echte zufällige Werte anhand dieses Verfahrens, jedoch hat auch diese Methode ein Problem. Die scheinbar zufälligen Werte an einem freien Analog-Pin werden aufgrund physikalischer Bedingungen erzeugt die in der unmittelbaren Umgebung des Pins herrschen, beispielsweise haben elektomagnetische Felder die im Raum stehen großen Einflus auf den Analogpin aber auch die simple Anwesenheit des Menschen kann dazu führen elektostatische Bedingungen in der Nähe zu verändern und folglich das Ergebnis zu verfälschen.

    Wollten Sie analogRead() zur Erzeugung eines booleans ala True/False nutzen könnten Sie dies eventuell so machen:

    if (analogRead(0) > 512) {
      return true;
    } else {
      return false;
    }

    Pseudocode der zu 50% true und zu 50% false erzeugt

    Zwar ist 512 exakt die Hälfte der Auflösung des Analaogpins mit maximal 1024, jedoch pendeln die gelesenen Werte eher um einen Bereich herum, der stark von den pyhsikalischen Bedingungen der Umgebung geprägt ist. In einem eigenen Versuch habe ich herausgefunden, das der Wert stark im Bereich 200-400 pendelte aber nie 0 oder 1024 angenommen hat. Eine echte Zufallsverteilung ist dies also nicht, eine Anpassung ist also nötig.

    rnd = analogRead(0)
    if (rnd%2 == 0) {
      return true;
    } else {
      return false;
    }

    Pseudocode der der die Teilbarkeit nutzt um true oder fals zu erzeugen

    Die obige Implementierung ist besser geeignet, da es ihr vollkommen egal ist ob der Wert in einem festen Bereich pendelt oder nicht. Das Coding nutzt den Modulo2 und ergibt 0 oder 1 wenn der Wert durch 2 teilbar ist. Denn Sie können durchaus unterstellen, das der Wert zwar in einem engen Rahmen pendeln wird abber dennoch gerade oder ungerade Zahlen in einer natürlichen Verteilung aufweisen wird.

    Arduinos Empfehlung

    Das ARDUINO Projekt selbst empfiehlt allerdings auch eine eigene Lösung, die aus einer Kombination aus randomSeed() und analogRead() besteht.

    long randNumber;
    
    void setup() {
      Serial.begin(9600);
      randomSeed(analogRead(0));
    }
    
    void loop() {
      randNumber = random(300);
      Serial.println(randNumber);
      delay(50);
    }

    Zwar sind die wenigen Zeilen nicht sehr schwer zu verstehen, jedoch wird vielen Anwendern nicht klar, wie randomSeed(analogRead(0)); wohl mit randNumber = random(300); in Verbindung steht? Denn eine gemeinsame Variable nutzen sie nicht und tauschen auch keine Return-Variable aus. Der Witz liegt in der Hardwareimplementierung. in setup() wird der Zufallsgenerator mit einer Zufallsliste (Seed) initialisiert und im loop() nutzt random() eben genau diesen zuvor initialisierten Zufallsgeneraturs des Chips.

    Der Zufallsgenerator eines großen Computers ist einfach zu verwenden, demgegenüber muss man ein wenig Hardwarekenntnis beim ARDUINO mitbringen, um ihn ähnlich wie am Computer nutzen zu können.

    Schlagworte:

    Random Zufall Seed rnd

    Das passt dazu:

    Derzeit sind noch keine passenden Beiträge vorhanden.

    Beiträge in der Kategorie "Arduino":

    Atmega328p minimal Schaltung mit Quarz

    Der Chip Atmega328P, kann auch ohne Entwickler-Board einzeln betrieben werden. Die minimale Beschaltung mit externen 16MHz Oszillator.

    Atmega328p ohne Quarz

    Sie können den Atmega328p DIL Chip auch ohne den externen 16MHz Quarz benutzen, damit ist der Chip ohne externe Oszillator-Beschaltung bei 8MHz nutzbar.

    DFPlayer Mini Pinout Datasheet

    Der DFPlayer mini ist eine kleine Platine die einen SD-Kartenshacht, einen MP3-Enocder und Stiftleisten zum einlöten oder aufstecken für kleine Projekte bereit hält.

    Zeitstabiler Timer mit dem Arduino

    So programmieren Sie einen wirklich zeitstabilen Timer mit dem Arduino UNO oder MEGA

    Der ARDUINO GIGIA R1 ist da

    Der neue ARDUINO Giga kommt in wenigen Wochen auf den Markt und führt die Produktlinie des ARDUINO MEGA weiter fort und erweitert das Entwickler-Board um nützliche Kommunikationsprotokolle wie WLAN und BLE.

    Probleme mit random() am ARDUINO

    In der EDV gibt es keinen echten Zufallsgenerator, der Werte tatsächlich zufällig erzeugt, so auch beim Arduino. Das sollten Sie wissen in Projekten mit Zufallswerten.

    AVR ISP Shield mit der ARDUINO IDE

    So brennen Sie den Bootloader für den ARDUINO ATmel ATMega328P mit einem AVR ISP Shield

    Daten auf die SD Karte mit dem Arduino schreiben

    Der ATMEGA328 Nano aus dem renomierten Hause MAKERFACTORY bei mir im Test - ist er doch nur ein Clone und was taugt er?

    Atmega328p Minimalschaltung mit ISP

    Minimalschaltung des Atmega 328P mit Quarz und einem ISP-Anschluss, für die Programmierung im fest verbauten Projekt für Software-Updates und ähnliches.

    Der ARDUINO Nano Clone

    Der ATMEGA328 Nano aus dem renomierten Hause MAKERFACTORY bei mir im Test - ist er doch nur ein Clone und was taugt er?

    AT Befehle HC-05, HC-06 mit ARDUINO

    Der HC-05 ist ein preiswertes Bluetooth Modul und kann, im Gegensatz zum HC-06, sowohl als Master und auch als Slave arbeiten.