Pages: [1] 2 3   Go Down
Author Topic: bessere Zufallszahlen erzeugen  (Read 2887 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
God Member
*****
Karma: 13
Posts: 933
ATmega 2560
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

für einen elektronischen Würfel mit Arduino, was sonst  smiley-wink, braucht man natürlich Zufallszahlen.
Nun habe ich mitbekommen das random() alleine immer wieder die gleiche Zahlenfolge erzeugt nach µC Reset.
Das kann man mit randomSeed() ändern. Ändert den Startwert für random(). Soweit ist mir das klar.

Was mir nicht klar ist, ist es sinnvoll vor jeden random() Aufruf immer ein randomSeed() zu starten oder reicht es randomSeed() einmal bei Sketchstart im setup aufzurufen und dann random() im Loop einfach machen lassen? Was bringt mehr Zufälle?

Gegenwärtige Idee wäre die Dauer des Tastendrucks zum würfeln auswerten, randomSeed() übergeben und dann mit random() eine Würfelaugenzahl erzeugen. Oder die Tastendruckdauer in [ms] noch mit irgendwas multiplizieren vor Übergabe an randomSeed()?



Logged

Tschau
Doc Arduino

Offline Offline
Jr. Member
**
Karma: 2
Posts: 77
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Es ist jetzt zwar keine direkte Antwort auf deine Frage.
Aber eine Anregung bzw eine Idee:

Benutz doch einen Analog-IN Eingang ohne Pulldown Widerstand.
Lass einfach einen Draht als Antenne fungieren. Die Störungen
sind doch ziemlich Random smiley-wink ?
Logged

Offline Offline
God Member
*****
Karma: 13
Posts: 933
ATmega 2560
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

pendelt sich der analoge Wert nicht in einem engen Bereich ein wo er dann rumzappelt, wenn er offen?


Logged

Tschau
Doc Arduino

Forum Moderator
BZ (I)
Online Online
Brattain Member
*****
Karma: 257
Posts: 21466
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ein unbeschalteter analoger Eingang ist gut für des Startwert des Zufallsgenerator.
Die Random-Funktion mußte wenn sie richtig programmiert ist zwar eine vom Anfangswert abhängige Zahlenfolge liefern. Diese sollte aber statistisch auf den ganzen Datenraum verteilt und die nächsten Zahlen nicht vom jetzigen oder zukünftigen Zahlen abhängen also nicht vorhersagbar sein.

Die Tastaturdruckdauer kann als Zufallszahl herangezogen werden wenn man zB den Modulo 10 nimmt. Die Taste muß aber über Interrupt eingelesen werden da durch Polling nur bestimmte Werte möglich sind weil die Schleife einfach eine gewisse Zeit braucht um abgearbeitet zu werden und darum nur vielfache dieses Wertes möglich sind.

Alternativ kannst Du auch eine modulo-Wert des micros() Werts bei Tastendruck verwenden, da der Tastendruck bei beliebigen Zeitpunkten erfolgt und sicher nicht auf die µS genau gemacht werden kann. Auch hier Interruptabfrage der Taste.

Grüße Uwe
Logged

Offline Offline
God Member
*****
Karma: 13
Posts: 933
ATmega 2560
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

also ist es sinnvoll vor jeden ramdom() immer wieder ein randomSeed() voranzustellen?

Dann werde ich mal die Tastendruckdauer mit Interrupt ermitteln und vielleicht einen offen Analogeingang noch dazu nehmen und miteinander multiplizieren. µs statt ms ist auch besser. Sind dann nicht wegen Interruptnutzung irgendwelche Pins nicht mehr nutzbar? Da war doch irgendwas.

Danke Euch für guten Hinweise.

Nochwas nebenbei. Warum zeigt das Forum bei nicht eingeloggt sein falsche Beitragserstellzeiten an? Fiel mir schon mehrfach auf. Uwe's Post soll zum Bsp. 14:34 Uhr erstellt wurden sein. Kann aber nicht sein. « Reply #3 on: Today at 02:34:38 PM » Logge ich mich ein, stimmt der Zeitstempel wieder. Könnte man vielleicht mal dem Forenadmin mitteilen zur Korrektur.
Logged

Tschau
Doc Arduino

Wien
Offline Offline
Edison Member
*
Karma: 28
Posts: 1879
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hi,

welche zeit ist denn die korrekte? Deine oder die von freund rufus aus kalkutta?

in Deinem profil stellst Du Deine zeitzone ein, dann wird das umgerechnet, wenn Du eingeloggt bist.

gruß stefan
Logged

Forum Moderator
BZ (I)
Online Online
Brattain Member
*****
Karma: 257
Posts: 21466
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nochwas nebenbei. Warum zeigt das Forum bei nicht eingeloggt sein falsche Beitragserstellzeiten an? Fiel mir schon mehrfach auf. Uwe's Post soll zum Bsp. 14:34 Uhr erstellt wurden sein. Kann aber nicht sein. « Reply #3 on: Today at 02:34:38 PM » Logge ich mich ein, stimmt der Zeitstempel wieder. Könnte man vielleicht mal dem Forenadmin mitteilen zur Korrektur.

Das ist die Zeit des Servers; aber frag mich nicht wo der Server sich befindet.
Ohne login weiß der Server nicht wo Du zuhause bist.
Grüße Uwe
Logged

Offline Offline
God Member
*****
Karma: 13
Posts: 933
ATmega 2560
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

wenn ich eingeloggt bin ist es die richtige Zeit. Sonst die falsche Zeit.

Edit beim tippen. Ach'so. Serverzeiten sind verschieden und werden beim Login wie Eisebaer schreibt korrigiert. Alles klar.

Ich überlege gerade wegen dem Interupt. Der Taster prellt ja. Dann würde ja der Interupt oder beide (je ein für gedrückt und nicht mehr gedrückt) während des prellens mir meine Drückzeit zu nichte machen. Kann man das entprellen mit der Bounce.h und Interrupt kombinieren oder gewinnt der Interrupt immer? Eigentlich ja, wird ja vorrangig behandelt. Ich bin da gerade in einer Endlosschleife im Kleinhirn ...  smiley-roll
Logged

Tschau
Doc Arduino

Forum Moderator
BZ (I)
Online Online
Brattain Member
*****
Karma: 257
Posts: 21466
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nein, Bounce.h und Interrupt kann man nicht kombinieren. Das Prellen und mehrfache einlesen der micro()Zeit ist in diesem Fall nicht schlimm.

In der Interruptroutine liest Du micros() in eine globale Variable und setzt ein Flag das der Taster gedrückt wurde.

Im loop() kontrollierst Du das Flag und bei gesetztem Flag (kannst Du zum Entprellen eine 5mS Pause machen) verarbeitest Du die Micros-Zeit zu einer Zufallszahl, gibst sie an das Display aus und löscht das Flag. In diesem Fall ist eine mehrmaliges Update der Zeit-Variable wegen Prellen nicht schlimm.

Grüße Uwe.
« Last Edit: March 17, 2013, 05:37:36 pm by uwefed » Logged

Offline Offline
God Member
*****
Karma: 13
Posts: 933
ATmega 2560
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

ich glaube ich hab's noch nicht verstanden, also die Methode. Laut meiner Überlegung brauche ich 2 Interrupts. Einen wenn ich auf den Taster drücke. High nach Low. Und einen 2. Interrupt wenn ich den Taster los lasse. Low nach High Pegelwechsel. Ich nutze den internen PullUp am Eingang.
Wenn der Taster aber prellt. Dann springt doch der µC mehrfach zwischen beiden Interrupts hin und her und am Ende müßte ich nur die letzte Prellzeit erhalten. ???  smiley-roll

Selbst wenn ich einmal kurz drücke und dann nochmal kurz drücken muß und dazwischen die Zeit messen möchte. Ich bekomme das prellen nicht aus dem Kopf und damit das hin und her springen.
Logged

Tschau
Doc Arduino

Forum Moderator
BZ (I)
Online Online
Brattain Member
*****
Karma: 257
Posts: 21466
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Du mußt nicht die Dauer des Tastendruck nehmen sondern die Zeit ab Einschalten des Arduino. Auch diese Zeit ist zufällig.
Grüße Uwe
Logged

Offline Offline
God Member
*****
Karma: 13
Posts: 933
ATmega 2560
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

das ist mir schon klar das ich die laufende Zeit jeweils abfragen muß und daraus die Differenz bilde.

Mir ist nur nicht klar wie das mit den entprellen funktionieren soll. Der Interrupt reagiert doch zum Bsp. auf ein LOW Signal. Der andere auf ein HIGH. Jetzt speicher ich den aktuellen µs Zähler. Jetzt lass ich den Taster los und speicher wieder den aktuellen µs Zeitzähler und bilde die Differenz. Das Problem was ich sehe ist. Wenn der Taster prellt spielen die Interrupts untereinander Ping Pong und messe nur die letzte Prellzeit. Verstehst Du mein Problem bzw. mein Denkfehler? Helf mir raus.  smiley-confuse

Das Pin angepaßte Bsp. aus meinem Buch (o'reillys Erik Bartmann) funktioniert auch nicht. LED 23 blinkt. Aber die tasterLED 8 reagiert nicht auf Tastendruck. Bleibt aus. Der Taster selbst funktioniert aber. Muß am Sketch liegen.

Code:
int ledPin = 23;                     // LED
int tasterLED =  8;                  // Taster-LED
int tasterPin = 12;                  // Taster

int interruptNumber = 0;             // Interrupt-Nummer
volatile int statusLED = LOW;        // LED-Status
 
void setup(){

  pinMode(ledPin, OUTPUT); 
  pinMode(tasterLED, OUTPUT);
  pinMode(tasterPin, INPUT);
  digitalWrite(tasterPin, HIGH);       // internen PullUp Widerstand aktiviert

  attachInterrupt(interruptNumber, interruptroutine, FALLING);
}
 
void loop(){
  for(int i = 0; i < 5; i++){
     digitalWrite(ledPin, HIGH); 
     delay(500);
     digitalWrite(ledPin, LOW);
     delay(500);
  }
}
 
void interruptroutine(){
  statusLED = statusLED^1;
  digitalWrite(tasterLED, statusLED);
}
« Last Edit: March 17, 2013, 06:57:21 pm by Doc_Arduino » Logged

Tschau
Doc Arduino

Forum Moderator
BZ (I)
Online Online
Brattain Member
*****
Karma: 257
Posts: 21466
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

das ist mir schon klar das ich die laufende Zeit jeweils abfragen muß und daraus die Differenz bilde.
Nein, keine Differenz.
Die Zeit zwischen Einschalten und Tastendruck ist gleich zufällig wie Dauer des Tastendrucks.
Grüße Uwe
Logged

Offline Offline
God Member
*****
Karma: 13
Posts: 933
ATmega 2560
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

okay, Sketch kann nicht funktionieren, ich muß natürlich den Taster auch an den Pin mit dem gewählten Interrupt anschließen und nicht woanders. Kann ich dann trotzdem den internen Pullup verwenden? An Pin2 = INT.0 Traue mich das noch nicht so zu flashen.

Wegen der Zeitmessung mach ich morgen weiter. Bin da im Moment scheinbar total neben der Spur ...  smiley-neutral

Logged

Tschau
Doc Arduino

Offline Offline
God Member
*****
Karma: 13
Posts: 933
ATmega 2560
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

so, habe mir das nochmal überlegt wie Du das meinen könntest.

Ich nehme die Zeit ab µC einschalten bis ersten Tastendruck. Die Zeit nehme ich für randomSeed().  Richtig?
Später lasse ich nur noch random() laufen solange die Taste gedrückt ist?

Meintest Du das so?
Logged

Tschau
Doc Arduino

Pages: [1] 2 3   Go Up
Jump to: