www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Random Zahl generieren


Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo liebe Community...


mitlerweile hab ich das mit dem PWM in den Griff bekommen aber habe noch 
ein anderes Problem:


Wie kann ich einen Random Wert, also eine Zufällige Zahl in einem 
Festgelegten bereich, z.B. 155 generieren?

Hab hier im Forum leider nichts brauchbares Gefunden.


Grüße
Sebastian

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achja ich programmiere in AVR-GCC

Autor: uwegw (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
<stdlib.h>
rand()

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hm

hab mal folgenden code gebastelt:
#include <avr/io.h>

int x=0;
 
unsigned short get_seed()
{
   unsigned short seed = 0;
   unsigned short *p = (unsigned short*) (RAMEND+1);
   extern unsigned short __heap_start;
    
   while (p >= &__heap_start + 1)
      seed ^= * (--p);
    
   return seed;
}

int main (void)
{
   srand(get_seed());
   x = (rand() %11); // Begrenzung von 0 - 10
}

Funktioniert das ganze?

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Probieren geht über studieren.

Autor: Vaterssohn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
google mal nach "lineare Kongruenzmethode". Nach dieser Formel arbeiten 
viele Zufallsgeneratoren.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich werd erstmal heut abend mein Programm Testen und euch dann 
berichten.


Grüße
Sebastian

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@sebastian, filtere mal alle Addressen aus die durch dein Program als 
globale Variablen schon belegt sind, also den Seed des RNGs selber auch. 
Dann wirst du feststellen das ein RESET eines schon unter Strom 
stehenden Controllers immer den gleichen Wert liefert.

Ich mache es immer so:

- ich benutze ein 32Bit LFSR als RNG
- diesem LSFR Code kann man die Polynome vorgeben
- ich benutz 2 unterschiedliche Polynome A und B
- beim Powerup der MCU lade ich aus dem EEPROM ein 32 Bit Wert als Seed
- diesen schicke ins LFSR mit Polynom A und speicher das Resultat zurück 
in den EEPROM an gleicher Stelle
- dieser Seed wird als akuelles Register des LFSR benutzt
- zur Laufzeit benutze ich das LFSR mit Polynom B

Somit laufen 2 LFSR in parallel. Das eine wird immer nur beim RESET 
aktualisert und dessen Seed steht im EEPROM. Das andere LFSR wird damit 
initialisiert. Beide LFSR benutzen andere Polynome.

Das ist zwar nicht echt zufällig, aber eben beweisbar immer 
pseudozufällig im Gegensatz zu deiner Methode.
Bei einem RESET wird nämlich der SRAM nicht ständig mit Zufallsdaten 
gefüllt, bzw. ist es garnicht gesagt das der SRAM ohne Strom nach 
Einschalten ein zufällig Inhalt aufweisen muß.
Gleiches gilte für Methoden wie mit dem ADC und Rauschen. Das Rauschen 
des ADCs muß nicht echt zufällig sein sondern systembedingt.

Gruß Hagen

PS: in der Codelib nach "Glühwürmchen" suchen, dort findest die meinen 
LFSR Source für WinAVR GCC und auch in main() oben besprochene 
Initialisierung.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
okay danke für deinen Tipp

ich werd heut abend dann mal Test und Programmierstunden einrichten ;)

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
falls du andere Polynome brauchst (müssen von spezieller Form sein damit 
die maximale Periode von 2^32-1 erreicht wird) dann sag es.

Gruß Hagen

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
okay mach ich sobald ich es testen konnte :)

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Sorry, dass ich den alten Thread hochhole, aber ich habe auch eine Frage 
bzgl. dieses Themas.
Ich habe mehrere µC, die das komplett gleiche Programm laufen haben. Nun 
muss ich eine Random-Zahl generieren, die bei allen aber unterschiedlich 
sein muss. Zur Zeit mach ich das mit der Rand()-Funktion, aber die 
Zahlen sind alle gleich!
Jemand deine Idee? Besten Dank!

mfg
Andy

Autor: Nils S. (kruemeltee) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
du brauchst nen passenden seed. Ich würde als platzsparenden 
Zufallsgenerator einen nach Park-Miller-Carta basteln, hier einige 
funktionierende Codebeispiele:
http://www.firstpr.com.au/dsp/rand31/

Als seed kannst du die Zeit nehmen. Sprich du bastelst dir entweder 
irgendwie die aktuelle Uhrzeit rein oder, was viel besser wär, eine 
"Systemuhr". Einen Timer (frequenz nahezu egal), der eine globale 
Variable hochzählt.

