Zufall

An einen Arduino sind 3 LEDs angeschlossen, rot an 10, gelb an 11 und grün an 12. Bei Drücken des Reset-Buttons, also jedes Mal, wenn der Arduino startet, soll eine Zufallszahl 10, 11 oder 12 generiert werden, die dann die entsprechende LED aktiviert. Die LED soll für 2 Sek. leuchten. Außerdem soll zeitgleich mit der Aktivierung der LED auf dem seriellen Monitor die entsprechende Farbe der leuchtenden LED angezeigt werden, d.h. sollte eine 11 vom Zufallsgenerator gewählt werden, muss die gelbe LED angehen und das Wort „gelb“soll auf dem seriellen Monitor erscheinen. Das Programm endet an dieser Stelle und wird, sollte der Nutzer erneut auf den Reset-Knopf drücken, von vorne abgespielt.

Ja!

@TO: Schön und warum baust Du es nicht einfach?

Gruß Tommy

Gibt es auch eine Frage zu deinem Beitrag ?
Oder ist es eine Projektvorstellung ?

Ich vermute, die Frage ist, dass wenn er einen Reset auslöst, immer sie selbe "Farbe" ausgegeben wird.

Antwort: Im Arduino befindet sich kein "echter" Zufallsgenerator. Durch den Reset werden ALLE werte wieder zurückgesetzt. Dadurch startet der Zufallsgenerator immer mit den selben Werten und gibt immer die selben Startwerte zurück.

Hier mal mein Testprogramm:

unsigned int zufall;
void setup() {
Serial.begin(9600);
randomSeed(100);
zufall=random(65535);
Serial.println(zufall);
}

void loop() {
}

Ausgabe nach jedem Reset im Serial-Monitor:
42325

Du brauchst für den Seed-Wert irgend einen zufälligen Wert um den Zufallsgenerator wirklich zufällig zu machen. :slight_smile:

Hi

Oder - statt Reset einen Taster, Der das Dauer-Warten unterbricht.
So bekommst Du 'die nächste' Zufallszahl.

Wenn Du beim 'auf den Taster warten' laufend Zufallszahlen ziehst, ist 'die Nächste' wirklich zufällig - da Du den Taster NIE identisch gedrückt bekommen wirst.

... ich sehe den sinnvollen Einsatz einer blockierenden While-Schleife ... werde wohl langsam alt :wink:

MfG

Da hier genaue Angaben für das Projekt fehlen kann man natürlich nur mutmaßen. Evtl will der TO den Arduino danach in den Schlafmodus versetzen…

unsigned int zufall;
int startzufall=0;

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

//Hier wird der Analogwert von Pin A0 10x eingelesen und addiert.
// A0 hat in diesem Fall keinerlei Außenbeschaltung

for(int i=0; i<10 ;i++){
  startzufall=startzufall+analogRead(A0);
}
randomSeed(startzufall);

zufall=random(65535);
Serial.println(zufall);
}

void loop() {

}

So hätte ich das jetzt gelöst.

Meine Wühlkiste sagt dazu:

#include <Streaming.h>

/*
 *  Das Universum als Zufallszahlengenerator
 *  
 *  Genutzt wird die Empfindlichkeit des 
 *  analogen Input.
 *  Ein paar cm Draht, als Antenne, an dem 
 *  universumPin verbessern den Zufall
 *  
 *  Ausgewertet wird nur das jeweils 
 *  niederwertigste Bit. Denn dort ist 
 *  der Einfluss des Universums am kräftigsten
 *  
 * 
 *  Einmal anfangs ausgeführt, bekommt man so einen 
 *  prächtigen Startwert für den eingebauten 
 *  Pseudozufallsgenerator
 *  https://www.arduino.cc/reference/en/language/functions/random-numbers/random/
 *  
 */

using SeedSize = unsigned long;

const byte universumPin {A0};



SeedSize meinUniversum(const byte aPin)
{
  SeedSize random = 0;
  SeedSize maske;
  for(maske=1;maske;maske<<=1)
  {
    if(1&analogRead(aPin)) random|=maske;
    delay(2); // dem Universum etwas Zeit geben, um an dem Pin zu wackeln
  }
  return random;
}

void setup() 
{
  Serial.begin(9600);
 // Serial << "Start: "<< __FILE__ << endl;
  randomSeed(meinUniversum(universumPin));
}

void loop() 
{
 //  Serial << meinUniversum(universumPin) << endl;
  Serial << random() << endl;
  delay(100);
}

combie:
Meine Wühlkiste sagt dazu:

#include <Streaming.h>

/*
*  Das Universum als Zufallszahlengenerator

*  Genutzt wird die Empfindlichkeit des
*  analogen Input.
*  Ein paar cm Draht, als Antenne, an dem
*  universumPin verbessern den Zufall

*  Ausgewertet wird nur das jeweils
*  niederwertigste Bit. Denn dort ist
*  der Einfluss des Universums am kräftigsten

*
*  Einmal anfangs ausgeführt, bekommt man so einen
*  prächtigen Startwert für den eingebauten
*  Pseudozufallsgenerator
random() - Arduino Reference

*/

using SeedSize = unsigned long;

const byte universumPin {A0};

SeedSize meinUniversum(const byte aPin)
{
  SeedSize random = 0;
  SeedSize maske;
  for(maske=1;maske;maske<<=1)
  {
    if(1&analogRead(aPin)) random|=maske;
    delay(2); // dem Universum etwas Zeit geben, um an dem Pin zu wackeln
  }
  return random;
}

void setup()
{
  Serial.begin(9600);
// Serial << "Start: "<< FILE << endl;
  randomSeed(meinUniversum(universumPin));
}

void loop()
{
//  Serial << meinUniversum(universumPin) << endl;
  Serial << random() << endl;
  delay(100);
}

Zwei dumme, ein Gedanke. :stuck_out_tongue:
Was Du nicht alles so in deiner Wühlkiste hast :smiley:

postmaster-ino:
statt Reset einen Taster, Der das Dauer-Warten unterbricht.

... ich sehe den sinnvollen Einsatz einer blockierenden While-Schleife ... werde wohl langsam alt :wink:

Macht bei der augenblicklichen Aufgabenstellung keinen Unterschied, geht aber genau so gut ohne blockierende while-Schleife

Was Du nicht alles so in deiner Wühlkiste hast :smiley:

Ja, da hat sich so einiges angesammelt…

Gefühlte 99% Schrott, fehlgeschlagene Experimente, Irrtümer, Versager.
Aber ein paar Perlen sind dabei.

liegt da in der Wühlkiste vieleicht auch ein Erklärung für den geneigten Anfänger und Erstposter, warum das “besser” ist als ein einziges
randomSeed(analogRead(0));

Deins ist ja cool, keine Frage. Aber für ein wenig “LED bling bling”? Ernsthaft?
Da muss ein 12Zeiler reichen, vieleicht sogar weniger…

/*
  In Falle einer Hausübung muss dieser copyright erhalten bleiben
  by noiasca
*/
const char *txt[] {"rot", "gelb", "grün"};
const byte pinOne = 10;
void setup() {
  Serial.begin(115200);
  randomSeed(analogRead(0));
  byte dHigvAF = random(0, 4);
  Serial.println(txt[dHigvAF]);
  pinMode(pinOne + dHigvAF, OUTPUT);
  digitalWrite(pinOne + dHigvAF, HIGH);
  delay(2000);  // dirty delay
  digitalWrite(pinOne + dHigvAF, LOW);
}

void loop() {
}

Och…
Die Entscheidung, was du als “besser” empfindest, kann ich gerne dir überlassen.

Nee, da will ich dir gar nicht rein reden.

Hi

Ich versuche mich Mal in einer Erklärung:
Der unbeschaltete Analog-Eingang stellt auch nur einen Kondensator da - Dessen Ladung bleibt auch bei mehrfachem Reset nahezu gleich - Du wirst also damit nur eine sehr kleine Anzahl an Anfangs-Werten haben und somit wird Sich Dein Zufall erkennbar voraussagbar zeigen.

Beim Einlesen des LSB des Analog-IN wird das Bit, Welches am stärksten rauscht, zum Setzen der einzelnen Bit-Positionen benutzt.
So hast Du auch in den oberen Bits einen Wechsel drin, was beim komplett auslesen des Pin nicht passieren wird.

MfG