Hat jemand eine Ahnung, wie man echte Zufallszahlen erzeugen kann ? Josef
random() schon mal die Suchfunktion hier probiert ??????? http://www.mikrocontroller.net/forum/read-1-31959.html
Ist natürlich nur die halbe Miete: echte Zufallszahlen generiert man so nicht, nur pseudo-Zufall (PRNG - pseudo random number generator). Um echte Zufallszahlen haben sich vor allem die Kryptografen viele Gedanken gemacht, dort kann man nachlesen. In jedem Falle braucht man außer einem guten PRNG ein hinreichend zufälliges seeding. Die Uhrzeit ist ungeeignet, die Anzahl der bisher auf dem Ethernet transferierten Pakete, der Abstand von Tastenanschlägen des Nutzers u. ä. sind besser geeignet.
Danke für die Antworten. Random ist leider absolut unbrauchbar. Ich glaube, daß externe RC Glieder mit großen Kapazitäten an einem AD-Wandlerport funktionieren. Josef
wenn du "wirkliche" zufallszahlen willst, dann solltest du einen rauschgenerator bauen und diesen an den ADC anschließen. flo
Wenn man den ADC-Eingang offen lässt rauscht Bit 0 wahrscheinlich "zufällig genug".
Ich hab mal was über Pseudozufallsgenerator gelesen. Dort wurde ein Schieberegister mit einem externen Takt versorgt. Zwei Ausgänge wurden mit einem EXOR oder EXNOR auf den Dateneingang zurückverbunden. Ich hab das mal mit 8 Bit Schieberegister probeweise ausprobiert: Ich konnte nur sehr schwer erkennen, dass sich die Zahlen nach (ich glaub) 255 Zyklen wiederholt hat. Ein Problem hatte ich dann auch noch: Wenn das Register Komplett leer ist, so läuft das ganze erst gar nicht los. Wenns dich Interresiert hol ich mal das Buch wieder raus... Gruß, Florian
Danke für eure Hilfe ! Habe nun etwas gebaut, das gut funktioniert: Ein RC-Glied (4K7/100 UF) mit einem Portpin laden. Die Analoggspannung mit dem AD-Wandler einlesen (zwischen R und C abtasten). Sobald diese einen best. Wert überschreitet, ist die Wandlung abgeschloßen. Bis dieser Wert erreicht ist, läuft ein Ringzähler zB. (0-9) ständig "die Runde ". Das macht dieser ca. 5 tausendmal. Durch das ungenaue RC-Glied entstehen immer wieder andere Zeiten, sodaß der Ringzähler immer woanders stehenbleibt. Es entstehen Zufallszahlen zwichen 0 und 9. (beliebig einstellbar). Falls es jemanden interessiert, habe den kurzen C-Code. Schöne Grüße Josef
//************************Zufallszahl mittels RC Glied ************** char Get_Rand_P (void) { int Temp; char Rnd ; Load = 1; //RC aufladen while (1) { Rnd++; if (Rnd > 9) Rnd = 0; Temp = read_adc (3); if (Temp > 870) break; } return Rnd; } //*******************************************************************
Das dürfte aber alles andere als eine Gleichverteilung (,,weißes Rauschen'') werden. Die Zeitkonstante des RC-Gliedes bewirkt eine recht starke Wichtung des ADC-Ergebnisses. Zumindest ohne statistische Analyse würde ich das selbst nicht benutzen. Ordentliche Zufallszahlen sind in der Tat keine leichte Aufgabe. Wenn Du aber rand() verworfen hast (*), dann solltest Du Dir die Quellen für random() im BSD ansehen. Allerdings rechnet der so viel mit 32 bit Zahlen, daß ich die Portierung für die avr-libc seinerzeit verworfen habe, da sie einfach zu groß für Otto Normalverbraucher war. Die Diskussion darüber solltest Du in den Annalen der avr-libc developers Mailingliste nachlesen können. Da ein guter PRNG vor allem mit dem vernünftigen Seeding steht und fällt, waren wir seinerzeit zu dem Schluß gekommen, daß Applikationen, die an dieser Stelle wirklich erhöhten Bedarf gegenüber rand() haben, ohnehin ihre eigenen Dinge implementieren werden. Literatur dazu gibt's ja ein wenig. Ich bin kein Mathematiker, aber solange Du nicht gerade halbwegs weißes Rauschen mit dem ADC abtastest, läufst Du vermutlich große Gefahr, um einige Größenordnungen schlechter in Deiner Zufälligkeit zu sein als die bewährten PRNG-Algorithmen. Klar, Du brauchst weniger Code auf diese Weise, aber Deinen Erklärungen nach kam's Dir ja vor allem auf eine gute Zufälligkeit an. (*) Warum eigentlich, hast Du's denn wenigstens mal getestet? Ein vernünftiges Seeding mußt Du Dir natürlich selbst organisieren. Der benutzte Algorithmus ist nicht der ,,Standard''-rand() Algorithmus, der jahrelang in praktisch allen C-Implementierungen benutzt worden ist. Es ist der Basisalgorithmus des 32-bit random() aus BSD.
Sorry, ich sollte natürlich dazu schreiben, daß sich meine Ausführungen auf die avr-libc (die zum avr-gcc mitgeliefert wird) beziehen. Wenn Du eine andere Bibliothek hast, dann kann das alles ganz anders sein, aber dann kannst Du Dir ja zumindest den Sourcecode der avr-libc zu Gemüte führen.
Danke für deine Anregungen. Es handelt sich bei diesem Programm, wo Zufallszahlen benötigt werden, um ein Betriebssytem für Spielautomaten (Einarmiger Bandit mit 3 Walzen, die über ein OLED dargestellt werden) Dieser Automat verfügt noch über 120 Leds und Glühlampen. Dazu kommen SED Segmentanzeigen, 10 Taster usw. Dieses Gerät wird auf einem Messestand aufgestellt und soll das Interesse der Besucher wecken. Die Besucher können mittels SMS einen Einsatz tätigen. 3 solcher Geräte sind mittels Funk vernetzt (zwecks Jackpotsteuerung). Die Zufallszahlen werden wärend des Walzenlaufs ermittelt (4 Zahlen) Alleine hier ermittelt c-RND immer eine erkennbare Reihenfolge. Bei unsere Methode nicht. Das Ergebnis der Zufallszahlen wird statistisch ausgewertet. Erst dann werden die Walzen dementsprechend gestoppt (Abbremsphase). Sollte sich eine erkennbare Reihenfolge oder zu hohe Gewinne ergeben, müssen neue Zufallszahlen errechnet werden. Das Gerät hat eine programmierbare Gewinnausschüttung. Dementsprechen gibt es eine Einnahmen/Ausgabenrechnung. Sollte ein zu starke Gewichtung der Zahlen erfolgen, werden die AD- Schwellen Werte korrigiert. Der Code besteht aus ca. 6000 C Zeilen. Also mach ich mich wieder ans programmieren. Schöne Grüße Josef
> Die Zufallszahlen werden wärend des Walzenlaufs ermittelt (4 Zahlen) > Alleine hier ermittelt c-RND immer eine erkennbare Reihenfolge. Das von der avr-libc? Was nimmst Du als Wert für srand()? Wenn Du schon über ADC & Co. nachdenkst, würde ich Dir eher zu einem Z-Dioden-Rauschgenerator raten. Dessen Ausgang vielleicht an den Analog-Komparator legen und für den input capture interrupt benutzen. Das Ganze nimmst Du dann als seed für srand().
Keine schlechte Idee, was für ein Signal erzeugt ein Rauschgenerator ? Was meinst du mit seed (Pflänzchen)? Josef
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.