Das höchste der Gefühle wär natürlich wenn du dir daraus die Unix 
Systemzeit errechnen lässt und das dann als seed nimmst.

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was ist mit Hardware?

Das Rauschen einer Z-Diode, Trigger, Zähler - sollte echte Zufallszahlen 
hervorbringen und gibts bestimmt auch als fertigen Chip, oder?

Frank

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, danke erstmal für eure Hinweise.
Was ich mir gedacht habe: Wie wärs, wenn ich von Anfang an einen Timer 
laufen lasse und wenn ich die Zahl brauche, mach ich Rand()*TCNT2/255. 
Ich glaube, ein bisschen unterschiedlich werden die Timer auf 2 Atmels 
schon laufen, oder glaubt ihr, dass die immer die gleichen Werte haben 
werden??

Autor: Nils S. (kruemeltee) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die haben IMMER die gleichen Werte, allerdings nicht zur selben Zeit ;)

Autor: Barny F. (barny)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was spricht denn gegen die Methode den Ram vor dem 1. Schreibzugriff 
auszulesen und alle Werte mit XOR zu verodern?
Der Startzustand des Ram's müsste eigentlich jedes mal anders sein.

Autor: Maxxie (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist er aber nicht. Die Speicherzellen haben recht hohe Tendenzen beim 
einschalten sehr oft den gleichen Zustand einzunehmen 
(Fertigungstoleranzen die einen Zustand bevorzugen lassen) Man kann mit 
der Methode gar recht sicher feststellen, ob man der sram gewechselt 
worden ist (für systeme in denen das möglich ist)

Man kann aber recht volatile Meßwerte mit hernehmen. Ein floating ADC 
ist zwar auch nicht ganz zufällig, aber nett :-p

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Maxxie schrieb:
> Ist er aber nicht. Die Speicherzellen haben recht hohe Tendenzen beim
> einschalten sehr oft den gleichen Zustand einzunehmen

Wobei ich mir vosrtellen kann, dass ein XOR über alle nicht
benutzten RAM-Zellen (so es genügend viele sind) in der Tat
gar keinen so schlechten Zufallswert ergeben könnte.  Das müsste
man einfach mal mit hinreichend vielen Versuchen erfassen und
dann als Plot darstellen.

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Wie gesagt, ich habs nun über den TCNT2 gelöst - meint ihr, ist das ein 
zuverlässiger Zufallszahlengenerator?
Was mir noch in den Sinn gekommen ist: Gibt es eine Art Seriennummer im 
Atmel, die ich auslesen und für die Zufallszahlenberechnung heranziehen 
könnte??
THX

Andy

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Zur Zeit mach ich das mit der Rand()-Funktion ...
> Wie gesagt, ich habs nun über den TCNT2 gelöst - meint ihr, ist das ein
> zuverlässiger Zufallszahlengenerator?
Es geht doch gar nicht um den Generator, sondern nur um den Anfangswert 
(seed = die Saat). Ich glaube nicht, dass der Timer immer anders 
losläuft und du damit zuverlässig jedesmal einen anderen Startwert hast.

Sehr schön zum Erzeugen eines Saatwertes sind Benutzeraktionen oder 
extern angeschlossene Hardware (Endschalter, Taster, Zeichen über 
SIO...). Wenn ein Timer schnell hochläuft und der Zählerwert bei einem 
Pegelwechsel als Seed verwendet wird, kann ein Benutzer oder Ventil 
ziemlich sicher nicht denselben Startwert zweimal erzeugen. srand() muß 
ja nicht in der Nähe von rand() stehen, und es kann auch öfter 
aufgerufen werden.

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deshalb hab ich ja den Timer genommen. Nur ist die Frage, ob 2 µC die 
zugleich eingeschalten werden und die zugleich einen Zufallswert 
ausspucken sollen, denselben Wert ausgeben werden, oder ob die 2 Timer 
ein bisschen auseinanderlaufen werden.
Hätte ich eine Art Seriennummer, die einzigartig ist, könnte ich ja 
diese zum Seed-Wert nehmen und ich hätte 2 verschieden laufenden 
Timer...

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
BTW: Was ist srand()??

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andy schrieb:
> BTW: Was ist srand()??
Ja, wie bitte?
Du hängst dich an einen Thread und hast den nicht mal durchgelesen?
Beitrag "Re: Random Zahl generieren"
Das ist hart, meine Herren  :-/

Mit srand() wird der Startwert für den Zufallszahlengenerator 
festgelegt.
Als Stichworte für Guugel: srand() und rand(). Damit werden 
Zufallszahlen erzeugt.

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sorry, hab ich grade gelesen.... :-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.